⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpda.c

📁 一款开源的soap库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*httpda.cgSOAP HTTP Digest Authentication plugin.Supports both Basic and Digest authentication.Usage (client side, see httpdatest.h/.c for example):soap_register_plugin(&soap, http_da);if (soap_call_ns__method(&soap, ...) != SOAP_OK){ if (soap.error == 401) // HTTP authentication is required  { if (!strcmp(soap.authrealm, authrealm)) // check authentication realm    { struct http_da_info info; // to store userid and passwd      http_da_save(&soap, &info, authrealm, userid, passwd);      if (soap_call_ns__method(&soap, ...) == SOAP_OK)      { ...        soap_end(&soap);	... // userid and passwd were deallocated        http_da_restore(&soap, &info); // get userid and passwd after soap_end()        if (!soap_call_ns__method(&soap, ...) == SOAP_OK)	  ...        http_da_release(&soap, &info); // remove userid and passwdUsage (server side, see httpdatest.h/.c for example):soap_register_plugin(&soap, http_da);...soap_serve(&soap);...int ns__method(struct soap *soap, ...){ if (soap->userid && soap->passwd) // Basic authentication  { if (!strcmp(soap->userid, userid) && !strcmp(soap->passwd, passwd))    { ... // can also check soap->authrealm       return SOAP_OK;    }  }  else if (soap->authrealm && soap->userid) // Digest authentication  { passwd = ... // database lookup on userid and authrealm to find passwd    if (!strcmp(soap->authrealm, authrealm) && !strcmp(soap->userid, userid))    { if (!http_da_verify_post(soap, passwd)) // HTTP POST DA verification      { ...        return SOAP_OK;      }    }  }  soap->authrealm = authrealm; // realm to send to client  return 401; // Not authorized, challenge with digest authentication}Compile with -DWITH_OPENSSLLink with OpenSSL (for md5evp.c), httpda.c, md5evp.c, and threads.cgSOAP XML Web services toolsCopyright (C) 2000-2005, Robert van Engelen, Genivia Inc., All Rights Reserved.This part of the software is released under one of the following licenses:GPL, the gSOAP public license, or Genivia's license for commercial use.--------------------------------------------------------------------------------gSOAP public license.The contents of this file are subject to the gSOAP Public License Version 1.3(the "License"); you may not use this file except in compliance with theLicense. You may obtain a copy of the License athttp://www.cs.fsu.edu/~engelen/soaplicense.htmlSoftware distributed under the License is distributed on an "AS IS" basis,WITHOUT WARRANTY OF ANY KIND, either express or implied. See the Licensefor the specific language governing rights and limitations under the License.The Initial Developer of the Original Code is Robert A. van Engelen.Copyright (C) 2000-2005, Robert van Engelen, Genivia, Inc., All Rights Reserved.--------------------------------------------------------------------------------GPL license.This program is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the Free SoftwareFoundation; either version 2 of the License, or (at your option) any laterversion.This program is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE. See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along withthis program; if not, write to the Free Software Foundation, Inc., 59 TemplePlace, Suite 330, Boston, MA 02111-1307 USAAuthor contact information:engelen@genivia.com / engelen@acm.org--------------------------------------------------------------------------------A commercial use license is available from Genivia, Inc., contact@genivia.com--------------------------------------------------------------------------------*/#include "httpda.h"const char http_da_id[12] = HTTP_DA_ID;/* session database and lock */static struct http_da_session *http_da_session = NULL;static MUTEX_TYPE http_da_session_lock;#define HTTP_DA_NONCELEN 21#define HTTP_DA_OPAQUELEN 9/******************************************************************************\ * *	Forward decls *\******************************************************************************/static int http_da_init(struct soap *soap, struct http_da_data *data);static int http_da_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src);static void http_da_delete(struct soap *soap, struct soap_plugin *p);static int http_da_post_header(struct soap *soap, const char *key, const char *val);static int http_da_parse_header(struct soap *soap, const char *key, const char *val);static int http_da_prepareinit(struct soap *soap);static int http_da_preparesend(struct soap *soap, const char *buf, size_t len);static int http_da_preparerecv(struct soap *soap, const char *buf, size_t len);static int http_da_disconnect(struct soap *soap);static int http_da_verify_method(struct soap *soap, char *method, char *passwd);static void http_da_session_start(const char *realm, const char *nonce, const char *opaque);static int http_da_session_update(const char *realm, const char *nonce, const char *opaque, const char *cnonce, const char *ncount);static void http_da_session_cleanup();void http_da_calc_nonce(struct soap *soap, char nonce[HTTP_DA_NONCELEN]);void http_da_calc_opaque(struct soap *soap, char opaque[HTTP_DA_OPAQUELEN]);static void http_da_calc_HA1(struct soap *soap, void **context, char *alg, char *userid, char *realm, char *passwd, char *nonce, char *cnonce, char HA1hex[33]);static void http_da_calc_response(struct soap *soap, void **context, char HA1hex[33], char *nonce, char *ncount, char *cnonce, char *qop, char *method, char *uri, char entityHAhex[33], char response[33]);/******************************************************************************\ * *	Plugin registry *\******************************************************************************/int http_da(struct soap *soap, struct soap_plugin *p, void *arg){  p->id = http_da_id;  p->data = (void*)SOAP_MALLOC(soap, sizeof(struct http_da_data));  p->fcopy = http_da_copy;  p->fdelete = http_da_delete;  if (p->data)  {    if (http_da_init(soap, (struct http_da_data*)p->data))    {      SOAP_FREE(soap, p->data);      return SOAP_EOM;    }  }  return SOAP_OK;}static int http_da_init(struct soap *soap, struct http_da_data *data){  data->fposthdr = soap->fposthdr;  soap->fposthdr = http_da_post_header;  data->fparsehdr = soap->fparsehdr;  soap->fparsehdr = http_da_parse_header;  data->fprepareinit = soap->fprepareinit;  soap->fprepareinit = http_da_prepareinit;  data->context = NULL;  memset(data->digest, 0, sizeof(data->digest));  return SOAP_OK;}static int http_da_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src){  *dst = *src;  dst->data = (void*)SOAP_MALLOC(soap, sizeof(struct http_da_data));  memcpy(dst->data, src->data, sizeof(struct http_da_data));  ((struct http_da_data*)dst->data)->context = NULL;  memset(((struct http_da_data*)dst->data)->digest, 0, sizeof(((struct http_da_data*)dst->data)->digest));  ((struct http_da_data*)dst->data)->nonce = NULL;  ((struct http_da_data*)dst->data)->opaque = NULL;  ((struct http_da_data*)dst->data)->qop = NULL;  ((struct http_da_data*)dst->data)->alg = NULL;  ((struct http_da_data*)dst->data)->nc = 0;  ((struct http_da_data*)dst->data)->ncount = NULL;  ((struct http_da_data*)dst->data)->cnonce = NULL;  ((struct http_da_data*)dst->data)->response = NULL;  return SOAP_OK;}static void http_da_delete(struct soap *soap, struct soap_plugin *p){  struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id);  if (data)  {    if (data->context)      md5_handler(soap, &data->context, MD5_DELETE, NULL, 0);    SOAP_FREE(soap, data);  }}/******************************************************************************\ * *	Callbacks *\******************************************************************************/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);    if (qop)      sprintf(soap->tmpbuf, "Digest realm=\"%s\", username=\"%s\", nonce=\"%s\", uri=\"%s\", qop=\"%s\", nc=%s, cnonce=\"%s\", response=\"%s\", opaque=\"%s\"", soap->authrealm, soap->userid, data->nonce, soap->path, qop, ncount, cnonce, response, data->opaque);    else      sprintf(soap->tmpbuf, "Digest realm=\"%s\", username=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\", opaque=\"%s\"", soap->authrealm, soap->userid, data->nonce, soap->path, response, data->opaque);    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_parse_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;  /* check if server received Authorization Digest HTTP header from client */  if (!soap_tag_cmp(key, "Authorization") && !soap_tag_cmp(val, "Digest *"))  {    soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "realm"));    soap->userid = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "username"));    soap->passwd = NULL;    data->nonce = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "nonce"));    data->opaque = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "opaque"));    data->qop = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "qop"));    data->alg = NULL;    data->ncount = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "nc"));    data->cnonce = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "cnonce"));    data->response = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "response"));    if (data->qop && !soap_tag_cmp(data->qop, "auth-int"))    {      if (soap->fpreparerecv != http_da_preparerecv)      {        data->fpreparerecv = soap->fpreparerecv;        soap->fpreparerecv = http_da_preparerecv;      }      if (soap->fdisconnect != http_da_disconnect)      {        data->fdisconnect = soap->fdisconnect;        soap->fdisconnect = http_da_disconnect;      }      md5_handler(soap, &data->context, MD5_INIT, NULL, 0);    }    return SOAP_OK;  }  /* check if client received WWW-Authenticate Digest HTTP header from server */  if (!soap_tag_cmp(key, "WWW-Authenticate") && !soap_tag_cmp(val, "Digest *"))  {    soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "realm"));    data->nonce = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "nonce"));    data->opaque = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "opaque"));    data->qop = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "qop"));    data->alg = soap_strdup(soap, soap_get_header_attribute(soap, val + 7, "algorithm"));    data->nc = 1;    data->ncount = NULL;    data->cnonce = NULL;    data->response = NULL;    return SOAP_OK;  }  return data->fparsehdr(soap, key, val);}static int http_da_prepareinit(struct soap *soap){  struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id);  if (!data)    return SOAP_PLUGIN_ERROR;  if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MIME)))  { /* TODO: handle attachments automatically, does not work yet */    soap->mode &= ~SOAP_IO;    soap->mode |= SOAP_IO_STORE;  }  else  {    if (soap->fpreparerecv == http_da_preparerecv)      soap->fpreparerecv = data->fpreparerecv;    if (soap->fdisconnect == http_da_disconnect)      soap->fdisconnect = data->fdisconnect;    if (soap->userid && soap->passwd)    {      md5_handler(soap, &data->context, MD5_INIT, NULL, 0);      if (soap->fpreparesend != http_da_preparesend)      {        data->fpreparesend = soap->fpreparesend;        soap->fpreparesend = http_da_preparesend;      }    }    if (data->fprepareinit)      return data->fprepareinit(soap);  }  return SOAP_OK;}static int http_da_preparesend(struct soap *soap, const char *buf, size_t len){  struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id);  if (!data)    return SOAP_PLUGIN_ERROR;  md5_handler(soap, &data->context, MD5_UPDATE, (char*)buf, len);  if (data->fpreparesend)    return data->fpreparesend(soap, buf, len);  return SOAP_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -