00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "curlbuild.h"
00027 #include "config-os400.h"
00028
00029 #include <sys/types.h>
00030 #include <sys/socket.h>
00031 #include <sys/un.h>
00032
00033 #include <stdlib.h>
00034 #include <stddef.h>
00035 #include <string.h>
00036 #include <pthread.h>
00037 #include <netdb.h>
00038 #include <qadrt.h>
00039 #include <errno.h>
00040
00041 #ifdef HAVE_ZLIB_H
00042 #include <zlib.h>
00043 #endif
00044
00045 #ifdef USE_GSKIT
00046 #include <gskssl.h>
00047 #include <qsoasync.h>
00048 #endif
00049
00050 #ifdef HAVE_GSSAPI
00051 #include <gssapi.h>
00052 #endif
00053
00054 #ifndef CURL_DISABLE_LDAP
00055 #include <ldap.h>
00056 #endif
00057
00058 #include <netinet/in.h>
00059 #include <arpa/inet.h>
00060
00061 #include "os400sys.h"
00062
00063
00071 #pragma convert(0)
00072
00073
00074 #define MIN_BYTE_GAIN 1024
00075
00076 typedef struct {
00077 unsigned long size;
00078 char * buf;
00079 } buffer_t;
00080
00081
00082 static char * buffer_undef(localkey_t key, long size);
00083 static char * buffer_threaded(localkey_t key, long size);
00084 static char * buffer_unthreaded(localkey_t key, long size);
00085
00086 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
00087 static pthread_key_t thdkey;
00088 static buffer_t * locbufs;
00089
00090 char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
00091
00092
00093 static void
00094 thdbufdestroy(void * private)
00095
00096 {
00097 if(private) {
00098 buffer_t * p = (buffer_t *) private;
00099 localkey_t i;
00100
00101 for(i = (localkey_t) 0; i < LK_LAST; i++) {
00102 free(p->buf);
00103 p++;
00104 }
00105
00106 free(private);
00107 }
00108 }
00109
00110
00111 static void
00112 terminate(void)
00113
00114 {
00115 if(Curl_thread_buffer == buffer_threaded) {
00116 locbufs = pthread_getspecific(thdkey);
00117 pthread_setspecific(thdkey, (void *) NULL);
00118 pthread_key_delete(thdkey);
00119 }
00120
00121 if(Curl_thread_buffer != buffer_undef) {
00122 thdbufdestroy((void *) locbufs);
00123 locbufs = (buffer_t *) NULL;
00124 }
00125
00126 Curl_thread_buffer = buffer_undef;
00127 }
00128
00129
00130 static char *
00131 get_buffer(buffer_t * buf, long size)
00132
00133 {
00134 char * cp;
00135
00136
00137
00138
00139 if(size < 0)
00140 return buf->buf;
00141
00142 if(!buf->buf) {
00143 if((buf->buf = malloc(size)))
00144 buf->size = size;
00145
00146 return buf->buf;
00147 }
00148
00149 if((unsigned long) size <= buf->size) {
00150
00151
00152
00153 if(buf->size - size < MIN_BYTE_GAIN)
00154 return buf->buf;
00155 }
00156
00157
00158
00159 if((cp = realloc(buf->buf, size))) {
00160 buf->buf = cp;
00161 buf->size = size;
00162 }
00163 else if(size <= buf->size)
00164 cp = buf->buf;
00165
00166 return cp;
00167 }
00168
00169
00170 static char *
00171 buffer_unthreaded(localkey_t key, long size)
00172
00173 {
00174 return get_buffer(locbufs + key, size);
00175 }
00176
00177
00178 static char *
00179 buffer_threaded(localkey_t key, long size)
00180
00181 {
00182 buffer_t * bufs;
00183
00184
00185
00186
00187
00188 bufs = (buffer_t *) pthread_getspecific(thdkey);
00189
00190 if(!bufs) {
00191 if(size < 0)
00192 return (char *) NULL;
00193
00194
00195
00196 if(!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
00197 return (char *) NULL;
00198
00199 if(pthread_setspecific(thdkey, (void *) bufs)) {
00200 free(bufs);
00201 return (char *) NULL;
00202 }
00203 }
00204
00205 return get_buffer(bufs + key, size);
00206 }
00207
00208
00209 static char *
00210 buffer_undef(localkey_t key, long size)
00211
00212 {
00213
00214
00215
00216
00217 pthread_mutex_lock(&mutex);
00218
00219
00220
00221 if(Curl_thread_buffer == buffer_undef) {
00222 if(!pthread_key_create(&thdkey, thdbufdestroy))
00223 Curl_thread_buffer = buffer_threaded;
00224 else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
00225 pthread_mutex_unlock(&mutex);
00226 return (char *) NULL;
00227 }
00228 else
00229 Curl_thread_buffer = buffer_unthreaded;
00230
00231 atexit(terminate);
00232 }
00233
00234 pthread_mutex_unlock(&mutex);
00235 return Curl_thread_buffer(key, size);
00236 }
00237
00238
00239 static char *
00240 set_thread_string(localkey_t key, const char * s)
00241
00242 {
00243 int i;
00244 char * cp;
00245
00246 if(!s)
00247 return (char *) NULL;
00248
00249 i = strlen(s) + 1;
00250 cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
00251
00252 if(cp) {
00253 i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
00254 cp[i] = '\0';
00255 }
00256
00257 return cp;
00258 }
00259
00260
00261 int
00262 Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
00263 char * nodename, curl_socklen_t nodenamelen,
00264 char * servname, curl_socklen_t servnamelen,
00265 int flags)
00266
00267 {
00268 char * enodename;
00269 char * eservname;
00270 int status;
00271 int i;
00272
00273 enodename = (char *) NULL;
00274 eservname = (char *) NULL;
00275
00276 if(nodename && nodenamelen)
00277 if(!(enodename = malloc(nodenamelen)))
00278 return EAI_MEMORY;
00279
00280 if(servname && servnamelen)
00281 if(!(eservname = malloc(servnamelen))) {
00282 free(enodename);
00283 return EAI_MEMORY;
00284 }
00285
00286 status = getnameinfo(sa, salen, enodename, nodenamelen,
00287 eservname, servnamelen, flags);
00288
00289 if(!status) {
00290 if(enodename) {
00291 i = QadrtConvertE2A(nodename, enodename,
00292 nodenamelen - 1, strlen(enodename));
00293 nodename[i] = '\0';
00294 }
00295
00296 if(eservname) {
00297 i = QadrtConvertE2A(servname, eservname,
00298 servnamelen - 1, strlen(eservname));
00299 servname[i] = '\0';
00300 }
00301 }
00302
00303 free(enodename);
00304 free(eservname);
00305 return status;
00306 }
00307
00308
00309 int
00310 Curl_getaddrinfo_a(const char * nodename, const char * servname,
00311 const struct addrinfo * hints,
00312 struct addrinfo * * res)
00313
00314 {
00315 char * enodename;
00316 char * eservname;
00317 int status;
00318 int i;
00319
00320 enodename = (char *) NULL;
00321 eservname = (char *) NULL;
00322
00323 if(nodename) {
00324 i = strlen(nodename);
00325
00326 if(!(enodename = malloc(i + 1)))
00327 return EAI_MEMORY;
00328
00329 i = QadrtConvertA2E(enodename, nodename, i, i);
00330 enodename[i] = '\0';
00331 }
00332
00333 if(servname) {
00334 i = strlen(servname);
00335
00336 if(!(eservname = malloc(i + 1))) {
00337 free(enodename);
00338 return EAI_MEMORY;
00339 }
00340
00341 QadrtConvertA2E(eservname, servname, i, i);
00342 eservname[i] = '\0';
00343 }
00344
00345 status = getaddrinfo(enodename, eservname, hints, res);
00346 free(enodename);
00347 free(eservname);
00348 return status;
00349 }
00350
00351
00352 #ifdef USE_GSKIT
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 struct gskstrlist {
00367 struct gskstrlist * next;
00368 const char * ebcdicstr;
00369 const char * asciistr;
00370 };
00371
00372 struct Curl_gsk_descriptor {
00373 gsk_handle h;
00374 struct gskstrlist * strlist;
00375 };
00376
00377
00378 int
00379 Curl_gsk_environment_open(gsk_handle * my_env_handle)
00380
00381 {
00382 struct Curl_gsk_descriptor * p;
00383 gsk_handle h;
00384 int rc;
00385
00386 if(!my_env_handle)
00387 return GSK_OS400_ERROR_INVALID_POINTER;
00388 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
00389 return GSK_INSUFFICIENT_STORAGE;
00390 p->strlist = (struct gskstrlist *) NULL;
00391 if((rc = gsk_environment_open(&p->h)) != GSK_OK)
00392 free(p);
00393 else
00394 *my_env_handle = (gsk_handle) p;
00395 return rc;
00396 }
00397
00398
00399 int
00400 Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
00401 gsk_handle * my_session_handle)
00402
00403 {
00404 struct Curl_gsk_descriptor * p;
00405 gsk_handle h;
00406 int rc;
00407
00408 if(!my_env_handle)
00409 return GSK_INVALID_HANDLE;
00410 if(!my_session_handle)
00411 return GSK_OS400_ERROR_INVALID_POINTER;
00412 h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
00413 if(!(p = (struct Curl_gsk_descriptor *) malloc(sizeof *p)))
00414 return GSK_INSUFFICIENT_STORAGE;
00415 p->strlist = (struct gskstrlist *) NULL;
00416 if((rc = gsk_secure_soc_open(h, &p->h)) != GSK_OK)
00417 free(p);
00418 else
00419 *my_session_handle = (gsk_handle) p;
00420 return rc;
00421 }
00422
00423
00424 static void
00425 gsk_free_handle(struct Curl_gsk_descriptor * p)
00426
00427 {
00428 struct gskstrlist * q;
00429
00430 while((q = p->strlist)) {
00431 p->strlist = q;
00432 free((void *) q->asciistr);
00433 free(q);
00434 }
00435 free(p);
00436 }
00437
00438
00439 int
00440 Curl_gsk_environment_close(gsk_handle * my_env_handle)
00441
00442 {
00443 struct Curl_gsk_descriptor * p;
00444 int rc;
00445
00446 if(!my_env_handle)
00447 return GSK_OS400_ERROR_INVALID_POINTER;
00448 if(!*my_env_handle)
00449 return GSK_INVALID_HANDLE;
00450 p = (struct Curl_gsk_descriptor *) *my_env_handle;
00451 if((rc = gsk_environment_close(&p->h)) == GSK_OK) {
00452 gsk_free_handle(p);
00453 *my_env_handle = (gsk_handle) NULL;
00454 }
00455 return rc;
00456 }
00457
00458
00459 int
00460 Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
00461
00462 {
00463 struct Curl_gsk_descriptor * p;
00464 int rc;
00465
00466 if(!my_session_handle)
00467 return GSK_OS400_ERROR_INVALID_POINTER;
00468 if(!*my_session_handle)
00469 return GSK_INVALID_HANDLE;
00470 p = (struct Curl_gsk_descriptor *) *my_session_handle;
00471 if((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
00472 gsk_free_handle(p);
00473 *my_session_handle = (gsk_handle) NULL;
00474 }
00475 return rc;
00476 }
00477
00478
00479 int
00480 Curl_gsk_environment_init(gsk_handle my_env_handle)
00481
00482 {
00483 struct Curl_gsk_descriptor * p;
00484
00485 if(!my_env_handle)
00486 return GSK_INVALID_HANDLE;
00487 p = (struct Curl_gsk_descriptor *) my_env_handle;
00488 return gsk_environment_init(p->h);
00489 }
00490
00491
00492 int
00493 Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
00494
00495 {
00496 struct Curl_gsk_descriptor * p;
00497
00498 if(!my_session_handle)
00499 return GSK_INVALID_HANDLE;
00500 p = (struct Curl_gsk_descriptor *) my_session_handle;
00501 return gsk_secure_soc_init(p->h);
00502 }
00503
00504
00505 int
00506 Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
00507 const char * buffer, int bufSize)
00508
00509 {
00510 struct Curl_gsk_descriptor * p;
00511 char * ebcdicbuf;
00512 int rc;
00513
00514 if(!my_gsk_handle)
00515 return GSK_INVALID_HANDLE;
00516 if(!buffer)
00517 return GSK_OS400_ERROR_INVALID_POINTER;
00518 if(bufSize < 0)
00519 return GSK_ATTRIBUTE_INVALID_LENGTH;
00520 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00521 if(!bufSize)
00522 bufSize = strlen(buffer);
00523 if(!(ebcdicbuf = malloc(bufSize + 1)))
00524 return GSK_INSUFFICIENT_STORAGE;
00525 QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
00526 ebcdicbuf[bufSize] = '\0';
00527 rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
00528 free(ebcdicbuf);
00529 return rc;
00530 }
00531
00532
00533 int
00534 Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
00535 GSK_ENUM_VALUE enumValue)
00536
00537 {
00538 struct Curl_gsk_descriptor * p;
00539
00540 if(!my_gsk_handle)
00541 return GSK_INVALID_HANDLE;
00542 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00543 return gsk_attribute_set_enum(p->h, enumID, enumValue);
00544 }
00545
00546
00547 int
00548 Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
00549 GSK_NUM_ID numID, int numValue)
00550
00551 {
00552 struct Curl_gsk_descriptor * p;
00553
00554 if(!my_gsk_handle)
00555 return GSK_INVALID_HANDLE;
00556 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00557 return gsk_attribute_set_numeric_value(p->h, numID, numValue);
00558 }
00559
00560
00561 int
00562 Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
00563 GSK_CALLBACK_ID callBackID,
00564 void * callBackAreaPtr)
00565
00566 {
00567 struct Curl_gsk_descriptor * p;
00568
00569 if(!my_gsk_handle)
00570 return GSK_INVALID_HANDLE;
00571 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00572 return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
00573 }
00574
00575
00576 static int
00577 cachestring(struct Curl_gsk_descriptor * p,
00578 const char * ebcdicbuf, int bufsize, const char * * buffer)
00579
00580 {
00581 int rc;
00582 char * asciibuf;
00583 struct gskstrlist * sp;
00584
00585 for(sp = p->strlist; sp; sp = sp->next)
00586 if(sp->ebcdicstr == ebcdicbuf)
00587 break;
00588 if(!sp) {
00589 if(!(sp = (struct gskstrlist *) malloc(sizeof *sp)))
00590 return GSK_INSUFFICIENT_STORAGE;
00591 if(!(asciibuf = malloc(bufsize + 1))) {
00592 free(sp);
00593 return GSK_INSUFFICIENT_STORAGE;
00594 }
00595 QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
00596 asciibuf[bufsize] = '\0';
00597 sp->ebcdicstr = ebcdicbuf;
00598 sp->asciistr = asciibuf;
00599 sp->next = p->strlist;
00600 p->strlist = sp;
00601 }
00602 *buffer = sp->asciistr;
00603 return GSK_OK;
00604 }
00605
00606
00607 int
00608 Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
00609 const char * * buffer, int * bufSize)
00610
00611 {
00612 struct Curl_gsk_descriptor * p;
00613 int rc;
00614 const char * mybuf;
00615 int mylen;
00616
00617 if(!my_gsk_handle)
00618 return GSK_INVALID_HANDLE;
00619 if(!buffer || !bufSize)
00620 return GSK_OS400_ERROR_INVALID_POINTER;
00621 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00622 if((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
00623 return rc;
00624 if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
00625 *bufSize = mylen;
00626 return rc;
00627 }
00628
00629
00630 int
00631 Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
00632 GSK_ENUM_VALUE * enumValue)
00633
00634 {
00635 struct Curl_gsk_descriptor * p;
00636
00637 if(!my_gsk_handle)
00638 return GSK_INVALID_HANDLE;
00639 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00640 return gsk_attribute_get_enum(p->h, enumID, enumValue);
00641 }
00642
00643
00644 int
00645 Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
00646 GSK_NUM_ID numID, int * numValue)
00647
00648 {
00649 struct Curl_gsk_descriptor * p;
00650
00651 if(!my_gsk_handle)
00652 return GSK_INVALID_HANDLE;
00653 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00654 return gsk_attribute_get_numeric_value(p->h, numID, numValue);
00655 }
00656
00657
00658 int
00659 Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
00660 GSK_CERT_ID certID,
00661 const gsk_cert_data_elem * * certDataElem,
00662 int * certDataElementCount)
00663
00664 {
00665 struct Curl_gsk_descriptor * p;
00666
00667 if(!my_gsk_handle)
00668 return GSK_INVALID_HANDLE;
00669 p = (struct Curl_gsk_descriptor *) my_gsk_handle;
00670
00671 return gsk_attribute_get_cert_info(p->h, certID,
00672 certDataElem, certDataElementCount);
00673 }
00674
00675
00676 int
00677 Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
00678
00679 {
00680 struct Curl_gsk_descriptor * p;
00681
00682 if(!my_session_handle)
00683 return GSK_INVALID_HANDLE;
00684 p = (struct Curl_gsk_descriptor *) my_session_handle;
00685 return gsk_secure_soc_misc(p->h, miscID);
00686 }
00687
00688
00689 int
00690 Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
00691 int readBufSize, int * amtRead)
00692
00693 {
00694 struct Curl_gsk_descriptor * p;
00695
00696 if(!my_session_handle)
00697 return GSK_INVALID_HANDLE;
00698 p = (struct Curl_gsk_descriptor *) my_session_handle;
00699 return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
00700 }
00701
00702
00703 int
00704 Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
00705 int writeBufSize, int * amtWritten)
00706
00707 {
00708 struct Curl_gsk_descriptor * p;
00709
00710 if(!my_session_handle)
00711 return GSK_INVALID_HANDLE;
00712 p = (struct Curl_gsk_descriptor *) my_session_handle;
00713 return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
00714 }
00715
00716
00717 const char *
00718 Curl_gsk_strerror_a(int gsk_return_value)
00719
00720 {
00721 return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
00722 }
00723
00724 int
00725 Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
00726 int IOCompletionPort,
00727 Qso_OverlappedIO_t * communicationsArea)
00728
00729 {
00730 struct Curl_gsk_descriptor * p;
00731
00732 if(!my_session_handle)
00733 return GSK_INVALID_HANDLE;
00734 p = (struct Curl_gsk_descriptor *) my_session_handle;
00735 return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
00736 }
00737
00738 #endif
00739
00740
00741
00742 #ifdef HAVE_GSSAPI
00743
00744
00745
00746 static int
00747 Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
00748
00749 {
00750 unsigned int i;
00751 char * t;
00752
00753
00754
00755
00756 i = buf->length;
00757
00758 if(i) {
00759 if(!(t = malloc(i))) {
00760 gss_release_buffer(minor_status, buf);
00761
00762 if(minor_status)
00763 *minor_status = ENOMEM;
00764
00765 return -1;
00766 }
00767
00768 QadrtConvertE2A(t, buf->value, i, i);
00769 memcpy(buf->value, t, i);
00770 free(t);
00771 }
00772
00773 return 0;
00774 }
00775
00776
00777 OM_uint32
00778 Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
00779 gss_OID in_name_type, gss_name_t * out_name)
00780
00781 {
00782 int rc;
00783 unsigned int i;
00784 gss_buffer_desc in;
00785
00786 if(!in_name || !in_name->value || !in_name->length)
00787 return gss_import_name(minor_status, in_name, in_name_type, out_name);
00788
00789 memcpy((char *) &in, (char *) in_name, sizeof in);
00790 i = in.length;
00791
00792 if(!(in.value = malloc(i + 1))) {
00793 if(minor_status)
00794 *minor_status = ENOMEM;
00795
00796 return GSS_S_FAILURE;
00797 }
00798
00799 QadrtConvertA2E(in.value, in_name->value, i, i);
00800 ((char *) in.value)[i] = '\0';
00801 rc = gss_import_name(minor_status, &in, in_name_type, out_name);
00802 free(in.value);
00803 return rc;
00804 }
00805
00806
00807 OM_uint32
00808 Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
00809 int status_type, gss_OID mech_type,
00810 gss_msg_ctx_t * message_context, gss_buffer_t status_string)
00811
00812 {
00813 int rc;
00814
00815 rc = gss_display_status(minor_status, status_value, status_type,
00816 mech_type, message_context, status_string);
00817
00818 if(rc != GSS_S_COMPLETE || !status_string ||
00819 !status_string->length || !status_string->value)
00820 return rc;
00821
00822
00823
00824
00825
00826 if(Curl_gss_convert_in_place(minor_status, status_string))
00827 return GSS_S_FAILURE;
00828
00829 return rc;
00830 }
00831
00832
00833 OM_uint32
00834 Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
00835 gss_cred_id_t cred_handle,
00836 gss_ctx_id_t * context_handle,
00837 gss_name_t target_name, gss_OID mech_type,
00838 gss_flags_t req_flags, OM_uint32 time_req,
00839 gss_channel_bindings_t input_chan_bindings,
00840 gss_buffer_t input_token,
00841 gss_OID * actual_mech_type,
00842 gss_buffer_t output_token, gss_flags_t * ret_flags,
00843 OM_uint32 * time_rec)
00844
00845 {
00846 int rc;
00847 unsigned int i;
00848 gss_buffer_desc in;
00849 gss_buffer_t inp;
00850
00851 in.value = NULL;
00852
00853 if((inp = input_token))
00854 if(inp->length && inp->value) {
00855 i = inp->length;
00856
00857 if(!(in.value = malloc(i + 1))) {
00858 if(minor_status)
00859 *minor_status = ENOMEM;
00860
00861 return GSS_S_FAILURE;
00862 }
00863
00864 QadrtConvertA2E(in.value, input_token->value, i, i);
00865 ((char *) in.value)[i] = '\0';
00866 in.length = i;
00867 inp = ∈
00868 }
00869
00870 rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
00871 target_name, mech_type, req_flags, time_req,
00872 input_chan_bindings, inp, actual_mech_type,
00873 output_token, ret_flags, time_rec);
00874 free(in.value);
00875
00876 if(rc != GSS_S_COMPLETE || !output_token ||
00877 !output_token->length || !output_token->value)
00878 return rc;
00879
00880
00881
00882
00883
00884 if(Curl_gss_convert_in_place(minor_status, output_token))
00885 return GSS_S_FAILURE;
00886
00887 return rc;
00888 }
00889
00890
00891 OM_uint32
00892 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
00893 gss_ctx_id_t * context_handle,
00894 gss_buffer_t output_token)
00895
00896 {
00897 int rc;
00898
00899 rc = gss_delete_sec_context(minor_status, context_handle, output_token);
00900
00901 if(rc != GSS_S_COMPLETE || !output_token ||
00902 !output_token->length || !output_token->value)
00903 return rc;
00904
00905
00906
00907
00908
00909 if(Curl_gss_convert_in_place(minor_status, output_token))
00910 return GSS_S_FAILURE;
00911
00912 return rc;
00913 }
00914
00915 #endif
00916
00917
00918 #ifndef CURL_DISABLE_LDAP
00919
00920
00921
00922 void *
00923 Curl_ldap_init_a(char * host, int port)
00924
00925 {
00926 unsigned int i;
00927 char * ehost;
00928 void * result;
00929
00930 if(!host)
00931 return (void *) ldap_init(host, port);
00932
00933 i = strlen(host);
00934
00935 if(!(ehost = malloc(i + 1)))
00936 return (void *) NULL;
00937
00938 QadrtConvertA2E(ehost, host, i, i);
00939 ehost[i] = '\0';
00940 result = (void *) ldap_init(ehost, port);
00941 free(ehost);
00942 return result;
00943 }
00944
00945
00946 int
00947 Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
00948
00949 {
00950 int i;
00951 char * edn;
00952 char * epasswd;
00953
00954 edn = (char *) NULL;
00955 epasswd = (char *) NULL;
00956
00957 if(dn) {
00958 i = strlen(dn);
00959
00960 if(!(edn = malloc(i + 1)))
00961 return LDAP_NO_MEMORY;
00962
00963 QadrtConvertA2E(edn, dn, i, i);
00964 edn[i] = '\0';
00965 }
00966
00967 if(passwd) {
00968 i = strlen(passwd);
00969
00970 if(!(epasswd = malloc(i + 1))) {
00971 free(edn);
00972 return LDAP_NO_MEMORY;
00973 }
00974
00975 QadrtConvertA2E(epasswd, passwd, i, i);
00976 epasswd[i] = '\0';
00977 }
00978
00979 i = ldap_simple_bind_s(ld, edn, epasswd);
00980 free(epasswd);
00981 free(edn);
00982 return i;
00983 }
00984
00985
00986 int
00987 Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
00988 char * * attrs, int attrsonly, LDAPMessage * * res)
00989
00990 {
00991 int i;
00992 int j;
00993 char * ebase;
00994 char * efilter;
00995 char * * eattrs;
00996 int status;
00997
00998 ebase = (char *) NULL;
00999 efilter = (char *) NULL;
01000 eattrs = (char * *) NULL;
01001 status = LDAP_SUCCESS;
01002
01003 if(base) {
01004 i = strlen(base);
01005
01006 if(!(ebase = malloc(i + 1)))
01007 status = LDAP_NO_MEMORY;
01008 else {
01009 QadrtConvertA2E(ebase, base, i, i);
01010 ebase[i] = '\0';
01011 }
01012 }
01013
01014 if(filter && status == LDAP_SUCCESS) {
01015 i = strlen(filter);
01016
01017 if(!(efilter = malloc(i + 1)))
01018 status = LDAP_NO_MEMORY;
01019 else {
01020 QadrtConvertA2E(efilter, filter, i, i);
01021 efilter[i] = '\0';
01022 }
01023 }
01024
01025 if(attrs && status == LDAP_SUCCESS) {
01026 for(i = 0; attrs[i++];)
01027 ;
01028
01029 if(!(eattrs = calloc(i, sizeof *eattrs)))
01030 status = LDAP_NO_MEMORY;
01031 else {
01032 for(j = 0; attrs[j]; j++) {
01033 i = strlen(attrs[j]);
01034
01035 if(!(eattrs[j] = malloc(i + 1))) {
01036 status = LDAP_NO_MEMORY;
01037 break;
01038 }
01039
01040 QadrtConvertA2E(eattrs[j], attrs[j], i, i);
01041 eattrs[j][i] = '\0';
01042 }
01043 }
01044 }
01045
01046 if(status == LDAP_SUCCESS)
01047 status = ldap_search_s(ld, ebase? ebase: "", scope,
01048 efilter? efilter: "(objectclass=*)",
01049 eattrs, attrsonly, res);
01050
01051 if(eattrs) {
01052 for(j = 0; eattrs[j]; j++)
01053 free(eattrs[j]);
01054
01055 free(eattrs);
01056 }
01057
01058 free(efilter);
01059 free(ebase);
01060 return status;
01061 }
01062
01063
01064 struct berval * *
01065 Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
01066
01067 {
01068 char * cp;
01069 struct berval * * result;
01070
01071 cp = (char *) NULL;
01072
01073 if(attr) {
01074 int i = strlen(attr);
01075
01076 if(!(cp = malloc(i + 1))) {
01077 ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
01078 ldap_err2string(LDAP_NO_MEMORY));
01079 return (struct berval * *) NULL;
01080 }
01081
01082 QadrtConvertA2E(cp, attr, i, i);
01083 cp[i] = '\0';
01084 }
01085
01086 result = ldap_get_values_len(ld, entry, cp);
01087 free(cp);
01088
01089
01090
01091
01092 return result;
01093 }
01094
01095
01096 char *
01097 Curl_ldap_err2string_a(int error)
01098
01099 {
01100 return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
01101 }
01102
01103
01104 char *
01105 Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
01106
01107 {
01108 int i;
01109 char * cp;
01110 char * cp2;
01111
01112 cp = ldap_get_dn(ld, entry);
01113
01114 if(!cp)
01115 return cp;
01116
01117 i = strlen(cp);
01118
01119 if(!(cp2 = malloc(i + 1)))
01120 return cp2;
01121
01122 QadrtConvertE2A(cp2, cp, i, i);
01123 cp2[i] = '\0';
01124
01125
01126
01127
01128
01129 strcpy(cp, cp2);
01130 free(cp2);
01131 return cp;
01132 }
01133
01134
01135 char *
01136 Curl_ldap_first_attribute_a(void * ld,
01137 LDAPMessage * entry, BerElement * * berptr)
01138
01139 {
01140 int i;
01141 char * cp;
01142 char * cp2;
01143
01144 cp = ldap_first_attribute(ld, entry, berptr);
01145
01146 if(!cp)
01147 return cp;
01148
01149 i = strlen(cp);
01150
01151 if(!(cp2 = malloc(i + 1)))
01152 return cp2;
01153
01154 QadrtConvertE2A(cp2, cp, i, i);
01155 cp2[i] = '\0';
01156
01157
01158
01159
01160
01161 strcpy(cp, cp2);
01162 free(cp2);
01163 return cp;
01164 }
01165
01166
01167 char *
01168 Curl_ldap_next_attribute_a(void * ld,
01169 LDAPMessage * entry, BerElement * berptr)
01170
01171 {
01172 int i;
01173 char * cp;
01174 char * cp2;
01175
01176 cp = ldap_next_attribute(ld, entry, berptr);
01177
01178 if(!cp)
01179 return cp;
01180
01181 i = strlen(cp);
01182
01183 if(!(cp2 = malloc(i + 1)))
01184 return cp2;
01185
01186 QadrtConvertE2A(cp2, cp, i, i);
01187 cp2[i] = '\0';
01188
01189
01190
01191
01192
01193 strcpy(cp, cp2);
01194 free(cp2);
01195 return cp;
01196 }
01197
01198 #endif
01199
01200
01201 static int
01202 convert_sockaddr(struct sockaddr_storage * dstaddr,
01203 const struct sockaddr * srcaddr, int srclen)
01204
01205 {
01206 const struct sockaddr_un * srcu;
01207 struct sockaddr_un * dstu;
01208 unsigned int i;
01209 unsigned int dstsize;
01210
01211
01212
01213 if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
01214 sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
01215 errno = EINVAL;
01216 return -1;
01217 }
01218
01219 memcpy((char *) dstaddr, (char *) srcaddr, srclen);
01220
01221 switch (srcaddr->sa_family) {
01222
01223 case AF_UNIX:
01224 srcu = (const struct sockaddr_un *) srcaddr;
01225 dstu = (struct sockaddr_un *) dstaddr;
01226 dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
01227 srclen -= offsetof(struct sockaddr_un, sun_path);
01228 i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
01229 dstu->sun_path[i] = '\0';
01230 i += offsetof(struct sockaddr_un, sun_path);
01231 srclen = i;
01232 }
01233
01234 return srclen;
01235 }
01236
01237
01238 int
01239 Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
01240
01241 {
01242 int i;
01243 struct sockaddr_storage laddr;
01244
01245 i = convert_sockaddr(&laddr, destaddr, addrlen);
01246
01247 if(i < 0)
01248 return -1;
01249
01250 return connect(sd, (struct sockaddr *) &laddr, i);
01251 }
01252
01253
01254 int
01255 Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
01256
01257 {
01258 int i;
01259 struct sockaddr_storage laddr;
01260
01261 i = convert_sockaddr(&laddr, localaddr, addrlen);
01262
01263 if(i < 0)
01264 return -1;
01265
01266 return bind(sd, (struct sockaddr *) &laddr, i);
01267 }
01268
01269
01270 int
01271 Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
01272 struct sockaddr * dstaddr, int addrlen)
01273
01274 {
01275 int i;
01276 struct sockaddr_storage laddr;
01277
01278 i = convert_sockaddr(&laddr, dstaddr, addrlen);
01279
01280 if(i < 0)
01281 return -1;
01282
01283 return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
01284 }
01285
01286
01287 int
01288 Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
01289 struct sockaddr * fromaddr, int * addrlen)
01290
01291 {
01292 int i;
01293 int rcvlen;
01294 int laddrlen;
01295 const struct sockaddr_un * srcu;
01296 struct sockaddr_un * dstu;
01297 struct sockaddr_storage laddr;
01298
01299 if(!fromaddr || !addrlen || *addrlen <= 0)
01300 return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
01301
01302 laddrlen = sizeof laddr;
01303 laddr.ss_family = AF_UNSPEC;
01304 rcvlen = recvfrom(sd, buffer, buflen, flags,
01305 (struct sockaddr *) &laddr, &laddrlen);
01306
01307 if(rcvlen < 0)
01308 return rcvlen;
01309
01310 switch (laddr.ss_family) {
01311
01312 case AF_UNIX:
01313 srcu = (const struct sockaddr_un *) &laddr;
01314 dstu = (struct sockaddr_un *) fromaddr;
01315 i = *addrlen - offsetof(struct sockaddr_un, sun_path);
01316 laddrlen -= offsetof(struct sockaddr_un, sun_path);
01317 i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
01318 laddrlen = i + offsetof(struct sockaddr_un, sun_path);
01319
01320 if(laddrlen < *addrlen)
01321 dstu->sun_path[i] = '\0';
01322
01323 break;
01324
01325 case AF_UNSPEC:
01326 break;
01327
01328 default:
01329 if(laddrlen > *addrlen)
01330 laddrlen = *addrlen;
01331
01332 if(laddrlen)
01333 memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
01334
01335 break;
01336 }
01337
01338 *addrlen = laddrlen;
01339 return rcvlen;
01340 }
01341
01342
01343 #ifdef HAVE_LIBZ
01344 const char *
01345 Curl_os400_zlibVersion(void)
01346
01347 {
01348 return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
01349 }
01350
01351
01352 int
01353 Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
01354
01355 {
01356 z_const char * msgb4 = strm->msg;
01357 int ret;
01358
01359 ret = inflateInit(strm);
01360
01361 if(strm->msg != msgb4)
01362 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
01363
01364 return ret;
01365 }
01366
01367
01368 int
01369 Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
01370 const char * version, int stream_size)
01371
01372 {
01373 z_const char * msgb4 = strm->msg;
01374 int ret;
01375
01376 ret = inflateInit2(strm, windowBits);
01377
01378 if(strm->msg != msgb4)
01379 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
01380
01381 return ret;
01382 }
01383
01384
01385 int
01386 Curl_os400_inflate(z_streamp strm, int flush)
01387
01388 {
01389 z_const char * msgb4 = strm->msg;
01390 int ret;
01391
01392 ret = inflate(strm, flush);
01393
01394 if(strm->msg != msgb4)
01395 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
01396
01397 return ret;
01398 }
01399
01400
01401 int
01402 Curl_os400_inflateEnd(z_streamp strm)
01403
01404 {
01405 z_const char * msgb4 = strm->msg;
01406 int ret;
01407
01408 ret = inflateEnd(strm);
01409
01410 if(strm->msg != msgb4)
01411 strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
01412
01413 return ret;
01414 }
01415
01416 #endif