Annotation of embedaddon/curl/packages/OS400/os400sys.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
9: *
10: * This software is licensed as described in the file COPYING, which
11: * you should have received as part of this distribution. The terms
12: * are also available at https://curl.haxx.se/docs/copyright.html.
13: *
14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15: * copies of the Software, and permit persons to whom the Software is
16: * furnished to do so, under the terms of the COPYING file.
17: *
18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19: * KIND, either express or implied.
20: *
21: *
22: ***************************************************************************/
23:
24: /* OS/400 additional support. */
25:
26: #include <curl/curl.h>
27: #include "config-os400.h" /* Not curl_setup.h: we only need some defines. */
28:
29: #include <sys/types.h>
30: #include <sys/socket.h>
31: #include <sys/un.h>
32:
33: #include <stdlib.h>
34: #include <stddef.h>
35: #include <string.h>
36: #include <pthread.h>
37: #include <netdb.h>
38: #include <qadrt.h>
39: #include <errno.h>
40:
41: #ifdef HAVE_ZLIB_H
42: #include <zlib.h>
43: #endif
44:
45: #ifdef USE_GSKIT
46: #include <gskssl.h>
47: #include <qsoasync.h>
48: #endif
49:
50: #ifdef HAVE_GSSAPI
51: #include <gssapi.h>
52: #endif
53:
54: #ifndef CURL_DISABLE_LDAP
55: #include <ldap.h>
56: #endif
57:
58: #include <netinet/in.h>
59: #include <arpa/inet.h>
60:
61: #include "os400sys.h"
62:
63:
64: /**
65: *** QADRT OS/400 ASCII runtime defines only the most used procedures, but
66: *** but a lot of them are not supported. This module implements
67: *** ASCII wrappers for those that are used by libcurl, but not
68: *** defined by QADRT.
69: **/
70:
71: #pragma convert(0) /* Restore EBCDIC. */
72:
73:
74: #define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
75:
76: typedef struct {
77: unsigned long size; /* Buffer size. */
78: char * buf; /* Buffer address. */
79: } buffer_t;
80:
81:
82: static char * buffer_undef(localkey_t key, long size);
83: static char * buffer_threaded(localkey_t key, long size);
84: static char * buffer_unthreaded(localkey_t key, long size);
85:
86: static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
87: static pthread_key_t thdkey;
88: static buffer_t * locbufs;
89:
90: char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
91:
92:
93: static void
94: thdbufdestroy(void * private)
95:
96: {
97: if(private) {
98: buffer_t * p = (buffer_t *) private;
99: localkey_t i;
100:
101: for(i = (localkey_t) 0; i < LK_LAST; i++) {
102: free(p->buf);
103: p++;
104: }
105:
106: free(private);
107: }
108: }
109:
110:
111: static void
112: terminate(void)
113:
114: {
115: if(Curl_thread_buffer == buffer_threaded) {
116: locbufs = pthread_getspecific(thdkey);
117: pthread_setspecific(thdkey, (void *) NULL);
118: pthread_key_delete(thdkey);
119: }
120:
121: if(Curl_thread_buffer != buffer_undef) {
122: thdbufdestroy((void *) locbufs);
123: locbufs = (buffer_t *) NULL;
124: }
125:
126: Curl_thread_buffer = buffer_undef;
127: }
128:
129:
130: static char *
131: get_buffer(buffer_t * buf, long size)
132:
133: {
134: char * cp;
135:
136: /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
137: Return the buffer address. */
138:
139: if(size < 0)
140: return buf->buf;
141:
142: if(!buf->buf) {
143: buf->buf = malloc(size);
144: if(buf->buf)
145: buf->size = size;
146:
147: return buf->buf;
148: }
149:
150: if((unsigned long) size <= buf->size) {
151: /* Shorten the buffer only if it frees a significant byte count. This
152: avoids some realloc() overhead. */
153:
154: if(buf->size - size < MIN_BYTE_GAIN)
155: return buf->buf;
156: }
157:
158: /* Resize the buffer. */
159:
160: cp = realloc(buf->buf, size);
161: if(cp) {
162: buf->buf = cp;
163: buf->size = size;
164: }
165: else if(size <= buf->size)
166: cp = buf->buf;
167:
168: return cp;
169: }
170:
171:
172: static char *
173: buffer_unthreaded(localkey_t key, long size)
174:
175: {
176: return get_buffer(locbufs + key, size);
177: }
178:
179:
180: static char *
181: buffer_threaded(localkey_t key, long size)
182:
183: {
184: buffer_t * bufs;
185:
186: /* Get the buffer for the given local key in the current thread, and
187: make sure it is at least `size'-byte long. Set `size' to < 0 to get
188: its address only. */
189:
190: bufs = (buffer_t *) pthread_getspecific(thdkey);
191:
192: if(!bufs) {
193: if(size < 0)
194: return (char *) NULL; /* No buffer yet. */
195:
196: /* Allocate buffer descriptors for the current thread. */
197:
198: bufs = calloc((size_t) LK_LAST, sizeof(*bufs));
199: if(!bufs)
200: return (char *) NULL;
201:
202: if(pthread_setspecific(thdkey, (void *) bufs)) {
203: free(bufs);
204: return (char *) NULL;
205: }
206: }
207:
208: return get_buffer(bufs + key, size);
209: }
210:
211:
212: static char *
213: buffer_undef(localkey_t key, long size)
214:
215: {
216: /* Define the buffer system, get the buffer for the given local key in
217: the current thread, and make sure it is at least `size'-byte long.
218: Set `size' to < 0 to get its address only. */
219:
220: pthread_mutex_lock(&mutex);
221:
222: /* Determine if we can use pthread-specific data. */
223:
224: if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
225: if(!pthread_key_create(&thdkey, thdbufdestroy))
226: Curl_thread_buffer = buffer_threaded;
227: else if(!(locbufs = calloc((size_t) LK_LAST, sizeof(*locbufs)))) {
228: pthread_mutex_unlock(&mutex);
229: return (char *) NULL;
230: }
231: else
232: Curl_thread_buffer = buffer_unthreaded;
233:
234: atexit(terminate);
235: }
236:
237: pthread_mutex_unlock(&mutex);
238: return Curl_thread_buffer(key, size);
239: }
240:
241:
242: static char *
243: set_thread_string(localkey_t key, const char * s)
244:
245: {
246: int i;
247: char * cp;
248:
249: if(!s)
250: return (char *) NULL;
251:
252: i = strlen(s) + 1;
253: cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
254:
255: if(cp) {
256: i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
257: cp[i] = '\0';
258: }
259:
260: return cp;
261: }
262:
263:
264: int
265: Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
266: char * nodename, curl_socklen_t nodenamelen,
267: char * servname, curl_socklen_t servnamelen,
268: int flags)
269:
270: {
271: char *enodename = NULL;
272: char *eservname = NULL;
273: int status;
274:
275: if(nodename && nodenamelen) {
276: enodename = malloc(nodenamelen);
277: if(!enodename)
278: return EAI_MEMORY;
279: }
280:
281: if(servname && servnamelen) {
282: eservname = malloc(servnamelen);
283: if(!eservname) {
284: free(enodename);
285: return EAI_MEMORY;
286: }
287: }
288:
289: status = getnameinfo(sa, salen, enodename, nodenamelen,
290: eservname, servnamelen, flags);
291:
292: if(!status) {
293: int i;
294: if(enodename) {
295: i = QadrtConvertE2A(nodename, enodename,
296: nodenamelen - 1, strlen(enodename));
297: nodename[i] = '\0';
298: }
299:
300: if(eservname) {
301: i = QadrtConvertE2A(servname, eservname,
302: servnamelen - 1, strlen(eservname));
303: servname[i] = '\0';
304: }
305: }
306:
307: free(enodename);
308: free(eservname);
309: return status;
310: }
311:
312:
313: int
314: Curl_getaddrinfo_a(const char * nodename, const char * servname,
315: const struct addrinfo * hints,
316: struct addrinfo * * res)
317:
318: {
319: char * enodename;
320: char * eservname;
321: int status;
322: int i;
323:
324: enodename = (char *) NULL;
325: eservname = (char *) NULL;
326:
327: if(nodename) {
328: i = strlen(nodename);
329:
330: enodename = malloc(i + 1);
331: if(!enodename)
332: return EAI_MEMORY;
333:
334: i = QadrtConvertA2E(enodename, nodename, i, i);
335: enodename[i] = '\0';
336: }
337:
338: if(servname) {
339: i = strlen(servname);
340:
341: eservname = malloc(i + 1);
342: if(!eservname) {
343: free(enodename);
344: return EAI_MEMORY;
345: }
346:
347: QadrtConvertA2E(eservname, servname, i, i);
348: eservname[i] = '\0';
349: }
350:
351: status = getaddrinfo(enodename, eservname, hints, res);
352: free(enodename);
353: free(eservname);
354: return status;
355: }
356:
357:
358: #ifdef USE_GSKIT
359:
360: /* ASCII wrappers for the GSKit procedures. */
361:
362: /*
363: * EBCDIC --> ASCII string mapping table.
364: * Some strings returned by GSKit are dynamically allocated and automatically
365: * released when closing the handle.
366: * To provide the same functionality, we use a "private" handle that
367: * holds the GSKit handle and a list of string mappings. This will allow
368: * avoid conversion of already converted strings and releasing them upon
369: * close time.
370: */
371:
372: struct gskstrlist {
373: struct gskstrlist * next;
374: const char * ebcdicstr;
375: const char * asciistr;
376: };
377:
378: struct Curl_gsk_descriptor {
379: gsk_handle h;
380: struct gskstrlist * strlist;
381: };
382:
383:
384: int
385: Curl_gsk_environment_open(gsk_handle * my_env_handle)
386:
387: {
388: struct Curl_gsk_descriptor * p;
389: int rc;
390:
391: if(!my_env_handle)
392: return GSK_OS400_ERROR_INVALID_POINTER;
393: p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
394: if(!p)
395: return GSK_INSUFFICIENT_STORAGE;
396: p->strlist = (struct gskstrlist *) NULL;
397: rc = gsk_environment_open(&p->h);
398: if(rc != GSK_OK)
399: free(p);
400: else
401: *my_env_handle = (gsk_handle) p;
402: return rc;
403: }
404:
405:
406: int
407: Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
408: gsk_handle * my_session_handle)
409:
410: {
411: struct Curl_gsk_descriptor * p;
412: gsk_handle h;
413: int rc;
414:
415: if(!my_env_handle)
416: return GSK_INVALID_HANDLE;
417: if(!my_session_handle)
418: return GSK_OS400_ERROR_INVALID_POINTER;
419: h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
420: p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
421: if(!p)
422: return GSK_INSUFFICIENT_STORAGE;
423: p->strlist = (struct gskstrlist *) NULL;
424: rc = gsk_secure_soc_open(h, &p->h);
425: if(rc != GSK_OK)
426: free(p);
427: else
428: *my_session_handle = (gsk_handle) p;
429: return rc;
430: }
431:
432:
433: static void
434: gsk_free_handle(struct Curl_gsk_descriptor * p)
435:
436: {
437: struct gskstrlist * q;
438:
439: while((q = p->strlist)) {
440: p->strlist = q;
441: free((void *) q->asciistr);
442: free(q);
443: }
444: free(p);
445: }
446:
447:
448: int
449: Curl_gsk_environment_close(gsk_handle * my_env_handle)
450:
451: {
452: struct Curl_gsk_descriptor * p;
453: int rc;
454:
455: if(!my_env_handle)
456: return GSK_OS400_ERROR_INVALID_POINTER;
457: if(!*my_env_handle)
458: return GSK_INVALID_HANDLE;
459: p = (struct Curl_gsk_descriptor *) *my_env_handle;
460: rc = gsk_environment_close(&p->h);
461: if(rc == GSK_OK) {
462: gsk_free_handle(p);
463: *my_env_handle = (gsk_handle) NULL;
464: }
465: return rc;
466: }
467:
468:
469: int
470: Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
471:
472: {
473: struct Curl_gsk_descriptor * p;
474: int rc;
475:
476: if(!my_session_handle)
477: return GSK_OS400_ERROR_INVALID_POINTER;
478: if(!*my_session_handle)
479: return GSK_INVALID_HANDLE;
480: p = (struct Curl_gsk_descriptor *) *my_session_handle;
481: rc = gsk_secure_soc_close(&p->h);
482: if(rc == GSK_OK) {
483: gsk_free_handle(p);
484: *my_session_handle = (gsk_handle) NULL;
485: }
486: return rc;
487: }
488:
489:
490: int
491: Curl_gsk_environment_init(gsk_handle my_env_handle)
492:
493: {
494: struct Curl_gsk_descriptor * p;
495:
496: if(!my_env_handle)
497: return GSK_INVALID_HANDLE;
498: p = (struct Curl_gsk_descriptor *) my_env_handle;
499: return gsk_environment_init(p->h);
500: }
501:
502:
503: int
504: Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
505:
506: {
507: struct Curl_gsk_descriptor * p;
508:
509: if(!my_session_handle)
510: return GSK_INVALID_HANDLE;
511: p = (struct Curl_gsk_descriptor *) my_session_handle;
512: return gsk_secure_soc_init(p->h);
513: }
514:
515:
516: int
517: Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
518: const char * buffer, int bufSize)
519:
520: {
521: struct Curl_gsk_descriptor * p;
522: char * ebcdicbuf;
523: int rc;
524:
525: if(!my_gsk_handle)
526: return GSK_INVALID_HANDLE;
527: if(!buffer)
528: return GSK_OS400_ERROR_INVALID_POINTER;
529: if(bufSize < 0)
530: return GSK_ATTRIBUTE_INVALID_LENGTH;
531: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
532: if(!bufSize)
533: bufSize = strlen(buffer);
534: ebcdicbuf = malloc(bufSize + 1);
535: if(!ebcdicbuf)
536: return GSK_INSUFFICIENT_STORAGE;
537: QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
538: ebcdicbuf[bufSize] = '\0';
539: rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
540: free(ebcdicbuf);
541: return rc;
542: }
543:
544:
545: int
546: Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
547: GSK_ENUM_VALUE enumValue)
548:
549: {
550: struct Curl_gsk_descriptor * p;
551:
552: if(!my_gsk_handle)
553: return GSK_INVALID_HANDLE;
554: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
555: return gsk_attribute_set_enum(p->h, enumID, enumValue);
556: }
557:
558:
559: int
560: Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
561: GSK_NUM_ID numID, int numValue)
562:
563: {
564: struct Curl_gsk_descriptor * p;
565:
566: if(!my_gsk_handle)
567: return GSK_INVALID_HANDLE;
568: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
569: return gsk_attribute_set_numeric_value(p->h, numID, numValue);
570: }
571:
572:
573: int
574: Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
575: GSK_CALLBACK_ID callBackID,
576: void * callBackAreaPtr)
577:
578: {
579: struct Curl_gsk_descriptor * p;
580:
581: if(!my_gsk_handle)
582: return GSK_INVALID_HANDLE;
583: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
584: return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
585: }
586:
587:
588: static int
589: cachestring(struct Curl_gsk_descriptor * p,
590: const char * ebcdicbuf, int bufsize, const char * * buffer)
591:
592: {
593: int rc;
594: char * asciibuf;
595: struct gskstrlist * sp;
596:
597: for(sp = p->strlist; sp; sp = sp->next)
598: if(sp->ebcdicstr == ebcdicbuf)
599: break;
600: if(!sp) {
601: sp = (struct gskstrlist *) malloc(sizeof(*sp));
602: if(!sp)
603: return GSK_INSUFFICIENT_STORAGE;
604: asciibuf = malloc(bufsize + 1);
605: if(!asciibuf) {
606: free(sp);
607: return GSK_INSUFFICIENT_STORAGE;
608: }
609: QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
610: asciibuf[bufsize] = '\0';
611: sp->ebcdicstr = ebcdicbuf;
612: sp->asciistr = asciibuf;
613: sp->next = p->strlist;
614: p->strlist = sp;
615: }
616: *buffer = sp->asciistr;
617: return GSK_OK;
618: }
619:
620:
621: int
622: Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
623: const char * * buffer, int * bufSize)
624:
625: {
626: struct Curl_gsk_descriptor * p;
627: int rc;
628: const char * mybuf;
629: int mylen;
630:
631: if(!my_gsk_handle)
632: return GSK_INVALID_HANDLE;
633: if(!buffer || !bufSize)
634: return GSK_OS400_ERROR_INVALID_POINTER;
635: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
636: rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen);
637: if(rc != GSK_OK)
638: return rc;
639: rc = cachestring(p, mybuf, mylen, buffer);
640: if(rc == GSK_OK)
641: *bufSize = mylen;
642: return rc;
643: }
644:
645:
646: int
647: Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
648: GSK_ENUM_VALUE * enumValue)
649:
650: {
651: struct Curl_gsk_descriptor * p;
652:
653: if(!my_gsk_handle)
654: return GSK_INVALID_HANDLE;
655: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
656: return gsk_attribute_get_enum(p->h, enumID, enumValue);
657: }
658:
659:
660: int
661: Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
662: GSK_NUM_ID numID, int * numValue)
663:
664: {
665: struct Curl_gsk_descriptor * p;
666:
667: if(!my_gsk_handle)
668: return GSK_INVALID_HANDLE;
669: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
670: return gsk_attribute_get_numeric_value(p->h, numID, numValue);
671: }
672:
673:
674: int
675: Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
676: GSK_CERT_ID certID,
677: const gsk_cert_data_elem * * certDataElem,
678: int * certDataElementCount)
679:
680: {
681: struct Curl_gsk_descriptor * p;
682:
683: if(!my_gsk_handle)
684: return GSK_INVALID_HANDLE;
685: p = (struct Curl_gsk_descriptor *) my_gsk_handle;
686: /* No need to convert code: text results are already in ASCII. */
687: return gsk_attribute_get_cert_info(p->h, certID,
688: certDataElem, certDataElementCount);
689: }
690:
691:
692: int
693: Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
694:
695: {
696: struct Curl_gsk_descriptor * p;
697:
698: if(!my_session_handle)
699: return GSK_INVALID_HANDLE;
700: p = (struct Curl_gsk_descriptor *) my_session_handle;
701: return gsk_secure_soc_misc(p->h, miscID);
702: }
703:
704:
705: int
706: Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
707: int readBufSize, int * amtRead)
708:
709: {
710: struct Curl_gsk_descriptor * p;
711:
712: if(!my_session_handle)
713: return GSK_INVALID_HANDLE;
714: p = (struct Curl_gsk_descriptor *) my_session_handle;
715: return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
716: }
717:
718:
719: int
720: Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
721: int writeBufSize, int * amtWritten)
722:
723: {
724: struct Curl_gsk_descriptor * p;
725:
726: if(!my_session_handle)
727: return GSK_INVALID_HANDLE;
728: p = (struct Curl_gsk_descriptor *) my_session_handle;
729: return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
730: }
731:
732:
733: const char *
734: Curl_gsk_strerror_a(int gsk_return_value)
735:
736: {
737: return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
738: }
739:
740: int
741: Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
742: int IOCompletionPort,
743: Qso_OverlappedIO_t * communicationsArea)
744:
745: {
746: struct Curl_gsk_descriptor * p;
747:
748: if(!my_session_handle)
749: return GSK_INVALID_HANDLE;
750: p = (struct Curl_gsk_descriptor *) my_session_handle;
751: return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
752: }
753:
754: #endif /* USE_GSKIT */
755:
756:
757:
758: #ifdef HAVE_GSSAPI
759:
760: /* ASCII wrappers for the GSSAPI procedures. */
761:
762: static int
763: Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
764:
765: {
766: unsigned int i = buf->length;
767:
768: /* Convert `buf' in place, from EBCDIC to ASCII.
769: If error, release the buffer and return -1. Else return 0. */
770:
771: if(i) {
772: char *t = malloc(i);
773: if(!t) {
774: gss_release_buffer(minor_status, buf);
775:
776: if(minor_status)
777: *minor_status = ENOMEM;
778:
779: return -1;
780: }
781:
782: QadrtConvertE2A(t, buf->value, i, i);
783: memcpy(buf->value, t, i);
784: free(t);
785: }
786:
787: return 0;
788: }
789:
790:
791: OM_uint32
792: Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
793: gss_OID in_name_type, gss_name_t * out_name)
794:
795: {
796: int rc;
797: unsigned int i;
798: gss_buffer_desc in;
799:
800: if(!in_name || !in_name->value || !in_name->length)
801: return gss_import_name(minor_status, in_name, in_name_type, out_name);
802:
803: memcpy((char *) &in, (char *) in_name, sizeof(in));
804: i = in.length;
805:
806: in.value = malloc(i + 1);
807: if(!in.value) {
808: if(minor_status)
809: *minor_status = ENOMEM;
810:
811: return GSS_S_FAILURE;
812: }
813:
814: QadrtConvertA2E(in.value, in_name->value, i, i);
815: ((char *) in.value)[i] = '\0';
816: rc = gss_import_name(minor_status, &in, in_name_type, out_name);
817: free(in.value);
818: return rc;
819: }
820:
821:
822: OM_uint32
823: Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
824: int status_type, gss_OID mech_type,
825: gss_msg_ctx_t * message_context, gss_buffer_t status_string)
826:
827: {
828: int rc;
829:
830: rc = gss_display_status(minor_status, status_value, status_type,
831: mech_type, message_context, status_string);
832:
833: if(rc != GSS_S_COMPLETE || !status_string ||
834: !status_string->length || !status_string->value)
835: return rc;
836:
837: /* No way to allocate a buffer here, because it will be released by
838: gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
839: with ASCII to return it. */
840:
841: if(Curl_gss_convert_in_place(minor_status, status_string))
842: return GSS_S_FAILURE;
843:
844: return rc;
845: }
846:
847:
848: OM_uint32
849: Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
850: gss_cred_id_t cred_handle,
851: gss_ctx_id_t * context_handle,
852: gss_name_t target_name, gss_OID mech_type,
853: gss_flags_t req_flags, OM_uint32 time_req,
854: gss_channel_bindings_t input_chan_bindings,
855: gss_buffer_t input_token,
856: gss_OID * actual_mech_type,
857: gss_buffer_t output_token, gss_flags_t * ret_flags,
858: OM_uint32 * time_rec)
859:
860: {
861: int rc;
862: gss_buffer_desc in;
863: gss_buffer_t inp;
864:
865: in.value = NULL;
866: inp = input_token;
867:
868: if(inp) {
869: if(inp->length && inp->value) {
870: unsigned int i = inp->length;
871:
872: in.value = malloc(i + 1);
873: if(!in.value) {
874: if(minor_status)
875: *minor_status = ENOMEM;
876:
877: return GSS_S_FAILURE;
878: }
879:
880: QadrtConvertA2E(in.value, input_token->value, i, i);
881: ((char *) in.value)[i] = '\0';
882: in.length = i;
883: inp = ∈
884: }
885: }
886:
887: rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
888: target_name, mech_type, req_flags, time_req,
889: input_chan_bindings, inp, actual_mech_type,
890: output_token, ret_flags, time_rec);
891: free(in.value);
892:
893: if(rc != GSS_S_COMPLETE || !output_token ||
894: !output_token->length || !output_token->value)
895: return rc;
896:
897: /* No way to allocate a buffer here, because it will be released by
898: gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
899: with ASCII to return it. */
900:
901: if(Curl_gss_convert_in_place(minor_status, output_token))
902: return GSS_S_FAILURE;
903:
904: return rc;
905: }
906:
907:
908: OM_uint32
909: Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
910: gss_ctx_id_t * context_handle,
911: gss_buffer_t output_token)
912:
913: {
914: int rc;
915:
916: rc = gss_delete_sec_context(minor_status, context_handle, output_token);
917:
918: if(rc != GSS_S_COMPLETE || !output_token ||
919: !output_token->length || !output_token->value)
920: return rc;
921:
922: /* No way to allocate a buffer here, because it will be released by
923: gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
924: with ASCII to return it. */
925:
926: if(Curl_gss_convert_in_place(minor_status, output_token))
927: return GSS_S_FAILURE;
928:
929: return rc;
930: }
931:
932: #endif /* HAVE_GSSAPI */
933:
934:
935: #ifndef CURL_DISABLE_LDAP
936:
937: /* ASCII wrappers for the LDAP procedures. */
938:
939: void *
940: Curl_ldap_init_a(char * host, int port)
941:
942: {
943: unsigned int i;
944: char * ehost;
945: void * result;
946:
947: if(!host)
948: return (void *) ldap_init(host, port);
949:
950: i = strlen(host);
951:
952: ehost = malloc(i + 1);
953: if(!ehost)
954: return (void *) NULL;
955:
956: QadrtConvertA2E(ehost, host, i, i);
957: ehost[i] = '\0';
958: result = (void *) ldap_init(ehost, port);
959: free(ehost);
960: return result;
961: }
962:
963:
964: int
965: Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
966:
967: {
968: int i;
969: char * edn;
970: char * epasswd;
971:
972: edn = (char *) NULL;
973: epasswd = (char *) NULL;
974:
975: if(dn) {
976: i = strlen(dn);
977:
978: edn = malloc(i + 1);
979: if(!edn)
980: return LDAP_NO_MEMORY;
981:
982: QadrtConvertA2E(edn, dn, i, i);
983: edn[i] = '\0';
984: }
985:
986: if(passwd) {
987: i = strlen(passwd);
988:
989: epasswd = malloc(i + 1);
990: if(!epasswd) {
991: free(edn);
992: return LDAP_NO_MEMORY;
993: }
994:
995: QadrtConvertA2E(epasswd, passwd, i, i);
996: epasswd[i] = '\0';
997: }
998:
999: i = ldap_simple_bind_s(ld, edn, epasswd);
1000: free(epasswd);
1001: free(edn);
1002: return i;
1003: }
1004:
1005:
1006: int
1007: Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
1008: char * * attrs, int attrsonly, LDAPMessage * * res)
1009:
1010: {
1011: int i;
1012: int j;
1013: char * ebase;
1014: char * efilter;
1015: char * * eattrs;
1016: int status;
1017:
1018: ebase = (char *) NULL;
1019: efilter = (char *) NULL;
1020: eattrs = (char * *) NULL;
1021: status = LDAP_SUCCESS;
1022:
1023: if(base) {
1024: i = strlen(base);
1025:
1026: ebase = malloc(i + 1);
1027: if(!ebase)
1028: status = LDAP_NO_MEMORY;
1029: else {
1030: QadrtConvertA2E(ebase, base, i, i);
1031: ebase[i] = '\0';
1032: }
1033: }
1034:
1035: if(filter && status == LDAP_SUCCESS) {
1036: i = strlen(filter);
1037:
1038: efilter = malloc(i + 1);
1039: if(!efilter)
1040: status = LDAP_NO_MEMORY;
1041: else {
1042: QadrtConvertA2E(efilter, filter, i, i);
1043: efilter[i] = '\0';
1044: }
1045: }
1046:
1047: if(attrs && status == LDAP_SUCCESS) {
1048: for(i = 0; attrs[i++];)
1049: ;
1050:
1051: eattrs = calloc(i, sizeof(*eattrs));
1052: if(!eattrs)
1053: status = LDAP_NO_MEMORY;
1054: else {
1055: for(j = 0; attrs[j]; j++) {
1056: i = strlen(attrs[j]);
1057:
1058: eattrs[j] = malloc(i + 1);
1059: if(!eattrs[j]) {
1060: status = LDAP_NO_MEMORY;
1061: break;
1062: }
1063:
1064: QadrtConvertA2E(eattrs[j], attrs[j], i, i);
1065: eattrs[j][i] = '\0';
1066: }
1067: }
1068: }
1069:
1070: if(status == LDAP_SUCCESS)
1071: status = ldap_search_s(ld, ebase? ebase: "", scope,
1072: efilter? efilter: "(objectclass=*)",
1073: eattrs, attrsonly, res);
1074:
1075: if(eattrs) {
1076: for(j = 0; eattrs[j]; j++)
1077: free(eattrs[j]);
1078:
1079: free(eattrs);
1080: }
1081:
1082: free(efilter);
1083: free(ebase);
1084: return status;
1085: }
1086:
1087:
1088: struct berval * *
1089: Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
1090:
1091: {
1092: char * cp;
1093: struct berval * * result;
1094:
1095: cp = (char *) NULL;
1096:
1097: if(attr) {
1098: int i = strlen(attr);
1099:
1100: cp = malloc(i + 1);
1101: if(!cp) {
1102: ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
1103: ldap_err2string(LDAP_NO_MEMORY));
1104: return (struct berval * *) NULL;
1105: }
1106:
1107: QadrtConvertA2E(cp, attr, i, i);
1108: cp[i] = '\0';
1109: }
1110:
1111: result = ldap_get_values_len(ld, entry, cp);
1112: free(cp);
1113:
1114: /* Result data are binary in nature, so they haven't been
1115: converted to EBCDIC. Therefore do not convert. */
1116:
1117: return result;
1118: }
1119:
1120:
1121: char *
1122: Curl_ldap_err2string_a(int error)
1123:
1124: {
1125: return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
1126: }
1127:
1128:
1129: char *
1130: Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
1131:
1132: {
1133: int i;
1134: char * cp;
1135: char * cp2;
1136:
1137: cp = ldap_get_dn(ld, entry);
1138:
1139: if(!cp)
1140: return cp;
1141:
1142: i = strlen(cp);
1143:
1144: cp2 = malloc(i + 1);
1145: if(!cp2)
1146: return cp2;
1147:
1148: QadrtConvertE2A(cp2, cp, i, i);
1149: cp2[i] = '\0';
1150:
1151: /* No way to allocate a buffer here, because it will be released by
1152: ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1153: overwrite the EBCDIC buffer with ASCII to return it. */
1154:
1155: strcpy(cp, cp2);
1156: free(cp2);
1157: return cp;
1158: }
1159:
1160:
1161: char *
1162: Curl_ldap_first_attribute_a(void * ld,
1163: LDAPMessage * entry, BerElement * * berptr)
1164:
1165: {
1166: int i;
1167: char * cp;
1168: char * cp2;
1169:
1170: cp = ldap_first_attribute(ld, entry, berptr);
1171:
1172: if(!cp)
1173: return cp;
1174:
1175: i = strlen(cp);
1176:
1177: cp2 = malloc(i + 1);
1178: if(!cp2)
1179: return cp2;
1180:
1181: QadrtConvertE2A(cp2, cp, i, i);
1182: cp2[i] = '\0';
1183:
1184: /* No way to allocate a buffer here, because it will be released by
1185: ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1186: overwrite the EBCDIC buffer with ASCII to return it. */
1187:
1188: strcpy(cp, cp2);
1189: free(cp2);
1190: return cp;
1191: }
1192:
1193:
1194: char *
1195: Curl_ldap_next_attribute_a(void * ld,
1196: LDAPMessage * entry, BerElement * berptr)
1197:
1198: {
1199: int i;
1200: char * cp;
1201: char * cp2;
1202:
1203: cp = ldap_next_attribute(ld, entry, berptr);
1204:
1205: if(!cp)
1206: return cp;
1207:
1208: i = strlen(cp);
1209:
1210: cp2 = malloc(i + 1);
1211: if(!cp2)
1212: return cp2;
1213:
1214: QadrtConvertE2A(cp2, cp, i, i);
1215: cp2[i] = '\0';
1216:
1217: /* No way to allocate a buffer here, because it will be released by
1218: ldap_memfree() and ldap_memalloc() does not exist. The solution is to
1219: overwrite the EBCDIC buffer with ASCII to return it. */
1220:
1221: strcpy(cp, cp2);
1222: free(cp2);
1223: return cp;
1224: }
1225:
1226: #endif /* CURL_DISABLE_LDAP */
1227:
1228:
1229: static int
1230: sockaddr2ebcdic(struct sockaddr_storage *dstaddr,
1231: const struct sockaddr *srcaddr, int srclen)
1232: {
1233: const struct sockaddr_un *srcu;
1234: struct sockaddr_un *dstu;
1235: unsigned int i;
1236: unsigned int dstsize;
1237:
1238: /* Convert a socket address to job CCSID, if needed. */
1239:
1240: if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
1241: sizeof(srcaddr->sa_family) || srclen > sizeof(*dstaddr)) {
1242: errno = EINVAL;
1243: return -1;
1244: }
1245:
1246: memcpy((char *) dstaddr, (char *) srcaddr, srclen);
1247:
1248: switch (srcaddr->sa_family) {
1249:
1250: case AF_UNIX:
1251: srcu = (const struct sockaddr_un *) srcaddr;
1252: dstu = (struct sockaddr_un *) dstaddr;
1253: dstsize = sizeof(*dstaddr) - offsetof(struct sockaddr_un, sun_path);
1254: srclen -= offsetof(struct sockaddr_un, sun_path);
1255: i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
1256: dstu->sun_path[i] = '\0';
1257: srclen = i + offsetof(struct sockaddr_un, sun_path);
1258: }
1259:
1260: return srclen;
1261: }
1262:
1263:
1264: static int
1265: sockaddr2ascii(struct sockaddr *dstaddr, int dstlen,
1266: const struct sockaddr_storage *srcaddr, int srclen)
1267: {
1268: const struct sockaddr_un *srcu;
1269: struct sockaddr_un *dstu;
1270: unsigned int dstsize;
1271:
1272: /* Convert a socket address to ASCII, if needed. */
1273:
1274: if(!srclen)
1275: return 0;
1276: if(srclen > dstlen)
1277: srclen = dstlen;
1278: if(!srcaddr || srclen < 0) {
1279: errno = EINVAL;
1280: return -1;
1281: }
1282:
1283: memcpy((char *) dstaddr, (char *) srcaddr, srclen);
1284:
1285: if(srclen >= offsetof(struct sockaddr_storage, ss_family) +
1286: sizeof(srcaddr->ss_family)) {
1287: switch (srcaddr->ss_family) {
1288:
1289: case AF_UNIX:
1290: srcu = (const struct sockaddr_un *) srcaddr;
1291: dstu = (struct sockaddr_un *) dstaddr;
1292: dstsize = dstlen - offsetof(struct sockaddr_un, sun_path);
1293: srclen -= offsetof(struct sockaddr_un, sun_path);
1294: if(dstsize > 0 && srclen > 0) {
1295: srclen = QadrtConvertE2A(dstu->sun_path, srcu->sun_path,
1296: dstsize - 1, srclen);
1297: dstu->sun_path[srclen] = '\0';
1298: }
1299: srclen += offsetof(struct sockaddr_un, sun_path);
1300: }
1301: }
1302:
1303: return srclen;
1304: }
1305:
1306:
1307: int
1308: Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
1309: {
1310: int i;
1311: struct sockaddr_storage laddr;
1312:
1313: i = sockaddr2ebcdic(&laddr, destaddr, addrlen);
1314:
1315: if(i < 0)
1316: return -1;
1317:
1318: return connect(sd, (struct sockaddr *) &laddr, i);
1319: }
1320:
1321:
1322: int
1323: Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
1324: {
1325: int i;
1326: struct sockaddr_storage laddr;
1327:
1328: i = sockaddr2ebcdic(&laddr, localaddr, addrlen);
1329:
1330: if(i < 0)
1331: return -1;
1332:
1333: return bind(sd, (struct sockaddr *) &laddr, i);
1334: }
1335:
1336:
1337: int
1338: Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
1339: struct sockaddr * dstaddr, int addrlen)
1340: {
1341: int i;
1342: struct sockaddr_storage laddr;
1343:
1344: i = sockaddr2ebcdic(&laddr, dstaddr, addrlen);
1345:
1346: if(i < 0)
1347: return -1;
1348:
1349: return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
1350: }
1351:
1352:
1353: int
1354: Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
1355: struct sockaddr * fromaddr, int * addrlen)
1356: {
1357: int rcvlen;
1358: struct sockaddr_storage laddr;
1359: int laddrlen = sizeof(laddr);
1360:
1361: if(!fromaddr || !addrlen || *addrlen <= 0)
1362: return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
1363:
1364: laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
1365: rcvlen = recvfrom(sd, buffer, buflen, flags,
1366: (struct sockaddr *) &laddr, &laddrlen);
1367:
1368: if(rcvlen < 0)
1369: return rcvlen;
1370:
1371: if(laddr.ss_family == AF_UNSPEC)
1372: laddrlen = 0;
1373: else {
1374: laddrlen = sockaddr2ascii(fromaddr, *addrlen, &laddr, laddrlen);
1375: if(laddrlen < 0)
1376: return laddrlen;
1377: }
1378: *addrlen = laddrlen;
1379: return rcvlen;
1380: }
1381:
1382:
1383: int
1384: Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen)
1385: {
1386: struct sockaddr_storage laddr;
1387: int laddrlen = sizeof(laddr);
1388: int retcode = getpeername(sd, (struct sockaddr *) &laddr, &laddrlen);
1389:
1390: if(!retcode) {
1391: laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
1392: if(laddrlen < 0)
1393: return laddrlen;
1394: *addrlen = laddrlen;
1395: }
1396:
1397: return retcode;
1398: }
1399:
1400:
1401: int
1402: Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen)
1403: {
1404: struct sockaddr_storage laddr;
1405: int laddrlen = sizeof(laddr);
1406: int retcode = getsockname(sd, (struct sockaddr *) &laddr, &laddrlen);
1407:
1408: if(!retcode) {
1409: laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
1410: if(laddrlen < 0)
1411: return laddrlen;
1412: *addrlen = laddrlen;
1413: }
1414:
1415: return retcode;
1416: }
1417:
1418:
1419: #ifdef HAVE_LIBZ
1420: const char *
1421: Curl_os400_zlibVersion(void)
1422:
1423: {
1424: return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
1425: }
1426:
1427:
1428: int
1429: Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
1430:
1431: {
1432: z_const char * msgb4 = strm->msg;
1433: int ret;
1434:
1435: ret = inflateInit(strm);
1436:
1437: if(strm->msg != msgb4)
1438: strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1439:
1440: return ret;
1441: }
1442:
1443:
1444: int
1445: Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
1446: const char * version, int stream_size)
1447:
1448: {
1449: z_const char * msgb4 = strm->msg;
1450: int ret;
1451:
1452: ret = inflateInit2(strm, windowBits);
1453:
1454: if(strm->msg != msgb4)
1455: strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1456:
1457: return ret;
1458: }
1459:
1460:
1461: int
1462: Curl_os400_inflate(z_streamp strm, int flush)
1463:
1464: {
1465: z_const char * msgb4 = strm->msg;
1466: int ret;
1467:
1468: ret = inflate(strm, flush);
1469:
1470: if(strm->msg != msgb4)
1471: strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1472:
1473: return ret;
1474: }
1475:
1476:
1477: int
1478: Curl_os400_inflateEnd(z_streamp strm)
1479:
1480: {
1481: z_const char * msgb4 = strm->msg;
1482: int ret;
1483:
1484: ret = inflateEnd(strm);
1485:
1486: if(strm->msg != msgb4)
1487: strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
1488:
1489: return ret;
1490: }
1491:
1492: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>