os400sys.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  *
00022  ***************************************************************************/
00023 
00024 /* OS/400 additional support. */
00025 
00026 #include "curlbuild.h"
00027 #include "config-os400.h"  /* Not curl_setup.h: we only need some defines. */
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)                              /* Restore EBCDIC. */
00072 
00073 
00074 #define MIN_BYTE_GAIN   1024    /* Minimum gain when shortening a buffer. */
00075 
00076 typedef struct {
00077         unsigned long   size;                   /* Buffer size. */
00078         char *          buf;                    /* Buffer address. */
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   /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
00137      Return the buffer address. */
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     /* Shorten the buffer only if it frees a significant byte count. This
00151        avoids some realloc() overhead. */
00152 
00153     if(buf->size - size < MIN_BYTE_GAIN)
00154       return buf->buf;
00155     }
00156 
00157   /* Resize the buffer. */
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   /* Get the buffer for the given local key in the current thread, and
00185      make sure it is at least `size'-byte long. Set `size' to < 0 to get
00186      its address only. */
00187 
00188   bufs = (buffer_t *) pthread_getspecific(thdkey);
00189 
00190   if(!bufs) {
00191     if(size < 0)
00192       return (char *) NULL;             /* No buffer yet. */
00193 
00194     /* Allocate buffer descriptors for the current thread. */
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   /* Define the buffer system, get the buffer for the given local key in
00214      the current thread, and make sure it is at least `size'-byte long.
00215      Set `size' to < 0 to get its address only. */
00216 
00217   pthread_mutex_lock(&mutex);
00218 
00219   /* Determine if we can use pthread-specific data. */
00220 
00221   if(Curl_thread_buffer == buffer_undef) {      /* If unchanged during lock. */
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 /* ASCII wrappers for the GSKit procedures. */
00355 
00356 /*
00357  * EBCDIC --> ASCII string mapping table.
00358  * Some strings returned by GSKit are dynamically allocated and automatically
00359  * released when closing the handle.
00360  * To provide the same functionality, we use a "private" handle that
00361  * holds the GSKit handle and a list of string mappings. This will allow
00362  * avoid conversion of already converted strings and releasing them upon
00363  * close time.
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   /* No need to convert code: text results are already in ASCII. */
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 /* USE_GSKIT */
00739 
00740 
00741 
00742 #ifdef HAVE_GSSAPI
00743 
00744 /* ASCII wrappers for the GSSAPI procedures. */
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   /* Convert `buf' in place, from EBCDIC to ASCII.
00754      If error, release the buffer and return -1. Else return 0. */
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   /* No way to allocate a buffer here, because it will be released by
00823      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
00824      with ASCII to return it. */
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 = &in;
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   /* No way to allocate a buffer here, because it will be released by
00881      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
00882      with ASCII to return it. */
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   /* No way to allocate a buffer here, because it will be released by
00906      gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
00907      with ASCII to return it. */
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 /* HAVE_GSSAPI */
00916 
00917 
00918 #ifndef CURL_DISABLE_LDAP
00919 
00920 /* ASCII wrappers for the LDAP procedures. */
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   /* Result data are binary in nature, so they haven't been
01090      converted to EBCDIC. Therefore do not convert. */
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   /* No way to allocate a buffer here, because it will be released by
01126      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
01127      overwrite the EBCDIC buffer with ASCII to return it. */
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   /* No way to allocate a buffer here, because it will be released by
01158      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
01159      overwrite the EBCDIC buffer with ASCII to return it. */
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   /* No way to allocate a buffer here, because it will be released by
01190      ldap_memfree() and ldap_memalloc() does not exist. The solution is to
01191      overwrite the EBCDIC buffer with ASCII to return it. */
01192 
01193   strcpy(cp, cp2);
01194   free(cp2);
01195   return cp;
01196 }
01197 
01198 #endif /* CURL_DISABLE_LDAP */
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   /* Convert a socket address into job CCSID, if needed. */
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;          /* To detect if unused. */
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


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:05