1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549 |
- /***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- *
- ***************************************************************************/
- /* OS/400 additional support. */
- #include "curlbuild.h"
- #include "config-os400.h" /* Not curl_setup.h: we only need some defines. */
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <stdlib.h>
- #include <stddef.h>
- #include <string.h>
- #include <pthread.h>
- #include <netdb.h>
- #include <qadrt.h>
- #include <errno.h>
- #ifdef HAVE_ZLIB_H
- #include <zlib.h>
- #endif
- #ifdef USE_QSOSSL
- #include <qsossl.h>
- #endif
- #ifdef USE_GSKIT
- #include <gskssl.h>
- #include <qsoasync.h>
- #endif
- #ifdef HAVE_GSSAPI
- #include <gssapi.h>
- #endif
- #ifndef CURL_DISABLE_LDAP
- #include <ldap.h>
- #endif
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include "os400sys.h"
- /**
- *** QADRT OS/400 ASCII runtime defines only the most used procedures, but
- *** but a lot of them are not supported. This module implements
- *** ASCII wrappers for those that are used by libcurl, but not
- *** defined by QADRT.
- **/
- #pragma convert(0) /* Restore EBCDIC. */
- #define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
- typedef struct {
- unsigned long size; /* Buffer size. */
- char * buf; /* Buffer address. */
- } buffer_t;
- static char * buffer_undef(localkey_t key, long size);
- static char * buffer_threaded(localkey_t key, long size);
- static char * buffer_unthreaded(localkey_t key, long size);
- static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- static pthread_key_t thdkey;
- static buffer_t * locbufs;
- char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
- static void
- thdbufdestroy(void * private)
- {
- localkey_t i;
- buffer_t * p;
- if(private) {
- p = (buffer_t *) private;
- for(i = (localkey_t) 0; i < LK_LAST; i++) {
- if(p->buf)
- free(p->buf);
- p++;
- }
- free(private);
- }
- }
- static void
- terminate(void)
- {
- if(Curl_thread_buffer == buffer_threaded) {
- locbufs = pthread_getspecific(thdkey);
- pthread_setspecific(thdkey, (void *) NULL);
- pthread_key_delete(thdkey);
- }
- if(Curl_thread_buffer != buffer_undef) {
- thdbufdestroy((void *) locbufs);
- locbufs = (buffer_t *) NULL;
- }
- Curl_thread_buffer = buffer_undef;
- }
- static char *
- get_buffer(buffer_t * buf, long size)
- {
- char * cp;
- /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
- Return the buffer address. */
- if(size < 0)
- return buf->buf;
- if(!buf->buf) {
- if((buf->buf = malloc(size)))
- buf->size = size;
- return buf->buf;
- }
- if((unsigned long) size <= buf->size) {
- /* Shorten the buffer only if it frees a significant byte count. This
- avoids some realloc() overhead. */
- if(buf->size - size < MIN_BYTE_GAIN)
- return buf->buf;
- }
- /* Resize the buffer. */
- if((cp = realloc(buf->buf, size))) {
- buf->buf = cp;
- buf->size = size;
- }
- else if(size <= buf->size)
- cp = buf->buf;
- return cp;
- }
- static char *
- buffer_unthreaded(localkey_t key, long size)
- {
- return get_buffer(locbufs + key, size);
- }
- static char *
- buffer_threaded(localkey_t key, long size)
- {
- buffer_t * bufs;
- /* Get the buffer for the given local key in the current thread, and
- make sure it is at least `size'-byte long. Set `size' to < 0 to get
- its address only. */
- bufs = (buffer_t *) pthread_getspecific(thdkey);
- if(!bufs) {
- if(size < 0)
- return (char *) NULL; /* No buffer yet. */
- /* Allocate buffer descriptors for the current thread. */
- if(!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
- return (char *) NULL;
- if(pthread_setspecific(thdkey, (void *) bufs)) {
- free(bufs);
- return (char *) NULL;
- }
- }
- return get_buffer(bufs + key, size);
- }
- static char *
- buffer_undef(localkey_t key, long size)
- {
- /* Define the buffer system, get the buffer for the given local key in
- the current thread, and make sure it is at least `size'-byte long.
- Set `size' to < 0 to get its address only. */
- pthread_mutex_lock(&mutex);
- /* Determine if we can use pthread-specific data. */
- if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
- if(!pthread_key_create(&thdkey, thdbufdestroy))
- Curl_thread_buffer = buffer_threaded;
- else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
- pthread_mutex_unlock(&mutex);
- return (char *) NULL;
- }
- else
- Curl_thread_buffer = buffer_unthreaded;
- atexit(terminate);
- }
- pthread_mutex_unlock(&mutex);
- return Curl_thread_buffer(key, size);
- }
- static char *
- set_thread_string(localkey_t key, const char * s)
- {
- int i;
- char * cp;
- if(!s)
- return (char *) NULL;
- i = strlen(s) + 1;
- cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
- if(cp) {
- i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
- cp[i] = '\0';
- }
- return cp;
- }
- int
- Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
- char * nodename, curl_socklen_t nodenamelen,
- char * servname, curl_socklen_t servnamelen,
- int flags)
- {
- char * enodename;
- char * eservname;
- int status;
- int i;
- enodename = (char *) NULL;
- eservname = (char *) NULL;
- if(nodename && nodenamelen)
- if(!(enodename = malloc(nodenamelen)))
- return EAI_MEMORY;
- if(servname && servnamelen)
- if(!(eservname = malloc(servnamelen))) {
- if(enodename)
- free(enodename);
- return EAI_MEMORY;
- }
- status = getnameinfo(sa, salen, enodename, nodenamelen,
- eservname, servnamelen, flags);
- if(!status) {
- if(enodename) {
- i = QadrtConvertE2A(nodename, enodename,
- nodenamelen - 1, strlen(enodename));
- nodename[i] = '\0';
- }
- if(eservname) {
- i = QadrtConvertE2A(servname, eservname,
- servnamelen - 1, strlen(eservname));
- servname[i] = '\0';
- }
- }
- if(enodename)
- free(enodename);
- if(eservname)
- free(eservname);
- return status;
- }
- int
- Curl_getaddrinfo_a(const char * nodename, const char * servname,
- const struct addrinfo * hints,
- struct addrinfo * * res)
- {
- char * enodename;
- char * eservname;
- int status;
- int i;
- enodename = (char *) NULL;
- eservname = (char *) NULL;
- if(nodename) {
- i = strlen(nodename);
- if(!(enodename = malloc(i + 1)))
- return EAI_MEMORY;
- i = QadrtConvertA2E(enodename, nodename, i, i);
- enodename[i] = '\0';
- }
- if(servname) {
- i = strlen(servname);
- if(!(eservname = malloc(i + 1))) {
- if(enodename)
- free(enodename);
- return EAI_MEMORY;
- }
- QadrtConvertA2E(eservname, servname, i, i);
- eservname[i] = '\0';
- }
- status = getaddrinfo(enodename, eservname, hints, res);
- if(enodename)
- free(enodename);
- if(eservname)
- free(eservname);
- return status;
- }
- #ifdef USE_QSOSSL
- /* ASCII wrappers for the SSL procedures. */
- int
- Curl_SSL_Init_Application_a(SSLInitApp * init_app)
- {
- int rc;
- unsigned int i;
- SSLInitApp ia;
- if(!init_app || !init_app->applicationID || !init_app->applicationIDLen)
- return SSL_Init_Application(init_app);
- memcpy((char *) &ia, (char *) init_app, sizeof ia);
- i = ia.applicationIDLen;
- if(!(ia.applicationID = malloc(i + 1))) {
- errno = ENOMEM;
- return SSL_ERROR_IO;
- }
- QadrtConvertA2E(ia.applicationID, init_app->applicationID, i, i);
- ia.applicationID[i] = '\0';
- rc = SSL_Init_Application(&ia);
- free(ia.applicationID);
- init_app->localCertificateLen = ia.localCertificateLen;
- init_app->sessionType = ia.sessionType;
- return rc;
- }
- int
- Curl_SSL_Init_a(SSLInit * init)
- {
- int rc;
- unsigned int i;
- SSLInit ia;
- if(!init || (!init->keyringFileName && !init->keyringPassword))
- return SSL_Init(init);
- memcpy((char *) &ia, (char *) init, sizeof ia);
- if(ia.keyringFileName) {
- i = strlen(ia.keyringFileName);
- if(!(ia.keyringFileName = malloc(i + 1))) {
- errno = ENOMEM;
- return SSL_ERROR_IO;
- }
- QadrtConvertA2E(ia.keyringFileName, init->keyringFileName, i, i);
- ia.keyringFileName[i] = '\0';
- }
- if(ia.keyringPassword) {
- i = strlen(ia.keyringPassword);
- if(!(ia.keyringPassword = malloc(i + 1))) {
- if(ia.keyringFileName)
- free(ia.keyringFileName);
- errno = ENOMEM;
- return SSL_ERROR_IO;
- }
- QadrtConvertA2E(ia.keyringPassword, init->keyringPassword, i, i);
- ia.keyringPassword[i] = '\0';
- }
- rc = SSL_Init(&ia);
- if(ia.keyringFileName)
- free(ia.keyringFileName);
- if(ia.keyringPassword)
- free(ia.keyringPassword);
- return rc;
- }
- char *
- Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
- {
- return set_thread_string(LK_SSL_ERROR,
- SSL_Strerror(sslreturnvalue, serrmsgp));
- }
- #endif /* USE_QSOSSL */
- #ifdef USE_GSKIT
- /* ASCII wrappers for the GSKit procedures. */
- /*
- * EBCDIC --> ASCII string mapping table.
- * Some strings returned by GSKit are dynamically allocated and automatically
- * released when closing the handle.
- * To provide the same functionality, we use a "private" handle that
- * holds the GSKit handle and a list of string mappings. This will allow
- * avoid conversion of already converted strings and releasing them upon
- * close time.
- */
- struct gskstrlist {
- struct gskstrlist * next;
- const char * ebcdicstr;
- const char * asciistr;
- };
- struct Curl_gsk_descriptor {
- gsk_handle h;
- struct gskstrlist * strlist;
- };
- int
- Curl_gsk_environment_open(gsk_handle * my_env_handle)
- {
- struct Curl_gsk_descriptor * p;
- gsk_handle h;
- int rc;
- if(!my_env_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
- return GSK_INSUFFICIENT_STORAGE;
- p->strlist = (struct gskstrlist *) NULL;
- if((rc = gsk_environment_open(&p->h)) != GSK_OK)
- free(p);
- else
- *my_env_handle = (gsk_handle) p;
- return rc;
- }
- int
- Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
- gsk_handle * my_session_handle)
- {
- struct Curl_gsk_descriptor * p;
- gsk_handle h;
- int rc;
- if(!my_env_handle)
- return GSK_INVALID_HANDLE;
- if(!my_session_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
- if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
- return GSK_INSUFFICIENT_STORAGE;
- p->strlist = (struct gskstrlist *) NULL;
- if((rc = gsk_secure_soc_open(h, &p->h)) != GSK_OK)
- free(p);
- else
- *my_session_handle = (gsk_handle) p;
- return rc;
- }
- static void
- gsk_free_handle(struct Curl_gsk_descriptor * p)
- {
- struct gskstrlist * q;
- while((q = p->strlist)) {
- p->strlist = q;
- free((void *) q->asciistr);
- free(q);
- }
- free(p);
- }
- int
- Curl_gsk_environment_close(gsk_handle * my_env_handle)
- {
- struct Curl_gsk_descriptor * p;
- int rc;
- if(!my_env_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- if(!*my_env_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) *my_env_handle;
- if((rc = gsk_environment_close(&p->h)) == GSK_OK) {
- gsk_free_handle(p);
- *my_env_handle = (gsk_handle) NULL;
- }
- return rc;
- }
- int
- Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
- {
- struct Curl_gsk_descriptor * p;
- int rc;
- if(!my_session_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- if(!*my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) *my_session_handle;
- if((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
- gsk_free_handle(p);
- *my_session_handle = (gsk_handle) NULL;
- }
- return rc;
- }
- int
- Curl_gsk_environment_init(gsk_handle my_env_handle)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_env_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_env_handle;
- return gsk_environment_init(p->h);
- }
- int
- Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_init(p->h);
- }
- int
- Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
- const char * buffer, int bufSize)
- {
- struct Curl_gsk_descriptor * p;
- char * ebcdicbuf;
- int rc;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- if(!buffer)
- return GSK_OS400_ERROR_INVALID_POINTER;
- if(bufSize < 0)
- return GSK_ATTRIBUTE_INVALID_LENGTH;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- if(!bufSize)
- bufSize = strlen(buffer);
- if(!(ebcdicbuf = malloc(bufSize + 1)))
- return GSK_INSUFFICIENT_STORAGE;
- QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
- ebcdicbuf[bufSize] = '\0';
- rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
- free(ebcdicbuf);
- return rc;
- }
- int
- Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
- GSK_ENUM_VALUE enumValue)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_set_enum(p->h, enumID, enumValue);
- }
- int
- Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
- GSK_NUM_ID numID, int numValue)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_set_numeric_value(p->h, numID, numValue);
- }
- int
- Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
- GSK_CALLBACK_ID callBackID,
- void * callBackAreaPtr)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
- }
- static int
- cachestring(struct Curl_gsk_descriptor * p,
- const char * ebcdicbuf, int bufsize, const char * * buffer)
- {
- int rc;
- char * asciibuf;
- struct gskstrlist * sp;
- for(sp = p->strlist; sp; sp = sp->next)
- if(sp->ebcdicstr == ebcdicbuf)
- break;
- if(!sp) {
- if(!(sp = (struct gskstrlist *) malloc(sizeof *sp)))
- return GSK_INSUFFICIENT_STORAGE;
- if(!(asciibuf = malloc(bufsize + 1))) {
- free(sp);
- return GSK_INSUFFICIENT_STORAGE;
- }
- QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
- asciibuf[bufsize] = '\0';
- sp->ebcdicstr = ebcdicbuf;
- sp->asciistr = asciibuf;
- sp->next = p->strlist;
- p->strlist = sp;
- }
- *buffer = sp->asciistr;
- return GSK_OK;
- }
- int
- Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
- const char * * buffer, int * bufSize)
- {
- struct Curl_gsk_descriptor * p;
- int rc;
- const char * mybuf;
- int mylen;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- if(!buffer || !bufSize)
- return GSK_OS400_ERROR_INVALID_POINTER;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- if((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
- return rc;
- if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
- *bufSize = mylen;
- return rc;
- }
- int
- Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
- GSK_ENUM_VALUE * enumValue)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_get_enum(p->h, enumID, enumValue);
- }
- int
- Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
- GSK_NUM_ID numID, int * numValue)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_get_numeric_value(p->h, numID, numValue);
- }
- int
- Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
- GSK_CERT_ID certID,
- const gsk_cert_data_elem * * certDataElem,
- int * certDataElementCount)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- /* No need to convert code: text results are already in ASCII. */
- return gsk_attribute_get_cert_info(p->h, certID,
- certDataElem, certDataElementCount);
- }
- int
- Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_misc(p->h, miscID);
- }
- int
- Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
- int readBufSize, int * amtRead)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
- }
- int
- Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
- int writeBufSize, int * amtWritten)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
- }
- const char *
- Curl_gsk_strerror_a(int gsk_return_value)
- {
- return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
- }
- int
- Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
- int IOCompletionPort,
- Qso_OverlappedIO_t * communicationsArea)
- {
- struct Curl_gsk_descriptor * p;
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
- }
- #endif /* USE_GSKIT */
- #ifdef HAVE_GSSAPI
- /* ASCII wrappers for the GSSAPI procedures. */
- static int
- Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
- {
- unsigned int i;
- char * t;
- /* Convert `buf' in place, from EBCDIC to ASCII.
- If error, release the buffer and return -1. Else return 0. */
- i = buf->length;
- if(i) {
- if(!(t = malloc(i))) {
- gss_release_buffer(minor_status, buf);
- if(minor_status)
- *minor_status = ENOMEM;
- return -1;
- }
- QadrtConvertE2A(t, buf->value, i, i);
- memcpy(buf->value, t, i);
- free(t);
- }
- return 0;
- }
- OM_uint32
- Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
- gss_OID in_name_type, gss_name_t * out_name)
- {
- int rc;
- unsigned int i;
- gss_buffer_desc in;
- if(!in_name || !in_name->value || !in_name->length)
- return gss_import_name(minor_status, in_name, in_name_type, out_name);
- memcpy((char *) &in, (char *) in_name, sizeof in);
- i = in.length;
- if(!(in.value = malloc(i + 1))) {
- if(minor_status)
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- QadrtConvertA2E(in.value, in_name->value, i, i);
- ((char *) in.value)[i] = '\0';
- rc = gss_import_name(minor_status, &in, in_name_type, out_name);
- free(in.value);
- return rc;
- }
- OM_uint32
- Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
- int status_type, gss_OID mech_type,
- gss_msg_ctx_t * message_context, gss_buffer_t status_string)
- {
- int rc;
- rc = gss_display_status(minor_status, status_value, status_type,
- mech_type, message_context, status_string);
- if(rc != GSS_S_COMPLETE || !status_string ||
- !status_string->length || !status_string->value)
- return rc;
- /* No way to allocate a buffer here, because it will be released by
- gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
- with ASCII to return it. */
- if(Curl_gss_convert_in_place(minor_status, status_string))
- return GSS_S_FAILURE;
- return rc;
- }
- OM_uint32
- Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
- gss_cred_id_t cred_handle,
- gss_ctx_id_t * context_handle,
- gss_name_t target_name, gss_OID mech_type,
- gss_flags_t req_flags, OM_uint32 time_req,
- gss_channel_bindings_t input_chan_bindings,
- gss_buffer_t input_token,
- gss_OID * actual_mech_type,
- gss_buffer_t output_token, gss_flags_t * ret_flags,
- OM_uint32 * time_rec)
- {
- int rc;
- unsigned int i;
- gss_buffer_desc in;
- gss_buffer_t inp;
- in.value = NULL;
- if((inp = input_token))
- if(inp->length && inp->value) {
- i = inp->length;
- if(!(in.value = malloc(i + 1))) {
- if(minor_status)
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
- QadrtConvertA2E(in.value, input_token->value, i, i);
- ((char *) in.value)[i] = '\0';
- in.length = i;
- inp = ∈
- }
- rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
- target_name, mech_type, req_flags, time_req,
- input_chan_bindings, inp, actual_mech_type,
- output_token, ret_flags, time_rec);
- if(in.value)
- free(in.value);
- if(rc != GSS_S_COMPLETE || !output_token ||
- !output_token->length || !output_token->value)
- return rc;
- /* No way to allocate a buffer here, because it will be released by
- gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
- with ASCII to return it. */
- if(Curl_gss_convert_in_place(minor_status, output_token))
- return GSS_S_FAILURE;
- return rc;
- }
- OM_uint32
- Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
- gss_ctx_id_t * context_handle,
- gss_buffer_t output_token)
- {
- int rc;
- rc = gss_delete_sec_context(minor_status, context_handle, output_token);
- if(rc != GSS_S_COMPLETE || !output_token ||
- !output_token->length || !output_token->value)
- return rc;
- /* No way to allocate a buffer here, because it will be released by
- gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
- with ASCII to return it. */
- if(Curl_gss_convert_in_place(minor_status, output_token))
- return GSS_S_FAILURE;
- return rc;
- }
- #endif /* HAVE_GSSAPI */
- #ifndef CURL_DISABLE_LDAP
- /* ASCII wrappers for the LDAP procedures. */
- void *
- Curl_ldap_init_a(char * host, int port)
- {
- unsigned int i;
- char * ehost;
- void * result;
- if(!host)
- return (void *) ldap_init(host, port);
- i = strlen(host);
- if(!(ehost = malloc(i + 1)))
- return (void *) NULL;
- QadrtConvertA2E(ehost, host, i, i);
- ehost[i] = '\0';
- result = (void *) ldap_init(ehost, port);
- free(ehost);
- return result;
- }
- int
- Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
- {
- int i;
- char * edn;
- char * epasswd;
- edn = (char *) NULL;
- epasswd = (char *) NULL;
- if(dn) {
- i = strlen(dn);
- if(!(edn = malloc(i + 1)))
- return LDAP_NO_MEMORY;
- QadrtConvertA2E(edn, dn, i, i);
- edn[i] = '\0';
- }
- if(passwd) {
- i = strlen(passwd);
- if(!(epasswd = malloc(i + 1))) {
- if(edn)
- free(edn);
- return LDAP_NO_MEMORY;
- }
- QadrtConvertA2E(epasswd, passwd, i, i);
- epasswd[i] = '\0';
- }
- i = ldap_simple_bind_s(ld, edn, epasswd);
- if(epasswd)
- free(epasswd);
- if(edn)
- free(edn);
- return i;
- }
- int
- Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
- char * * attrs, int attrsonly, LDAPMessage * * res)
- {
- int i;
- int j;
- char * ebase;
- char * efilter;
- char * * eattrs;
- int status;
- ebase = (char *) NULL;
- efilter = (char *) NULL;
- eattrs = (char * *) NULL;
- status = LDAP_SUCCESS;
- if(base) {
- i = strlen(base);
- if(!(ebase = malloc(i + 1)))
- status = LDAP_NO_MEMORY;
- else {
- QadrtConvertA2E(ebase, base, i, i);
- ebase[i] = '\0';
- }
- }
- if(filter && status == LDAP_SUCCESS) {
- i = strlen(filter);
- if(!(efilter = malloc(i + 1)))
- status = LDAP_NO_MEMORY;
- else {
- QadrtConvertA2E(efilter, filter, i, i);
- efilter[i] = '\0';
- }
- }
- if(attrs && status == LDAP_SUCCESS) {
- for(i = 0; attrs[i++];)
- ;
- if(!(eattrs = calloc(i, sizeof *eattrs)))
- status = LDAP_NO_MEMORY;
- else {
- for(j = 0; attrs[j]; j++) {
- i = strlen(attrs[j]);
- if(!(eattrs[j] = malloc(i + 1))) {
- status = LDAP_NO_MEMORY;
- break;
- }
- QadrtConvertA2E(eattrs[j], attrs[j], i, i);
- eattrs[j][i] = '\0';
- }
- }
- }
- if(status == LDAP_SUCCESS)
- status = ldap_search_s(ld, ebase? ebase: "", scope,
- efilter? efilter: "(objectclass=*)",
- eattrs, attrsonly, res);
- if(eattrs) {
- for(j = 0; eattrs[j]; j++)
- free(eattrs[j]);
- free(eattrs);
- }
- if(efilter)
- free(efilter);
- if(ebase)
- free(ebase);
- return status;
- }
- struct berval * *
- Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
- {
- int i;
- char * cp;
- struct berval * * result;
- cp = (char *) NULL;
- if(attr) {
- i = strlen(attr);
- if(!(cp = malloc(i + 1))) {
- ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
- ldap_err2string(LDAP_NO_MEMORY));
- return (struct berval * *) NULL;
- }
- QadrtConvertA2E(cp, attr, i, i);
- cp[i] = '\0';
- }
- result = ldap_get_values_len(ld, entry, cp);
- if(cp)
- free(cp);
- /* Result data are binary in nature, so they haven't been
- converted to EBCDIC. Therefore do not convert. */
- return result;
- }
- char *
- Curl_ldap_err2string_a(int error)
- {
- return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
- }
- char *
- Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
- {
- int i;
- char * cp;
- char * cp2;
- cp = ldap_get_dn(ld, entry);
- if(!cp)
- return cp;
- i = strlen(cp);
- if(!(cp2 = malloc(i + 1)))
- return cp2;
- QadrtConvertE2A(cp2, cp, i, i);
- cp2[i] = '\0';
- /* No way to allocate a buffer here, because it will be released by
- ldap_memfree() and ldap_memalloc() does not exist. The solution is to
- overwrite the EBCDIC buffer with ASCII to return it. */
- strcpy(cp, cp2);
- free(cp2);
- return cp;
- }
- char *
- Curl_ldap_first_attribute_a(void * ld,
- LDAPMessage * entry, BerElement * * berptr)
- {
- int i;
- char * cp;
- char * cp2;
- cp = ldap_first_attribute(ld, entry, berptr);
- if(!cp)
- return cp;
- i = strlen(cp);
- if(!(cp2 = malloc(i + 1)))
- return cp2;
- QadrtConvertE2A(cp2, cp, i, i);
- cp2[i] = '\0';
- /* No way to allocate a buffer here, because it will be released by
- ldap_memfree() and ldap_memalloc() does not exist. The solution is to
- overwrite the EBCDIC buffer with ASCII to return it. */
- strcpy(cp, cp2);
- free(cp2);
- return cp;
- }
- char *
- Curl_ldap_next_attribute_a(void * ld,
- LDAPMessage * entry, BerElement * berptr)
- {
- int i;
- char * cp;
- char * cp2;
- cp = ldap_next_attribute(ld, entry, berptr);
- if(!cp)
- return cp;
- i = strlen(cp);
- if(!(cp2 = malloc(i + 1)))
- return cp2;
- QadrtConvertE2A(cp2, cp, i, i);
- cp2[i] = '\0';
- /* No way to allocate a buffer here, because it will be released by
- ldap_memfree() and ldap_memalloc() does not exist. The solution is to
- overwrite the EBCDIC buffer with ASCII to return it. */
- strcpy(cp, cp2);
- free(cp2);
- return cp;
- }
- #endif /* CURL_DISABLE_LDAP */
- static int
- convert_sockaddr(struct sockaddr_storage * dstaddr,
- const struct sockaddr * srcaddr, int srclen)
- {
- const struct sockaddr_un * srcu;
- struct sockaddr_un * dstu;
- unsigned int i;
- unsigned int dstsize;
- /* Convert a socket address into job CCSID, if needed. */
- if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
- sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
- errno = EINVAL;
- return -1;
- }
- memcpy((char *) dstaddr, (char *) srcaddr, srclen);
- switch (srcaddr->sa_family) {
- case AF_UNIX:
- srcu = (const struct sockaddr_un *) srcaddr;
- dstu = (struct sockaddr_un *) dstaddr;
- dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
- srclen -= offsetof(struct sockaddr_un, sun_path);
- i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
- dstu->sun_path[i] = '\0';
- i += offsetof(struct sockaddr_un, sun_path);
- srclen = i;
- }
- return srclen;
- }
- int
- Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
- {
- int i;
- struct sockaddr_storage laddr;
- i = convert_sockaddr(&laddr, destaddr, addrlen);
- if(i < 0)
- return -1;
- return connect(sd, (struct sockaddr *) &laddr, i);
- }
- int
- Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
- {
- int i;
- struct sockaddr_storage laddr;
- i = convert_sockaddr(&laddr, localaddr, addrlen);
- if(i < 0)
- return -1;
- return bind(sd, (struct sockaddr *) &laddr, i);
- }
- int
- Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
- struct sockaddr * dstaddr, int addrlen)
- {
- int i;
- struct sockaddr_storage laddr;
- i = convert_sockaddr(&laddr, dstaddr, addrlen);
- if(i < 0)
- return -1;
- return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
- }
- int
- Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
- struct sockaddr * fromaddr, int * addrlen)
- {
- int i;
- int rcvlen;
- int laddrlen;
- const struct sockaddr_un * srcu;
- struct sockaddr_un * dstu;
- struct sockaddr_storage laddr;
- if(!fromaddr || !addrlen || *addrlen <= 0)
- return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
- laddrlen = sizeof laddr;
- laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
- rcvlen = recvfrom(sd, buffer, buflen, flags,
- (struct sockaddr *) &laddr, &laddrlen);
- if(rcvlen < 0)
- return rcvlen;
- switch (laddr.ss_family) {
- case AF_UNIX:
- srcu = (const struct sockaddr_un *) &laddr;
- dstu = (struct sockaddr_un *) fromaddr;
- i = *addrlen - offsetof(struct sockaddr_un, sun_path);
- laddrlen -= offsetof(struct sockaddr_un, sun_path);
- i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
- laddrlen = i + offsetof(struct sockaddr_un, sun_path);
- if(laddrlen < *addrlen)
- dstu->sun_path[i] = '\0';
- break;
- case AF_UNSPEC:
- break;
- default:
- if(laddrlen > *addrlen)
- laddrlen = *addrlen;
- if(laddrlen)
- memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
- break;
- }
- *addrlen = laddrlen;
- return rcvlen;
- }
- #ifdef HAVE_LIBZ
- const char *
- Curl_os400_zlibVersion(void)
- {
- return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
- }
- int
- Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
- {
- z_const char * msgb4 = strm->msg;
- int ret;
- ret = inflateInit(strm);
- if(strm->msg != msgb4)
- strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
- return ret;
- }
- int
- Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
- const char * version, int stream_size)
- {
- z_const char * msgb4 = strm->msg;
- int ret;
- ret = inflateInit2(strm, windowBits);
- if(strm->msg != msgb4)
- strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
- return ret;
- }
- int
- Curl_os400_inflate(z_streamp strm, int flush)
- {
- z_const char * msgb4 = strm->msg;
- int ret;
- ret = inflate(strm, flush);
- if(strm->msg != msgb4)
- strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
- return ret;
- }
- int
- Curl_os400_inflateEnd(z_streamp strm)
- {
- z_const char * msgb4 = strm->msg;
- int ret;
- ret = inflateEnd(strm);
- if(strm->msg != msgb4)
- strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
- return ret;
- }
- #endif
|