90 # pragma comment(lib, "winsock.lib")
92 # pragma comment(lib, "wsock32.lib")
94 # pragma warning(disable : 4996)
107 #ifndef SOAP_UNKNOWN_CHAR
108 #define SOAP_UNKNOWN_CHAR (127)
112 #define SOAP_LT (soap_wchar)(-2)
113 #define SOAP_TT (soap_wchar)(-3)
114 #define SOAP_GT (soap_wchar)(-4)
115 #define SOAP_QT (soap_wchar)(-5)
116 #define SOAP_AP (soap_wchar)(-6)
118 #define soap_blank(c) ((c) >= 0 && (c) <= 32)
119 #define soap_notblank(c) ((c) > 32)
121 #if defined(WIN32) && !defined(UNDER_CE)
122 #define soap_hash_ptr(p) ((PtrToUlong(p) >> 3) & (SOAP_PTRHASH - 1))
124 #define soap_hash_ptr(p) ((size_t)(((unsigned long)(p) >> 3) & (SOAP_PTRHASH-1)))
131 static void soap_close_logfile(
struct soap*,
int);
132 static void soap_set_logfile(
struct soap*,
int,
const char*);
135 #ifdef SOAP_MEM_DEBUG
136 static void soap_init_mht(
struct soap*);
137 static void soap_free_mht(
struct soap*);
138 static void soap_track_unlink(
struct soap*,
const void*);
142 static int soap_set_error(
struct soap*,
const char*,
const char*,
const char*,
const char*,
int);
143 static int soap_copy_fault(
struct soap*,
const char*,
const char*,
const char*,
const char*);
152 static void *
fplugin(
struct soap*,
const char*);
171 static void soap_utilize_ns(
struct soap *soap,
const char *tag,
size_t n);
186 static int soap_getgziphdr(
struct soap*);
190 int soap_ssl_init_done = 0;
192 static int ssl_auth_init(
struct soap*);
193 static int ssl_verify_callback(
int, X509_STORE_CTX*);
194 static int ssl_verify_callback_allow_expired_certificate(
int, X509_STORE_CTX*);
195 static int ssl_password(
char*,
int,
int,
void *);
201 #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
203 static const char *
soap_decode(
char*,
size_t,
const char*,
const char*);
210 static const char *
http_error(
struct soap*,
int);
211 static int http_post(
struct soap*,
const char*,
const char*,
int,
const char*,
const char*,
size_t);
227 static int fsend(
struct soap*,
const char*,
size_t);
228 static size_t frecv(
struct soap*,
char*,
size_t);
230 static const char *
tcp_error(
struct soap*);
232 static int tcp_gethost(
struct soap*,
const char *addr,
struct in_addr *inaddr);
243 #define SOAP_SOCKBLOCK(fd) \
244 {u_long blocking = 0; \
245 ioctlsocket(fd, FIONBIO, &blocking); \
247 #define SOAP_SOCKNONBLOCK(fd) \
248 {u_long nonblocking = 1; \
249 ioctlsocket(fd, FIONBIO, &nonblocking); \
251 #elif defined(VXWORKS)
252 #define SOAP_SOCKBLOCK(fd) \
253 {u_long blocking = 0; \
254 ioctl(fd, FIONBIO, (int)(&blocking)); \
256 #define SOAP_SOCKNONBLOCK(fd) \
257 {u_long nonblocking = 1; \
258 ioctl(fd, FIONBIO, (int)(&nonblocking)); \
261 #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)&~O_NONBLOCK);
262 #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK);
263 #elif defined(SYMBIAN)
264 #define SOAP_SOCKBLOCK(fd) \
265 {long blocking = 0; \
266 ioctl(fd, 0, &blocking); \
268 #define SOAP_SOCKNONBLOCK(fd) \
269 {long nonblocking = 1; \
270 ioctl(fd, 0, &nonblocking); \
273 #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK);
274 #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
279 #if defined(PALM) && !defined(PALM_2)
280 unsigned short errno;
284 static const char soap_env1[42] =
"http://schemas.xmlsoap.org/soap/envelope/";
285 static const char soap_enc1[42] =
"http://schemas.xmlsoap.org/soap/encoding/";
286 static const char soap_env2[40] =
"http://www.w3.org/2003/05/soap-envelope";
287 static const char soap_enc2[40] =
"http://www.w3.org/2003/05/soap-encoding";
288 static const char soap_rpc[35] =
"http://www.w3.org/2003/05/soap-rpc";
292 const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF};
293 static const char soap_base64o[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
294 static const char soap_base64i[81] =
"\76XXX\77\64\65\66\67\70\71\72\73\74\75XXXXXXX\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31XXXXXX\32\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61\62\63";
298 static const char soap_indent[11] =
"\n\t\t\t\t\t\t\t\t\t";
305 # define SOAP_CANARY (0xC0DE)
308 static const char soap_padding[4] =
"\0\0\0";
309 #define SOAP_STR_PADDING (soap_padding)
310 #define SOAP_STR_EOS (soap_padding)
311 #define SOAP_NON_NULL (soap_padding)
419 #ifdef HOST_NOT_FOUND
420 {HOST_NOT_FOUND,
"Host not found" },
423 {TRY_AGAIN,
"Try Again" },
426 {NO_RECOVERY,
"No Recovery" },
429 {NO_DATA,
"No Data" },
432 {NO_ADDRESS,
"No Address" },
445 {203,
"Non-Authoritative Information" },
446 {204,
"No Content" },
447 {205,
"Reset Content" },
448 {206,
"Partial Content" },
449 {300,
"Multiple Choices" },
450 {301,
"Moved Permanently" },
453 {304,
"Not Modified" },
455 {307,
"Temporary Redirect" },
456 {400,
"Bad Request" },
457 {401,
"Unauthorized" },
458 {402,
"Payment Required" },
461 {405,
"Method Not Allowed" },
462 {406,
"Not Acceptable" },
463 {407,
"Proxy Authentication Required" },
464 {408,
"Request Time-out" },
467 {411,
"Length Required" },
468 {412,
"Precondition Failed" },
469 {413,
"Request Entity Too Large" },
470 {414,
"Request-URI Too Large" },
471 {415,
"Unsupported Media Type" },
472 {416,
"Requested range not satisfiable" },
473 {417,
"Expectation Failed" },
474 {500,
"Internal Server Error" },
475 {501,
"Not Implemented" },
476 {502,
"Bad Gateway" },
477 {503,
"Service Unavailable" },
478 {504,
"Gateway Time-out" },
479 {505,
"HTTP Version not supported" },
488 #define _SSL_ERROR(e) {e, #e}
490 _SSL_ERROR(SSL_ERROR_SSL),
491 _SSL_ERROR(SSL_ERROR_ZERO_RETURN),
492 _SSL_ERROR(SSL_ERROR_WANT_READ),
493 _SSL_ERROR(SSL_ERROR_WANT_WRITE),
494 _SSL_ERROR(SSL_ERROR_WANT_CONNECT),
495 _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP),
496 _SSL_ERROR(SSL_ERROR_SYSCALL),
515 static int tcp_done = 0;
518 #if defined(HP_UX) && defined(HAVE_GETHOSTBYNAME_R)
526 fsend(
struct soap *soap,
const char *s,
size_t n)
528 register int nwritten, err;
529 #if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT)
533 soap->
os->write(s, (std::streamsize)n);
535 if (soap->
os->good())
554 if ((
int)soap->
socket >= (int)FD_SETSIZE)
561 struct timeval timeout;
577 FD_SET(soap->
socket, &fd);
581 r = select((
int)soap->
socket + 1, &fd, &fd, &fd, &timeout);
584 r = select((
int)soap->
socket + 1, NULL, &fd, &fd, &timeout);
609 nwritten = SSL_write(soap->
ssl, s, (
int)n);
611 nwritten = BIO_write(soap->
bio, s, (
int)n);
627 struct timeval timeout;
633 if ((
int)soap->
socket >= (
int)FD_SETSIZE)
648 timeout.tv_usec = 1000 * udp_delay;
650 FD_SET(soap->
socket, &fd);
651 select((
int)soap->
socket + 1, NULL, NULL, &fd, &timeout);
663 while (nwritten < 0 && --udp_repeat > 0);
668 #if !defined(PALM) && !defined(AS400)
677 #if defined(WITH_OPENSSL) || !defined(WITH_LEAN)
683 if (soap->
ssl && (r = SSL_get_error(soap->
ssl, nwritten)) != SSL_ERROR_NONE && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
694 struct timeval timeout;
698 if ((
int)soap->
socket >= (
int)FD_SETSIZE)
716 timeout.tv_usec = 10000;
720 FD_SET(soap->
socket, &fd);
723 if (soap->
ssl && r == SSL_ERROR_WANT_READ)
724 r = select((
int)soap->
socket + 1, &fd, NULL, &fd, &timeout);
726 r = select((
int)soap->
socket + 1, NULL, &fd, &fd, &timeout);
729 r = select((
int)soap->
socket + 1, NULL, &fd, &fd, &timeout);
758 nwritten = fwrite((
void*)s, 1, n, stdout);
762 nwritten = fwrite(s, 1, n, soap->
sendfd);
768 nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1;
771 nwritten = fwrite(s,
sizeof(
char), n, fdopen(soap->
sendfd,
"w"));
775 nwritten = _write(soap->
sendfd, s, (
unsigned int)n);
777 nwritten = write(soap->
sendfd, s, (
unsigned int)n);
865 register size_t n = soap->
bufidx;
875 soap->
d_stream->avail_in = (
unsigned int)n;
877 soap->
z_crc = crc32(soap->
z_crc, (Byte*)soap->
buf, (
unsigned int)n);
882 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Deflating %u bytes\n", soap->
d_stream->avail_in));
884 if (deflate(soap->
d_stream, Z_NO_FLUSH) != Z_OK)
939 sprintf(t,
"\r\n%lX\r\n" + (soap->
chunksize ? 0 : 2), (
unsigned long)n);
940 DBGMSG(SENT, t, strlen(t));
942 if ((soap->
error = soap->
fsend(soap, t, strlen(t))))
974 soap_send2(
struct soap *soap,
const char *s1,
const char *s2)
990 soap_send3(
struct soap *soap,
const char *s1,
const char *s2,
const char *s3)
1005 frecv(
struct soap *soap,
char *s,
size_t n)
1009 register int retries = 100;
1012 #if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT)
1016 if (soap->
is->good())
1017 return soap->
is->read(s, (std::streamsize)n).gcount();
1029 register int err = 0;
1041 if ((
int)soap->
socket >= (
int)FD_SETSIZE)
1051 struct timeval timeout;
1057 timeout.tv_usec = 0;
1066 FD_SET(soap->
socket, &fd);
1067 r = select((
int)soap->
socket + 1, &fd, NULL, &fd, &timeout);
1092 r = SSL_read(soap->
ssl, s, (
int)n);
1097 err = SSL_get_error(soap->
ssl, r);
1099 if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
1104 r = BIO_read(soap->
bio, s, (
int)n);
1120 memset((
void*)&soap->
peer, 0,
sizeof(soap->
peer));
1124 soap->
ip = ntohl(soap->
peer.sin_addr.s_addr);
1148 {
struct timeval timeout;
1154 timeout.tv_usec = 0;
1164 timeout.tv_usec = 0;
1169 if ((
int)soap->
socket >= (
int)FD_SETSIZE)
1177 FD_SET(soap->
socket, &fd);
1180 if (soap->
ssl && err == SSL_ERROR_WANT_WRITE)
1181 r = select((
int)soap->
socket + 1, NULL, &fd, &fd, &timeout);
1183 r = select((
int)soap->
socket + 1, &fd, NULL, &fd, &timeout);
1186 r = select((
int)soap->
socket + 1, &fd, NULL, &fd, &timeout);
1227 return fread(s, 1, n, stdin);
1230 return fread(s, 1, n, soap->
recvfd);
1235 r = httpBlockRead(soap->rpmreqid, s, n);
1239 r = _read(soap->
recvfd, s, (
unsigned int)n);
1242 r = read(soap->
recvfd, s, (
unsigned int)n);
1267 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Read %u bytes from socket %d\n", (
unsigned int)soap->
buflen, soap->
socket));
1283 return (c >=
'0' && c <=
'9') || (c >=
'A' && c <= 'F') || (c >=
'a' && c <=
'f');
1294 register size_t ret;
1299 if (soap->
d_stream->next_out == Z_NULL)
1305 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Inflating\n"));
1308 r = inflate(soap->
d_stream, Z_NO_FLUSH);
1310 if (r == Z_OK || r == Z_STREAM_END)
1316 soap->
z_crc = crc32(soap->
z_crc, (Byte*)soap->
buf, (
unsigned int)ret);
1318 if (r == Z_STREAM_END)
1320 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Inflated %lu->%lu bytes\n", soap->
d_stream->total_in, soap->
d_stream->total_out));
1328 DBGLOG(RECV, SOAP_MESSAGE(fdebug,
"\n---- decompressed ----\n"));
1330 DBGLOG(RECV, SOAP_MESSAGE(fdebug,
"\n----\n"));
1334 else if (r != Z_BUF_ERROR)
1351 DBGLOG(RECV, SOAP_MESSAGE(fdebug,
"\n---- compressed ----\n"));
1367 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Getting chunk: read %u bytes\n", (
unsigned int)ret));
1379 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Read %u bytes (chunked) from socket %d\n", (
unsigned int)ret, soap->
socket));
1384 return soap->
ahead = EOF;
1390 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Getting chunk size (idx=%u len=%u)\n", (
unsigned int)soap->
bufidx, (
unsigned int)soap->
buflen));
1395 return soap->
ahead = EOF;
1403 while ((
int)c != EOF && c !=
'\n')
1407 return soap->
ahead = EOF;
1410 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Chunk size = %s (hex)\n", tmp));
1416 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"End of chunked message\n"));
1418 while ((
int)c != EOF && c !=
'\n')
1427 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Moving buf len to idx=%u len=%u (%s)\n", (
unsigned int)soap->
bufidx, (
unsigned int)soap->
buflen, tmp));
1434 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Passed end of buffer for chunked HTTP (%u bytes left)\n", (
unsigned int)(soap->
buflen - soap->
bufidx)));
1451 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Read %u bytes from socket %d\n", (
unsigned int)ret, soap->
socket));
1468 soap->
d_stream->avail_in = (
unsigned int)ret;
1471 r = inflate(soap->
d_stream, Z_NO_FLUSH);
1473 if (r == Z_OK || r == Z_STREAM_END)
1482 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Inflated %u bytes\n", (
unsigned int)soap->
buflen));
1484 if (ret && !soap->
buflen)
1489 if (r == Z_STREAM_END)
1491 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Inflated total %lu->%lu bytes\n", soap->
d_stream->total_in, soap->
d_stream->total_out));
1496 DBGLOG(RECV, SOAP_MESSAGE(fdebug,
"\n---- decompressed ----\n"));
1529 unsigned char tmp[12];
1530 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"DIME hdr for chunked DIME is in buffer\n"));
1533 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Skip padding (%ld bytes)\n", -(
long)soap->
dime.
size&3));
1535 for (i = -(
long)soap->
dime.
size & 3; i > 0; i--)
1544 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Get DIME hdr for next chunk\n"));
1547 for (i = 12; i > 0; i--)
1557 soap->
dime.
size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]);
1558 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Get DIME chunk (%u bytes)\n", (
unsigned int)soap->
dime.
size));
1562 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"More chunking\n"));
1575 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Last chunk\n"));
1581 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"%u bytes remaining\n", (
unsigned int)soap->
count));
1587 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (
unsigned int)soap->
dime.
chunksize));
1601 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"%lu bytes remaining, count=%u\n", (
unsigned long)(soap->
buflen - soap->
bufidx), (
unsigned int)soap->
count));
1640 if (code_map && str)
1644 if (!strcmp(str, code_map->
string))
1667 return code_map->
code;
1687 while (code_map->
code != code && code_map->
string)
1701 register long bits = 0;
1709 for (p = code_map; p->
string; p++)
1711 register size_t n = strlen(p->
string);
1718 while (*str > 0 && *str <= 32)
1741 register char *t = soap->
tmpbuf;
1747 if (code_map->
code & code)
1749 register const char *s = code_map->
string;
1754 while (*s && t < soap->tmpbuf +
sizeof(soap->
tmpbuf) - 1)
1778 register char *s = tmp;
1780 for (i = 0; i < 7; i++)
1784 if (c ==
';' || (
int)c == EOF)
1794 if (tmp[1] ==
'x' || tmp[1] ==
'X')
1797 return atol(tmp + 1);
1800 if (!strcmp(tmp,
"lt"))
1803 if (!strcmp(tmp,
"gt"))
1806 if (!strcmp(tmp,
"amp"))
1809 if (!strcmp(tmp,
"quot"))
1812 if (!strcmp(tmp,
"apos"))
1832 return (
unsigned char)soap->
buf[soap->
bufidx];
1846 return (
unsigned char)soap->
buf[soap->
bufidx++];
1869 while ((
int)c != EOF)
1911 if (c ==
'!' || c ==
'?' || c ==
'%')
1923 while ((
int)c != EOF && c !=
'[');
1933 if (c ==
'-' && (c =
soap_get1(soap)) ==
'-')
1939 if (c ==
'-' && (c =
soap_get1(soap)) ==
'-')
1942 while ((
int)c != EOF);
1948 while ((
int)c != EOF)
1996 register char *s = buf;
1997 register int i =
sizeof(buf);
2002 while ((
int)c != EOF && c !=
'?')
2016 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"XML PI <?%s?>\n", buf));
2018 if (!strncmp(buf,
"xml ", 4))
2020 s = strstr(buf,
" encoding=");
2027 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Switching to latin1 encoding\n"));
2032 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Switching to utf-8 encoding\n"));
2053 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Moving %ld bytes forward\n", (
long)n));
2086 if (c < 0x80 && c > 0)
2096 register char *t = tmp;
2099 *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
2103 *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
2107 *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
2111 *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
2114 *t++ = (char)(0xFC | ((c >> 30) & 0x01));
2115 *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
2118 *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
2121 *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
2124 *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
2127 *t++ = (char)(0x80 | (c & 0x3F));
2132 sprintf(tmp,
"&#%lu;", c);
2175 if (c == 0xEF && c1 == 0x3B && c2 == 0x3F)
2179 return ((
soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2;
2184 return ((
soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
2189 return ((
soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
2216 for (i = 0; i < n; i++)
2218 register int m = *s++;
2219 d[0] = (char)((m >> 4) + (m > 159 ?
'7' :
'0'));
2221 d[1] = (char)(m + (m > 9 ?
'7' :
'0'));
2253 register size_t i, k;
2262 for (i = 0; i < k; i++)
2264 register char d1, d2;
2287 *n = (int)(soap->
lablen + i - k);
2297 *s++ = ((d1 >=
'A' ? (d1 & 0x7) + 9 : d1 -
'0') << 4) + (d2 >=
'A' ? (d2 & 0x7) + 9 : d2 -
'0');
2319 register char d1, d2;
2348 *s++ = ((d1 >=
'A' ? (d1 & 0x7) + 9 : d1 -
'0') << 4) + (d2 >=
'A' ? (d2 & 0x7) + 9 : d2 -
'0');
2364 register unsigned long m;
2382 for (; n > 2; n -= 3, s += 3)
2385 m = (m << 8) | s[1];
2386 m = (m << 8) | s[2];
2388 for (i = 4; i > 0; m >>= 6)
2389 d[--i] = soap_base64o[m & 0x3F];
2399 for (i = 0; i < n; i++)
2400 m = (m << 8) | *s++;
2405 for (i++; i > 0; m >>= 6)
2406 d[--i] = soap_base64o[m & 0x3F];
2408 for (i = 3; i > n; i--)
2440 register size_t i, k;
2455 for (i = 0; i < k - 2; i += 3)
2457 register unsigned long m = 0;
2464 if (c ==
'=' || c < 0)
2471 *s++ = (char)((m >> 4) & 0xFF);
2475 *s++ = (char)((m >> 10) & 0xFF);
2476 *s++ = (char)((m >> 2) & 0xFF);
2481 *n = (int)(soap->
lablen + i - k);
2500 if (c >= 0 && c <= 79)
2502 register int b = soap_base64i[c];
2521 *s++ = (char)((m >> 16) & 0xFF);
2522 *s++ = (char)((m >> 8) & 0xFF);
2523 *s++ = (char)(m & 0xFF);
2546 register unsigned long m = 0;
2553 if (c ==
'=' || c < 0)
2561 *s++ = (char)((m >> 4) & 0xFF);
2565 *s++ = (char)((m >> 10) & 0xFF);
2566 *s++ = (char)((m >> 2) & 0xFF);
2587 if (c >= 0 && c <= 79)
2589 int b = soap_base64i[c];
2608 *s++ = (char)((m >> 16) & 0xFF);
2609 *s++ = (char)((m >> 8) & 0xFF);
2610 *s++ = (char)(m & 0xFF);
2624 soap_xop_forward(
struct soap *soap,
unsigned char **ptr,
int *size,
char **
id,
char **type,
char **options)
2627 int body = soap->
body;
2653 soap_dime_forward(
struct soap *soap,
unsigned char **ptr,
int *size,
char **
id,
char **type,
char **options)
2692 if (s && (t = (
char*)
soap_malloc(soap, strlen(s) + 1)))
2715 if ((t = (
wchar_t*)
soap_malloc(soap,
sizeof(
wchar_t) * (n + 1))))
2716 memcpy(t, s,
sizeof(
wchar_t) * (n + 1));
2731 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"New block sequence (prev=%p)\n", soap->
blist));
2759 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Push block of %u bytes (%u bytes total)\n", (
unsigned int)n, (
unsigned int)b->
size + (
unsigned int)n));
2761 if (!(p = (
char*)
SOAP_MALLOC(soap, n +
sizeof(
char*) +
sizeof(
size_t))))
2767 *(
char**)p = b->
ptr;
2768 *(
size_t*)(p +
sizeof(
char*)) = n;
2771 return p +
sizeof(
char*) +
sizeof(
size_t);
2790 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Pop block\n"));
2792 b->
size -= *(
size_t*)(p +
sizeof(
char*));
2793 b->
ptr = *(
char**)p;
2799 #ifndef WITH_NOIDREF
2810 register void *p, **q;
2814 for (ip = soap->
iht[i]; ip; ip = ip->
next)
2816 if (ip->
ptr && (
char*)ip->
ptr >= start && (
char*)ip->
ptr < end)
2818 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Update id='%s' %p -> %p\n", ip->
id, ip->
ptr, (
char*)ip->
ptr + (p1 - p2)));
2819 ip->
ptr = (
char*)ip->
ptr + (p1 - p2);
2822 for (q = &ip->
link; q; q = (
void**)p)
2826 if (p && (
char*)p >= start && (
char*)p < end)
2828 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Link update id='%s' %p\n", ip->
id, p));
2829 *q = (
char*)p + (p1 - p2);
2833 for (q = &ip->
copy; q; q = (
void**)p)
2837 if (p && (
char*)p >= start && (
char*)p < end)
2839 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Copy chain update id='%s' %p\n", ip->
id, p));
2840 *q = (
char*)p + (p1 - p2);
2846 if ((
char*)fp->
ptr >= start && (
char*)fp->
ptr < end)
2848 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Copy list update id='%s' %p\n", ip->
id, fp));
2849 fp->
ptr = (
char*)fp->
ptr + (p1 - p2);
2857 for (xp = soap->
xlist; xp; xp = xp->
next)
2859 if (xp->
ptr && (
char*)xp->
ptr >= start && (
char*)xp->
ptr < end)
2862 xp->
ptr = (
unsigned char**)((
char*)xp->
ptr + (p1 - p2));
2863 xp->
size = (
int*)((
char*)xp->
size + (p1 - p2));
2864 xp->
type = (
char**)((
char*)xp->
type + (p1 - p2));
2875 #ifndef WITH_NOIDREF
2883 register const char *p;
2887 for (ip = soap->
iht[i]; ip; ip = ip->
next)
2889 for (p = (
const char*)ip->
copy; p; p = *(
const char**)p)
2890 if (p >= start && p < end)
2894 if ((
const char*)fp->
ptr >= start && (
const char*)fp->
ptr < end)
2905 #ifndef WITH_NOIDREF
2916 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Resolving forwarded data\n"));
2920 for (ip = soap->
iht[i]; ip; ip = ip->
next)
2924 register void * p, **q, *r;
2925 q = (
void**)ip->
link;
2929 DBGLOG(TEST,
if (q) SOAP_MESSAGE(fdebug,
"Traversing link chain to resolve id='%s'\n", ip->
id));
2935 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"... link %p -> %p\n", q, r));
2939 else if (*ip->
id ==
'#')
2941 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Missing data for id='%s'\n", ip->
id));
2942 strcpy(soap->
id, ip->
id + 1);
2951 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Resolution phase\n"));
2955 for (ip = soap->
iht[i]; ip; ip = ip->
next)
2961 register void * p, **q = (
void**)ip->
copy;
2963 DBGLOG(TEST,
if (q) SOAP_MESSAGE(fdebug,
"Traversing copy chain to resolve id='%s'\n", ip->
id));
2969 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"... copy %p -> %p (%u bytes)\n", ip->
ptr, q, (
unsigned int)ip->
size));
2981 register unsigned int k = fp->
level;
2982 register void *p = ip->
ptr;
2983 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Resolving forwarded data type=%d location=%p level=%u,%u id='%s'\n", ip->
type, p, ip->
level, fp->
level, ip->
id));
2985 while (ip->
level < k)
2987 register void **q = (
void**)
soap_malloc(soap,
sizeof(
void*));
2993 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Descending one level, new location=%p holds=%p...\n", q, *q));
3017 for (ip = soap->
iht[i]; ip; ip = ip->
next)
3021 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Resolution error: forwarded data for id='%s' could not be propagated, please report this problem to the developers\n", ip->
id));
3027 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Resolution done\n"));
3045 b->
size -= *(
size_t*)(b->
ptr +
sizeof(
char*)) - n;
3046 *(
size_t*)(b->
ptr +
sizeof(
char*)) = n;
3070 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"First block\n"));
3083 return r +
sizeof(
char*) +
sizeof(
size_t);
3103 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Next block\n"));
3104 b->
ptr = *(
char**)p;
3108 return b->
ptr +
sizeof(
char*) +
sizeof(
size_t);
3125 return *(
size_t*)(b->
ptr +
sizeof(
char*));
3143 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"End of block sequence, free all remaining blocks\n"));
3145 for (p = b->
ptr; p; p = q)
3151 if (soap->
blist == b)
3157 for (bp = soap->
blist; bp; bp = bp->
next)
3170 DBGLOG(TEST,
if (soap->
blist) SOAP_MESSAGE(fdebug,
"Restore previous block sequence\n"));
3182 register char *q, *s;
3187 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Save all blocks in contiguous memory space of %u bytes (%p->%p)\n", (
unsigned int)b->
size, b->
ptr, p));
3199 #ifndef WITH_NOIDREF
3205 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Copy %u bytes from %p to %p\n", (
unsigned int)n, q, s));
3255 sprintf(soap->
type,
"%s[%d", type, size[0]);
3257 for (i = 1; i < dim; i++)
3258 sprintf(soap->
type + strlen(soap->
type),
" %d", size[i]);
3264 sprintf(soap->
type,
"%s[%d", type, size[0] + offset[0]);
3266 for (i = 1; i < dim; i++)
3267 sprintf(soap->
type + strlen(soap->
type),
",%d", size[i] + offset[i]);
3271 sprintf(soap->
type,
"%s[%d", type, size[0]);
3273 for (i = 1; i < dim; i++)
3274 sprintf(soap->
type + strlen(soap->
type),
",%d", size[i]);
3277 strcat(soap->
type,
"]");
3305 for (i = 1; i < dim; i++)
3320 register int i, n = size[0];
3322 for (i = 1; i < dim; i++)
3336 register int i, j = 0;
3339 for (i = 0; i < dim && attr && *attr; i++)
3343 j += offset[i] = (int)atol(attr);
3344 attr = strchr(attr,
',');
3347 for (i = 0; i < dim && attr && *attr; i++)
3351 j += (int)atol(attr);
3352 attr = strchr(attr,
',');
3386 attr1 = strchr(s,
',');
3389 attr1 = strchr(s,
' ');
3391 if (attr2 && *attr2)
3421 register int i, k, n;
3426 i = (int)strlen(attr);
3431 for (i = i - 1; i >= 0; i--)
3432 if (attr[i] ==
'[' || attr[i] ==
',' || attr[i] ==
' ')
3435 k = (int)atol(attr + i + 1);
3436 n *= size[--dim] = k;
3441 while (i >= 0 && attr[i] !=
'[');
3464 pos[n++] = (int)atol(attr + i);
3466 while (attr[i] && attr[i] !=
',' && attr[i] !=
']')
3487 register short i = -1;
3488 register size_t n, k;
3495 for (i = 0; p->
id; p++, i++)
3497 if (p->
ns && !strcmp(ns, p->
ns))
3510 if (!strcmp(ns, p->
out))
3542 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Push namespace binding (level=%u) '%s' '%s'\n", soap->
level,
id, ns));
3546 np->
ns = np->
id + n + 1;
3548 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns));
3553 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Push OK ('%s' matches '%s' in namespace table)\n",
id, p->
id));
3572 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Pop namespace binding (level=%u) '%s'\n", soap->
level, np->
id));
3589 while (np && (strncmp(np->
id, id1, n1) || np->
id[n1]))
3603 if (n1 == 3 && n1 == n2 && !strncmp(id1,
"xml", 3) && !strncmp(id1, id2, 3))
3618 register const char *s;
3620 if (!tag || !strncmp(tag,
"xml", 3))
3625 if (!(s = strchr(tag,
':')))
3627 while (np && *np->
id)
3632 while (np && (strncmp(np->
id, tag, s - tag) || np->
id[s - tag]))
3661 register int c1 = *s;
3662 register int c2 = *t;
3664 if (!c1 || c1 ==
'"')
3671 if (c1 >=
'A' && c1 <=
'Z')
3674 if (c2 >=
'A' && c2 <=
'Z')
3688 if (c2 >=
'A' && c2 <=
'Z')
3695 if (!c1 || c1 ==
'"')
3698 if (c1 >=
'A' && c1 <=
'Z')
3715 if (*t ==
'*' && !t[1])
3729 register const char *s, *t;
3732 if (!tag1 || !tag2 || !*tag2)
3735 s = strchr(tag1,
':');
3736 t = strchr(tag2,
':');
3747 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
3761 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
3769 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2));
3781 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Tags match: '%s' '%s'\n", tag1, tag2));
3799 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Array type mismatch: '%s' '%s'\n", soap->
arrayType, type));
3821 unsigned char buf[4];
3823 if (!soap_ssl_init_done)
3826 RAND_pseudo_bytes(buf, 4);
3836 soap_ssl_server_context(
struct soap *soap,
unsigned short flags,
const char *keyfile,
const char *password,
const char *cafile,
const char *capath,
const char *dhfile,
const char *randfile,
const char *sid)
3850 SSL_CTX_set_session_id_context(soap->
ctx, (
unsigned char*)sid, (
unsigned int)strlen(sid));
3862 soap_ssl_client_context(
struct soap *soap,
unsigned short flags,
const char *keyfile,
const char *password,
const char *cafile,
const char *capath,
const char *randfile)
3883 if (!soap_ssl_init_done)
3885 soap_ssl_init_done = 1;
3888 SSL_load_error_strings();
3891 if (!RAND_load_file(
"/dev/urandom", 1024))
3894 RAND_seed(buf,
sizeof(buf));
3896 while (!RAND_status())
3899 RAND_seed(&r,
sizeof(
int));
3913 int err = SSL_get_error(soap->
ssl, ret);
3917 strcpy(soap->
msgbuf, msg);
3919 return ERR_error_string(err, soap->
msgbuf);
3921 if (ERR_peek_error())
3924 strcat(soap->
msgbuf,
"\n");
3926 while ((r = ERR_get_error()))
3934 strcpy(soap->
msgbuf,
"EOF was observed that violates the protocol. The client probably provided invalid authentication information.");
3937 sprintf(soap->
msgbuf,
"Error observed by underlying BIO: %s", strerror(errno));
3949 ssl_password(
char *buf,
int num,
int rwflag,
void *userdata)
3951 if (num < (
int)strlen((
char*)userdata) + 1)
3954 return (
int)strlen(strcpy(buf, (
char*)userdata));
3996 ssl_auth_init(
struct soap *soap)
4001 if (!soap_ssl_init_done)
4008 if (!(soap->
ctx = SSL_CTX_new(SSLv23_method())))
4018 if (!RAND_load_file(soap->
randfile, -1))
4024 if (!SSL_CTX_load_verify_locations(soap->
ctx, soap->
cafile, soap->
capath))
4028 SSL_CTX_set_client_CA_list(soap->
ctx, SSL_load_client_CA_file(soap->
cafile));
4033 if (!SSL_CTX_set_default_verify_paths(soap->
ctx))
4040 if (!SSL_CTX_use_certificate_chain_file(soap->
ctx, soap->
keyfile))
4045 SSL_CTX_set_default_passwd_cb_userdata(soap->
ctx, (
void*)soap->
password);
4046 SSL_CTX_set_default_passwd_cb(soap->
ctx, ssl_password);
4049 if (!SSL_CTX_use_PrivateKey_file(soap->
ctx, soap->
keyfile, SSL_FILETYPE_PEM))
4069 RSA *rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
4071 if (!SSL_CTX_set_tmp_rsa(soap->
ctx, rsa))
4085 bio = BIO_new_file(soap->
dhfile,
"r");
4090 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
4093 if (SSL_CTX_set_tmp_dh(soap->
ctx, dh) < 0)
4104 flags = (SSL_OP_ALL | SSL_OP_NO_SSLv2);
4107 flags |= SSL_OP_NO_TLSv1;
4110 flags |= SSL_OP_NO_SSLv3;
4112 SSL_CTX_set_options(soap->
ctx, flags);
4115 mode = (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
4117 mode = SSL_VERIFY_PEER;
4119 mode = SSL_VERIFY_NONE;
4122 #if (OPENSSL_VERSION_NUMBER < 0x00905100L)
4123 SSL_CTX_set_verify_depth(soap->
ctx, 1);
4125 SSL_CTX_set_verify_depth(soap->
ctx, 9);
4134 ssl_verify_callback(
int ok, X509_STORE_CTX *store)
4141 X509 *cert = X509_STORE_CTX_get_current_cert(store);
4142 fprintf(stderr,
"SSL verify error or warning with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store)));
4143 X509_NAME_oneline(X509_get_issuer_name(cert), data,
sizeof(data));
4144 fprintf(stderr,
"certificate issuer %s\n", data);
4145 X509_NAME_oneline(X509_get_subject_name(cert), data,
sizeof(data));
4146 fprintf(stderr,
"certificate subject %s\n", data);
4158 ssl_verify_callback_allow_expired_certificate(
int ok, X509_STORE_CTX *store)
4160 ok = ssl_verify_callback(ok, store);
4162 if (ok == 0 && X509_STORE_CTX_get_error(store) == X509_V_ERR_CERT_HAS_EXPIRED)
4165 fprintf(stderr,
"ignoring certificate expiration\n");
4167 X509_STORE_CTX_set_error(store, X509_V_OK);
4195 soap->
ssl = SSL_new(soap->
ctx);
4201 SSL_clear(soap->
ssl);
4207 bio = BIO_new_socket((
int)soap->socket, BIO_NOCLOSE);
4208 SSL_set_bio(soap->ssl, bio, bio);
4211 while ((r = SSL_accept(soap->ssl)) <= 0)
4213 int err = SSL_get_error(soap->
ssl, r);
4215 if (err == SSL_ERROR_WANT_ACCEPT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
4217 struct timeval timeout;
4221 if ((
int)soap->
socket >= (
int)FD_SETSIZE)
4226 timeout.tv_usec = 100000;
4228 FD_SET(soap->
socket, &fd);
4230 if (err == SSL_ERROR_WANT_READ)
4231 s = select((
int)soap->
socket + 1, &fd, NULL, &fd, &timeout);
4233 s = select((
int)soap->
socket + 1, NULL, &fd, &fd, &timeout);
4263 if ((err = SSL_get_verify_result(soap->
ssl)) != X509_V_OK)
4269 peer = SSL_get_peer_certificate(soap->
ssl);
4303 if (WSAStartup(MAKEWORD(1, 1), &w))
4329 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Done with context\n"));
4343 soap_free_cookies(soap);
4349 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Removing plugin '%s'\n", soap->
plugins->
id));
4405 SSL_SESSION_free(soap->
session);
4424 SSL_free(soap->
ssl);
4432 SSL_CTX_free(soap->
ctx);
4439 ERR_remove_state(0);
4441 #ifdef WITH_C_LOCALE
4460 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Free logfiles\n"));
4470 soap_close_logfile(soap, i);
4475 #ifdef SOAP_MEM_DEBUG
4476 soap_free_mht(soap);
4508 register const char *msg = NULL;
4516 msg =
"WSAStartup failed";
4525 {sprintf(soap->
msgbuf,
"TCP/UDP IP error %d", soap->
errnum);
4560 tcp_gethost(
struct soap *soap,
const char *addr,
struct in_addr *inaddr)
4563 struct hostent hostent, *host = &hostent;
4567 iadd = inet_addr((
char*)addr);
4569 #if defined(_AIX43) || ((defined(TRU64) || defined(HP_UX)) && defined(HAVE_GETHOSTBYNAME_R))
4570 struct hostent_data ht_data;
4573 iadd = inet_addr((
void*)addr);
4575 iadd = inet_addr(addr);
4581 memcpy(inaddr, &iadd,
sizeof(iadd));
4585 #if defined(__GLIBC__) || (defined(HAVE_GETHOSTBYNAME_R) && (defined(FREEBSD) || defined(__FreeBSD__)))
4590 #elif defined(_AIX43) || ((defined(TRU64) || defined(HP_UX)) && defined(HAVE_GETHOSTBYNAME_R))
4591 memset((
void*)&ht_data, 0,
sizeof(ht_data));
4593 if (gethostbyname_r(addr, &hostent, &ht_data) < 0)
4599 #elif defined(HAVE_GETHOSTBYNAME_R)
4601 #elif defined(VXWORKS)
4605 hostint = hostGetByName((
char*)addr);
4607 if (hostint == ERROR)
4616 if (!(host = gethostbyname((
void*)addr)))
4621 if (!(host = gethostbyname(addr)))
4629 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Host name not found\n"));
4634 inaddr->s_addr = hostint;
4636 memcpy(inaddr, host->h_addr, host->h_length);
4648 tcp_connect(
struct soap *soap,
const char *endpoint,
const char *host,
int port)
4651 struct addrinfo hints, *res, *ressave;
4675 memset((
void*)&hints, 0,
sizeof(hints));
4676 hints.ai_family = PF_UNSPEC;
4680 hints.ai_socktype = SOCK_DGRAM;
4683 hints.ai_socktype = SOCK_STREAM;
4690 err = getaddrinfo(host,
soap_int2s(soap, port), &hints, &res);
4700 fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
4709 fd = socket(AF_INET, SOCK_DGRAM, 0);
4712 fd = socket(AF_INET, SOCK_STREAM, 0);
4730 freeaddrinfo(ressave);
4735 #ifdef SOCKET_CLOSE_ON_EXEC
4738 SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
4741 fcntl(fd, F_SETFD, 1);
4748 struct linger linger;
4749 memset((
void*)&linger, 0,
sizeof(linger));
4753 if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (
char*)&linger,
sizeof(
struct linger)))
4759 freeaddrinfo(ressave);
4770 freeaddrinfo(ressave);
4775 if ((soap->
keep_alive || soap->
tcp_keep_alive) && setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (
char*)&set,
sizeof(
int)))
4781 freeaddrinfo(ressave);
4786 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (
char*)&len,
sizeof(
int)))
4792 freeaddrinfo(ressave);
4797 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (
char*)&len,
sizeof(
int)))
4803 freeaddrinfo(ressave);
4816 freeaddrinfo(ressave);
4822 #ifdef TCP_KEEPINTVL
4830 freeaddrinfo(ressave);
4844 freeaddrinfo(ressave);
4852 if (!(soap->
omode &
SOAP_IO_UDP) && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (
char*)&set,
sizeof(
int)))
4858 freeaddrinfo(ressave);
4868 struct sockaddr_in6 *in6addr = (
struct sockaddr_in6*)res->ai_addr;
4872 #elif defined(IP_MULTICAST_TTL)
4880 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (
char*)&ttl,
sizeof(ttl)))
4891 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (
char*)soap->
ipv4_multicast_if,
sizeof(
struct in_addr)))
4900 #ifndef IP_MULTICAST_IF
4901 #define IP_MULTICAST_IF 2
4904 if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (
char*)soap->
ipv4_multicast_if,
sizeof(
struct in_addr)))
4917 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Opening socket %d to host='%s' port=%d\n", fd, host, port));
4920 memset((
void*)&soap->
peer, 0,
sizeof(soap->
peer));
4921 soap->
peer.sin_family = AF_INET;
4931 freeaddrinfo(ressave);
4945 freeaddrinfo(ressave);
4950 soap->
peer.sin_port = htons((
short)port);
4959 freeaddrinfo(ressave);
4977 if (connect(fd, res->ai_addr, (
int)res->ai_addrlen))
4979 if (connect(fd, (
struct sockaddr*)&soap->
peer,
sizeof(soap->
peer)))
4998 if ((
int)fd >= (
int)FD_SETSIZE)
5002 freeaddrinfo(ressave);
5011 struct timeval timeout;
5018 timeout.tv_usec = 0;
5028 r = select((
int)fd + 1, NULL, &fds, NULL, &timeout);
5036 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Connect timeout\n"));
5040 freeaddrinfo(ressave);
5050 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Could not connect to host\n"));
5054 freeaddrinfo(ressave);
5062 if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, (
char*)&soap->
errnum, &k) && !soap->
errnum)
5065 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Could not connect to host\n"));
5073 freeaddrinfo(ressave);
5093 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Could not connect to host\n"));
5097 freeaddrinfo(ressave);
5108 freeaddrinfo(ressave);
5131 size_t n = soap->
count;
5132 char *userid, *passwd;
5150 strcpy(soap->
tmpbuf,
"Basic ");
5205 soap->
ssl = SSL_new(soap->
ctx);
5215 SSL_clear(soap->
ssl);
5222 SSL_SESSION_free(soap->
session);
5228 bio = BIO_new_socket((
int)fd, BIO_NOCLOSE);
5229 SSL_set_bio(soap->
ssl, bio, bio);
5241 if ((r = SSL_connect(soap->
ssl)) <= 0)
5243 int err = SSL_get_error(soap->
ssl, r);
5245 if (err != SSL_ERROR_WANT_CONNECT && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
5254 struct timeval timeout;
5258 if ((
int)soap->
socket >= (
int)FD_SETSIZE)
5269 timeout.tv_usec = 0;
5280 if (err == SSL_ERROR_WANT_READ)
5281 r = select((
int)fd + 1, &fds, NULL, NULL, &timeout);
5283 r = select((
int)fd + 1, NULL, &fds, NULL, &timeout);
5288 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Connect timeout\n"));
5296 while (!SSL_is_init_finished(soap->
ssl));
5307 if ((err = SSL_get_verify_result(soap->
ssl)) != X509_V_OK)
5320 peer = SSL_get_peer_certificate(soap->
ssl);
5329 ext_count = X509_get_ext_count(peer);
5335 for (i = 0; i < ext_count; i++)
5337 X509_EXTENSION *ext = X509_get_ext(peer, i);
5338 const char *ext_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
5340 if (ext_str && !strcmp(ext_str,
"subjectAltName"))
5342 X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext);
5344 #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
5345 const unsigned char *data;
5347 unsigned char *data;
5349 STACK_OF(CONF_VALUE) *val;
5355 data = ext->value->data;
5356 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
5359 ext_data = ASN1_item_d2i(NULL, &data, ext->value->length, ASN1_ITEM_ptr(meth->it));
5367 ext_data = meth->d2i(NULL, &data, ext->value->length);
5371 ext_data = meth->d2i(NULL, &data, ext->value->length);
5373 val = meth->i2v(meth, ext_data, NULL);
5375 for (j = 0; j < sk_CONF_VALUE_num(val); j++)
5377 CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
5379 if (nval && !strcmp(nval->name,
"DNS") && !strcmp(nval->value, host))
5392 if (!ok && (subj = X509_get_subject_name(peer)))
5399 i = X509_NAME_get_index_by_NID(subj, NID_commonName, i);
5404 name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i));
5412 unsigned char *tmp = NULL;
5413 ASN1_STRING_to_UTF8(&tmp, name);
5457 soap_bind(
struct soap *soap,
const char *host,
int port,
int backlog)
5460 struct addrinfo *addrinfo = NULL;
5461 struct addrinfo hints;
5462 struct addrinfo res;
5469 int level = IPPROTO_IPV6;
5494 memset((
void*)&hints, 0,
sizeof(hints));
5495 hints.ai_family = PF_UNSPEC;
5499 hints.ai_socktype = SOCK_DGRAM;
5502 hints.ai_socktype = SOCK_STREAM;
5504 hints.ai_flags = AI_PASSIVE;
5506 err = getaddrinfo(host,
soap_int2s(soap, port), &hints, &addrinfo);
5511 memcpy(&soap->
peer, addrinfo->ai_addr, addrinfo->ai_addrlen);
5512 soap->
peerlen = addrinfo->ai_addrlen;
5513 res.ai_addr = (
struct sockaddr*) & soap->
peer;
5514 res.ai_addrlen = soap->
peerlen;
5515 freeaddrinfo(addrinfo);
5518 if (err || !addrinfo)
5524 soap->
master = (int)socket(res.ai_family, res.ai_socktype, res.ai_protocol);
5529 soap->
master = (
int)socket(AF_INET, SOCK_DGRAM, 0);
5532 soap->
master = (int)socket(AF_INET, SOCK_STREAM, 0);
5550 #ifdef SOCKET_CLOSE_ON_EXEC
5553 SetHandleInformation((HANDLE)soap->
master, HANDLE_FLAG_INHERIT, 0);
5556 fcntl(soap->
master, F_SETFD, 1);
5575 if (setsockopt(soap->
master, SOL_SOCKET, SO_SNDBUF, (
char*)&len,
sizeof(
int)))
5582 if (setsockopt(soap->
master, SOL_SOCKET, SO_RCVBUF, (
char*)&len,
sizeof(
int)))
5591 if (!(soap->
omode &
SOAP_IO_UDP) && setsockopt(soap->
master, IPPROTO_TCP, TCP_NODELAY, (
char*)&set,
sizeof(
int)))
5603 if (setsockopt(soap->
master, level, IPV6_V6ONLY, (
char*)&unset,
sizeof(
int)))
5613 if (bind(soap->
master, res.ai_addr, (
int)res.ai_addrlen))
5616 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Could not bind to host\n"));
5624 memset((
void*)&soap->
peer, 0,
sizeof(soap->
peer));
5625 soap->
peer.sin_family = AF_INET;
5637 soap->
peer.sin_addr.s_addr = htonl(INADDR_ANY);
5639 soap->
peer.sin_port = htons((
short)port);
5645 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Could not bind to host\n"));
5656 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Could not bind to host\n"));
5676 struct timeval timeout;
5677 fd_set rfd, sfd, xfd;
5681 if ((
int)soap->
socket >= (
int)FD_SETSIZE)
5686 timeout.tv_usec = 0;
5693 FD_SET(soap->
socket, &rfd);
5694 FD_SET(soap->
socket, &sfd);
5695 FD_SET(soap->
socket, &xfd);
5696 r = select((
int)soap->
socket + 1, &rfd, &sfd, &xfd, &timeout);
5698 if (r > 0 && FD_ISSET(soap->
socket, &xfd))
5703 FD_SET(soap->
master, &sfd);
5704 r = select((
int)soap->
master + 1, NULL, &sfd, NULL, &timeout);
5716 && FD_ISSET(soap->
socket, &sfd)
5717 && (!FD_ISSET(soap->
socket, &rfd)
5718 || SSL_peek(soap->
ssl, soap->
tmpbuf, 1) > 0))
5724 && FD_ISSET(soap->
socket, &sfd)
5725 && (!FD_ISSET(soap->
socket, &rfd)
5742 DBGLOG(TEST, SOAP_MESSAGE(fdebug,
"Polling: other end down on socket=%d select=%d\n", soap->
socket, r));
5759 #ifdef SOCKET_CLOSE_ON_EXEC
5762 SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
5765 fcntl(fd, F_SETFD, FD_CLOEXEC);
5781 int n = (int)
sizeof(soap->
peer);
5793 memset((
void*)&soap->
peer, 0,
sizeof(soap->
peer));