static int http_da_verify_method(struct soap *soap, const char *method, const char *passwd) { struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id); char HA1hex[65], entityHAhex[65], response[65], responseHA[32]; size_t smd_len = 16; if (!data) return SOAP_ERR; if (data->alg && !soap_tag_cmp(data->alg, "SHA-256*")) smd_len = 32; /* reject if none or basic authentication was used */ if (!soap->authrealm || !soap->userid || soap->passwd) /* passwd is set when basic auth is used */ return SOAP_ERR; /* require at least qop="auth" to prevent replay attacks */ if (!data->qop) return SOAP_ERR; if (http_da_session_update(soap->authrealm, data->nonce, data->opaque, data->cnonce, data->ncount)) return SOAP_ERR; if (http_da_calc_HA1(soap, &data->smd_data, data->alg, soap->userid, soap->authrealm, passwd, data->nonce, data->cnonce, HA1hex)) return soap->error; if (!soap_tag_cmp(data->qop, "auth-int")) (void)soap_s2hex(soap, (unsigned char*)data->digest, entityHAhex, smd_len); if (http_da_calc_response(soap, &data->smd_data, data->alg, HA1hex, data->nonce, data->ncount, data->cnonce, data->qop, method, soap->path, entityHAhex, response, responseHA)) return soap->error; /* check digest response values */ if (memcmp(data->response, responseHA, smd_len)) return SOAP_ERR; return SOAP_OK; }
static int http_da_verify_method(struct soap *soap, char *method, char *passwd) { struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id); char HA1[33], entityHAhex[33], response[33]; if (!data) return SOAP_ERR; /* reject if none or basic authentication was used */ if (!soap->authrealm || !soap->userid || soap->passwd) /* passwd is set when basic auth is used */ return SOAP_ERR; /* require at least qop="auth" to prevent replay attacks */ if (!data->qop) return SOAP_ERR; if (http_da_session_update(soap->authrealm, data->nonce, data->opaque, data->cnonce, data->ncount)) return SOAP_ERR; http_da_calc_HA1(soap, &data->context, NULL, soap->userid, soap->authrealm, passwd, data->nonce, data->cnonce, HA1); if (!soap_tag_cmp(data->qop, "auth-int")) soap_s2hex(soap, (unsigned char*)data->digest, entityHAhex, 16); http_da_calc_response(soap, &data->context, HA1, data->nonce, data->ncount, data->cnonce, data->qop, method, soap->path, entityHAhex, response); #ifdef SOAP_DEBUG fprintf(stderr, "Debug message: verifying client response=%s with calculated digest=%s\n", data->response, response); #endif /* check digest response values */ if (strcmp(data->response, response)) return SOAP_ERR; return SOAP_OK; }
static int http_da_post_header(struct soap *soap, const char *key, const char *val) { struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id); if (!data) return SOAP_PLUGIN_ERROR; /* client's HTTP Authorization response */ if (key && !strcmp(key, "Authorization")) { char HA1[33], entityHAhex[33], response[33]; char cnonce[HTTP_DA_NONCELEN]; char ncount[9]; char *qop, *method; md5_handler(soap, &data->context, MD5_FINAL, data->digest, 0); http_da_calc_nonce(soap, cnonce); http_da_calc_HA1(soap, &data->context, data->alg, soap->userid, soap->authrealm, soap->passwd, data->nonce, cnonce, HA1); if (data->qop && !soap_tag_cmp(data->qop, "*auth-int*")) { qop = "auth-int"; soap_s2hex(soap, (unsigned char*)data->digest, entityHAhex, 16); } else if (data->qop) qop = "auth"; else qop = NULL; if (soap->status == SOAP_GET) method = "GET"; else method = "POST"; sprintf(ncount, "%8.8lx", data->nc++); http_da_calc_response(soap, &data->context, HA1, data->nonce, ncount, cnonce, qop, method, soap->path, entityHAhex, response); sprintf(soap->tmpbuf, "Digest realm=\"%s\", username=\"%s\", nonce=\"%s\", uri=\"%s\", nc=%s, cnonce=\"%s\", response=\"%s\"", soap->authrealm, soap->userid, data->nonce, soap->path, ncount, cnonce, response); if (data->opaque) sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ", opaque=\"%s\"", data->opaque); if (qop) sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ", qop=\"%s\"", qop); return data->fposthdr(soap, key, soap->tmpbuf); } /* server's HTTP Authorization response */ if (key && !strcmp(key, "WWW-Authenticate")) { char nonce[HTTP_DA_NONCELEN]; char opaque[HTTP_DA_OPAQUELEN]; http_da_calc_nonce(soap, nonce); http_da_calc_opaque(soap, opaque); http_da_session_start(soap->authrealm, nonce, opaque); sprintf(soap->tmpbuf, "Digest realm=\"%s\", qop=\"auth,auth-int\", nonce=\"%s\", opaque=\"%s\"", soap->authrealm, nonce, opaque); return data->fposthdr(soap, key, soap->tmpbuf); } return data->fposthdr(soap, key, val); }
static int http_da_post_header(struct soap *soap, const char *key, const char *val) { struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id); if (!data) return SOAP_PLUGIN_ERROR; /* client's HTTP Authorization request */ if (key && (!strcmp(key, "Authorization") || !strcmp(key, "Proxy-Authorization"))) { char HA1[33], entityHAhex[33], response[33]; char cnonce[HTTP_DA_NONCELEN]; char ncount[9]; const char *qop, *method; const char *userid = (*key == 'A' ? soap->userid : soap->proxy_userid); const char *passwd = (*key == 'A' ? soap->passwd : soap->proxy_passwd); md5_handler(soap, &data->context, MD5_FINAL, data->digest, 0); if (!userid || !passwd || !soap->authrealm || !data->nonce) { #ifdef SOAP_DEBUG fprintf(stderr, "Debug message: authentication header failed, missing authentication data\n"); #endif return SOAP_OK; } http_da_calc_nonce(soap, cnonce); http_da_calc_HA1(soap, &data->context, data->alg, userid, soap->authrealm, passwd, data->nonce, cnonce, HA1); if (data->qop && !soap_tag_cmp(data->qop, "*auth-int*")) { qop = "auth-int"; soap_s2hex(soap, (unsigned char*)data->digest, entityHAhex, 16); } else if (data->qop) qop = "auth"; else qop = NULL; if (soap->status == SOAP_GET) method = "GET"; else if (soap->status == SOAP_CONNECT) method = "CONNECT"; else method = "POST"; #ifdef HAVE_SNPRINTF soap_snprintf(ncount, sizeof(ncount), "%8.8lx", data->nc++); #else sprintf(ncount, "%8.8lx", data->nc++); #endif http_da_calc_response(soap, &data->context, HA1, data->nonce, ncount, cnonce, qop, method, soap->path, entityHAhex, response); #ifdef HAVE_SNPRINTF soap_snprintf(soap->tmpbuf, sizeof(soap->tmpbuf), "Digest realm=\"%s\", username=\"%s\", nonce=\"%s\", uri=\"%s\", nc=%s, cnonce=\"%s\", response=\"%s\"", soap->authrealm, userid, data->nonce, soap->path, ncount, cnonce, response); #else sprintf(soap->tmpbuf, "Digest realm=\"%s\", username=\"%s\", nonce=\"%s\", uri=\"%s\", nc=%s, cnonce=\"%s\", response=\"%s\"", soap->authrealm, userid, data->nonce, soap->path, ncount, cnonce, response); #endif if (data->opaque) #ifdef HAVE_SNPRINTF soap_snprintf(soap->tmpbuf + strlen(soap->tmpbuf), sizeof(soap->tmpbuf) - strlen(soap->tmpbuf), ", opaque=\"%s\"", data->opaque); #else sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ", opaque=\"%s\"", data->opaque); #endif if (qop) #ifdef HAVE_SNPRINTF soap_snprintf(soap->tmpbuf + strlen(soap->tmpbuf), sizeof(soap->tmpbuf) - strlen(soap->tmpbuf), ", qop=\"%s\"", qop); #else sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ", qop=\"%s\"", qop); #endif return data->fposthdr(soap, key, soap->tmpbuf); } /* server's HTTP Authorization challenge/response */ if (key && (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate"))) { char nonce[HTTP_DA_NONCELEN]; char opaque[HTTP_DA_OPAQUELEN]; http_da_calc_nonce(soap, nonce); http_da_calc_opaque(soap, opaque); http_da_session_start(soap->authrealm, nonce, opaque); #ifdef HAVE_SNPRINTF soap_snprintf(soap->tmpbuf, sizeof(soap->tmpbuf), "Digest realm=\"%s\", qop=\"auth,auth-int\", nonce=\"%s\", opaque=\"%s\"", soap->authrealm, nonce, opaque); #else sprintf(soap->tmpbuf, "Digest realm=\"%s\", qop=\"auth,auth-int\", nonce=\"%s\", opaque=\"%s\"", soap->authrealm, nonce, opaque); #endif return data->fposthdr(soap, key, soap->tmpbuf); } return data->fposthdr(soap, key, val); }
static int http_da_post_header(struct soap *soap, const char *key, const char *val) { struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id); if (!data) return SOAP_PLUGIN_ERROR; /* client's HTTP Authorization request */ if (key && (!strcmp(key, "Authorization") || !strcmp(key, "Proxy-Authorization"))) { char HA1hex[65], entityHAhex[65], response[65], responseHA[32]; char cnonce[HTTP_DA_NONCELEN]; char ncount[9]; const char *qop, *method; const char *userid = (*key == 'A' ? soap->userid : soap->proxy_userid); const char *passwd = (*key == 'A' ? soap->passwd : soap->proxy_passwd); size_t smd_len = 16; if (data->alg && !soap_tag_cmp(data->alg, "SHA-256*")) smd_len = 32; if (soap_smd_final(soap, &data->smd_data, data->digest, NULL)) return soap->error; if (!userid || !passwd || !soap->authrealm || !data->nonce) { #ifdef SOAP_DEBUG fprintf(stderr, "Debug message: authentication header construction failed, missing some of the authentication data!\n"); #endif return SOAP_OK; } http_da_calc_nonce(soap, cnonce); if (http_da_calc_HA1(soap, &data->smd_data, data->alg, userid, soap->authrealm, passwd, data->nonce, cnonce, HA1hex)) return soap->error; if (soap->status != SOAP_GET && soap->status != SOAP_CONNECT && data->qop && !soap_tag_cmp(data->qop, "*auth-int*")) { qop = "auth-int"; (void)soap_s2hex(soap, (unsigned char*)data->digest, entityHAhex, smd_len); } else if (data->qop) qop = "auth"; else qop = NULL; if (soap->status == SOAP_GET) method = "GET"; else if (soap->status == SOAP_CONNECT) method = "CONNECT"; else method = "POST"; (SOAP_SNPRINTF(ncount, sizeof(ncount), 8), "%8.8lx", data->nc++); if (http_da_calc_response(soap, &data->smd_data, data->alg, HA1hex, data->nonce, ncount, cnonce, qop, method, soap->path, entityHAhex, response, responseHA)) return soap->error; (SOAP_SNPRINTF(soap->tmpbuf, sizeof(soap->tmpbuf), strlen(soap->authrealm) + strlen(userid) + strlen(data->nonce) + strlen(soap->path) + strlen(ncount) + strlen(cnonce) + strlen(response) + 75), "Digest algorithm=%s, realm=\"%s\", username=\"%s\", nonce=\"%s\", uri=\"%s\", nc=%s, cnonce=\"%s\", response=\"%s\"", data->alg ? data->alg : "MD5", soap->authrealm, userid, data->nonce, soap->path, ncount, cnonce, response); if (data->opaque) { size_t l = strlen(soap->tmpbuf); (SOAP_SNPRINTF(soap->tmpbuf + l, sizeof(soap->tmpbuf) - l, strlen(data->opaque) + 11), ", opaque=\"%s\"", data->opaque); } if (qop) { size_t l = strlen(soap->tmpbuf); (SOAP_SNPRINTF(soap->tmpbuf + l, sizeof(soap->tmpbuf) - l, strlen(qop) + 8), ", qop=\"%s\"", qop); } return data->fposthdr(soap, key, soap->tmpbuf); } /* server's HTTP Authorization challenge/response */ if (key && (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate"))) { static const char *algos[] = { "MD5", "MD5-sess", "SHA-256", "SHA-256-sess", "SHA-512-256", "SHA-512-256-sess" }; const char *alg = algos[data->option]; char nonce[HTTP_DA_NONCELEN]; char opaque[HTTP_DA_OPAQUELEN]; http_da_calc_nonce(soap, nonce); http_da_calc_opaque(soap, opaque); http_da_session_start(soap->authrealm, nonce, opaque); if (data->option > 0) { (SOAP_SNPRINTF(soap->tmpbuf, sizeof(soap->tmpbuf), strlen(soap->authrealm) + strlen(nonce) + strlen(opaque) + 59), "Digest algorithm=%s, realm=\"%s\", qop=\"auth,auth-int\", nonce=\"%s\", opaque=\"%s\"", alg, soap->authrealm, nonce, opaque); if (data->fposthdr(soap, key, soap->tmpbuf)) return soap->error; } (SOAP_SNPRINTF(soap->tmpbuf, sizeof(soap->tmpbuf), strlen(soap->authrealm) + strlen(nonce) + strlen(opaque) + 59), "Digest algorithm=MD5, realm=\"%s\", qop=\"auth,auth-int\", nonce=\"%s\", opaque=\"%s\"", soap->authrealm, nonce, opaque); return data->fposthdr(soap, key, soap->tmpbuf); } return data->fposthdr(soap, key, val); }