📄 stdsoap2.c
字号:
soap_push_namespace(struct soap *soap, const char *id, const char *ns){ register struct soap_nlist *np; register struct Namespace *p; np = (struct soap_nlist*)SOAP_MALLOC(sizeof(struct soap_nlist) + strlen(id)); if (!np) return soap->error = SOAP_EOM; np->next = soap->nlist; soap->nlist = np; strcpy(np->id, id); np->level = soap->level; np->index = -1; np->ns = NULL; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns)); if ((p = soap->local_namespaces)) { register short i; for (i = 0; p->id; p++, i++) { if (p->ns) if (!soap_tag_cmp(ns, p->ns)) break; if (p->in) if (!soap_tag_cmp(ns, p->in)) { if (p->out) SOAP_FREE(p->out); if ((p->out = (char*)SOAP_MALLOC(strlen(ns) + 1))) strcpy(p->out, ns); if (i == 0) { if (!strcmp(ns, soap_env1)) { soap->version = 1; /* and make sure we use SOAP 1.1 encoding */ if (p->out) SOAP_FREE(p[1].out); if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc1)))) strcpy(p[1].out, soap_enc1); } else { soap->version = 2; /* and make sure we use SOAP 1.2 encoding */ if (p[1].out) SOAP_FREE(p[1].out); if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc2)))) strcpy(p[1].out, soap_enc2); } } break; } } if (p && p->id) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id)); np->index = i; } } if (!p || !p->id) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns)); np->ns = (char*)SOAP_MALLOC(strlen(ns) + 1); if (!np->ns) return soap->error = SOAP_EOM; strcpy(np->ns, ns); } return SOAP_OK;}#endif/******************************************************************************/#ifndef PALM_2SOAP_FMAC1intSOAP_FMAC2soap_push_default_namespace(struct soap *soap, const char *id, int n){ register struct soap_nlist *np = soap->nlist; while (np && np->index >= -1) np = np->next; if (np && (!strncmp(np->id, id, n) && !np->id[n])) return SOAP_OK; np = (struct soap_nlist*)SOAP_MALLOC(sizeof(struct soap_nlist) + n); if (!np) return soap->error = SOAP_EOM; np->next = soap->nlist; soap->nlist = np; strncpy(np->id, id, n); np->id[n] = '\0'; np->level = soap->level; np->index = -2; np->ns = NULL; return SOAP_OK;}#endif/******************************************************************************/#ifndef PALM_2SOAP_FMAC1voidSOAP_FMAC2soap_pop_namespace(struct soap *soap){ register struct soap_nlist *np; while (soap->nlist && soap->nlist->level >= soap->level) { np = soap->nlist->next; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Popped namespace binding (level=%u) '%s'\n", soap->level, soap->nlist->id)); if (soap->nlist->ns) SOAP_FREE(soap->nlist->ns); SOAP_FREE(soap->nlist); soap->nlist = np; }}#endif/******************************************************************************/#ifndef PALM_2SOAP_FMAC1intSOAP_FMAC2soap_match_namespace(struct soap *soap, const char *id1, const char *id2, int n1, int n2) { register struct soap_nlist *np = soap->nlist; while (np && (np->index == -2 || (strncmp(np->id, id1, n1) || np->id[n1]))) np = np->next; if (np) { if (np->index < 0 || (np->index >= 0 && soap->local_namespaces[np->index].id && (strncmp(soap->local_namespaces[np->index].id, id2, n2) || soap->local_namespaces[np->index].id[n2]))) return SOAP_NAMESPACE; return SOAP_OK; } if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2)) return SOAP_OK; return SOAP_SYNTAX_ERROR; }#endif/******************************************************************************/#ifndef PALM_2SOAP_FMAC1const char*SOAP_FMAC2soap_default_namespace(struct soap *soap){ register struct soap_nlist *np = soap->nlist; while (np && np->index >= -1) np = np->next; if (np) return np->id; return NULL;}#endif/******************************************************************************/#ifndef PALM_2SOAP_FMAC1intSOAP_FMAC2soap_tag_cmp(register const char *s, register const char *t){ for (; *s && *s != '"'; s++, t++) if (tolower(*s) != tolower(*t)) if (*t != '-') { if (*t != '*') return 1; if (*++t) { register int c = tolower(*t); for (; *s && *s != '"'; s++) { if (tolower(*s) == c) if (!soap_tag_cmp(s + 1, t + 1)) return 0; } break; } else return 0; } if (*t == '*' && !t[1]) return 0; return *t;}#endif/******************************************************************************/#ifndef PALM_2SOAP_FMAC1intSOAP_FMAC2soap_match_tag(struct soap *soap, const char *tag1, const char *tag2){ register const char *s, *t; if (!tag1 || !tag2 || !*tag2) return SOAP_OK; s = strchr(tag1, ':'); t = strchr(tag2, ':'); if (t) { if (s) { if (SOAP_STRCMP(s + 1, t + 1)) return SOAP_TAG_MISMATCH; if (t != tag2 && soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2)) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); return SOAP_TAG_MISMATCH; } } else if (SOAP_STRCMP(tag1, t + 1)) return SOAP_TAG_MISMATCH; else if (t != tag2 && soap_match_namespace(soap, tag1, tag2, 0, t - tag2)) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2)); return SOAP_TAG_MISMATCH; } DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2)); return SOAP_OK; } if (s) { if (((soap->mode & SOAP_XML_STRICT) && soap->part != SOAP_IN_HEADER && soap->encodingStyle)) return SOAP_TAG_MISMATCH; if (SOAP_STRCMP(s + 1, tag2)) return SOAP_TAG_MISMATCH; if (!soap->encodingStyle) { t = soap_default_namespace(soap); if (!t || soap_match_namespace(soap, tag1, t, s - tag1, strlen(t))) return SOAP_TAG_MISMATCH; } } else if (SOAP_STRCMP(tag1, tag2)) return SOAP_TAG_MISMATCH; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2)); return SOAP_OK;}#endif/******************************************************************************/#ifndef PALM_2SOAP_FMAC1intSOAP_FMAC2soap_match_array(struct soap *soap, const char *type){ if (*soap->arrayType) if (soap_match_tag(soap, soap->arrayType, type) && soap_match_tag(soap, soap->arrayType, "xsd:anyType") && soap_match_tag(soap, soap->arrayType, "xsd:ur-type") ) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type)); return SOAP_TAG_MISMATCH; } return SOAP_OK;}#endif/******************************************************************************/#ifdef WITH_OPENSSL/******************************************************************************/#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_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){ int err; soap->keyfile = keyfile; soap->password = password; soap->cafile = cafile; soap->capath = capath; if (dhfile) { soap->dhfile = dhfile; soap->rsa = 0; } else { soap->dhfile = NULL; soap->rsa = 1; } soap->randfile = randfile; soap->require_client_auth = (flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION); if (!(err = soap->fsslauth(soap))) if (sid) SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, strlen(sid)); return err; }#endif/******************************************************************************/#ifndef PALM_1SOAP_FMAC1intSOAP_FMAC2soap_ssl_client_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *randfile){ soap->keyfile = keyfile; soap->password = password; soap->cafile = cafile; soap->capath = capath; soap->dhfile = NULL; soap->rsa = 0; soap->randfile = randfile; soap->require_server_auth = (flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION); return soap->fsslauth(soap);}#endif/******************************************************************************/#ifndef PALM_1static voidssl_init(){ static int done = 0; if (!done) { done = 1; SSL_library_init();#ifndef WITH_LEAN SSL_load_error_strings();#endif }}#endif/******************************************************************************/#ifndef PALM_1static const char *ssl_error(struct soap *soap, int ret){ int err = SSL_get_error(soap->ssl, ret); const char *msg = soap_str_code(h_ssl_error_codes, err); if (msg) strcpy(soap->msgbuf, msg); else return ERR_error_string(err, soap->msgbuf); if (ERR_peek_error()) { unsigned long r; strcat(soap->msgbuf, "\n"); while ((r = ERR_get_error())) ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf)); } else { switch (ret) { case 0: strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information."); break; case -1: sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno)); break; } } return soap->msgbuf;}#endif/******************************************************************************/#ifndef PALM_1static intssl_password(char *buf, int num, int rwflag, void *userdata){ if (num < (int)strlen((char*)userdata) + 1) return 0; return strlen(strcpy(buf, (char*)userdata));}#endif/******************************************************************************//* This callback is included for future references. It should not be deleted#ifndef PALM_1static DH *ssl_tmp_dh(SSL *ssl, int is_export, int keylength){ static DH *dh512 = NULL; static DH *dh1024 = NULL; DH *dh; switch (keylength) { case 512: if (!dh512) { BIO *bio = BIO_new_file("dh512.pem", "r"); if (bio) { dh512 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); return dh512; } } else return dh512; default: if (!dh1024) { BIO *bio = BIO_new_file("dh1024.pem", "r"); if (bio) { dh1024 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); } } dh = dh1024; } return dh;}#endif*//******************************************************************************/#ifndef PALM_1static intssl_auth_init(struct soap *soap){ ssl_init(); if (!soap->ctx) if (!(soap->ctx = SSL_CTX_new(SSLv23_method()))) return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR); if (soap->randfile) { if (!RAND_load_file(soap->randfile, -1)) return soap_set_receiver_error(soap, "SSL error", "Can't load randomness", SOAP_SSL_ERROR); } else if (!RAND_load_file("/dev/random", 1024)) { int r;#ifdef HAVE_RAND_R unsigned int s = (unsigned int)time(NULL);#endif RAND_seed(soap->buf, sizeof(soap->buf)); while (!RAND_status()) {#ifdef HAVE_RAND_R r = rand_r(&s);#else r = rand();#endif RAND_seed(&r, sizeof(int)); } } if (soap->cafile || soap->capath) if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath)) return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and/or directory", SOAP_SSL_ERROR); if (!SSL_CTX_set_default_verify_paths(soap->ctx)) return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR); if (soap->keyfile) { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile)) return soap_set_receiver_error(soap, "SSL error", "Can't read certificate key file", SOAP_SSL_ERROR); if (soap->password) { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password); SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password); if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM)) return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR); } } if (soap->rsa) { RSA *rsa = RSA_generate_key(512, RSA_F4, NULL, NULL); if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa)) { if (rsa) RSA_free(rsa); return soap_set_receiver_error(soap, "SSL error", "Can't set RSA key", SOAP_SSL_ERROR); } RSA_free(rsa); } else if (soap->dhfile) { DH *dh = 0; BIO *bio; bio = BIO_new_file(soap->dhfile, "r"); if (!bio) return soap_set_receiver_error(soap, "SSL error", "Can't read DH file", SOAP_SSL_ERROR); dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); if (SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0) { if (dh) DH_free(dh); return soap_set_receiver_error(soap, "SSL error", "Can't set DH parameters", SOAP_SSL_ERROR); } DH_free(dh); } SSL_CTX_set_options(soap->ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); SSL_CTX_set_verify(soap->ctx, soap->require_client_auth ? (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) : soap->require_server_auth ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, soap->fsslverify);#if (OPENSSL_VERSION_NUMBER < 0x00905100L) SSL_CTX_set_verify_depth(soap->ctx, 1); #endif return SOAP_OK;}#endif/******************************************************************************/#ifndef PALM_1static intssl_verify_callback(int ok, X509_STORE_CTX *store){#ifdef SOAP_DEBUG if (!ok) { char data[256]; X509 *cert = X509_STORE_CTX_get_current_cert(store); fprintf(stderr, "SSL Verify error 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))); X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data)); fprintf(stderr,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -