From 1183312d9d5248a93e28cf55e88ef0c819cc27a0 Mon Sep 17 00:00:00 2001 From: m0gg Date: Fri, 24 Nov 2006 10:54:03 +0000 Subject: Message signature with xmlsec1 --- configure | 45 ++++++++++++- configure.ac | 9 ++- examples/csoap/simpleserver.c | 4 +- libcsoap/Makefile.am | 5 ++ libcsoap/soap-addressing.c | 33 +++++++++- libcsoap/soap-addressing.h | 5 +- libcsoap/soap-env.c | 22 +++---- libcsoap/soap-fault.c | 22 +++---- libcsoap/soap-server.c | 145 ++++++++++++++++++++++++++++-------------- nanohttp/nanohttp-server.c | 4 +- 10 files changed, 210 insertions(+), 84 deletions(-) diff --git a/configure b/configure index b07eb95..f8fd081 100755 --- a/configure +++ b/configure @@ -464,7 +464,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL csoap_major csoap_minor csoap_patch csoap_release csoap_version nanohttp_release nanohttp_version LIBOBJS LIBUUID acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS LIBSOCKET LIBNSL XML2_CONFIG XML_CPPFLAGS XML_LIBS XMLSEC1_CONFIG XMLSEC1_CFLAGS XMLSEC1_LIBS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL csoap_major csoap_minor csoap_patch csoap_release csoap_version nanohttp_release nanohttp_version LIBOBJS LIBUUID acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS LIBSOCKET LIBNSL XML2_CONFIG XML_CPPFLAGS XML_LIBS BUILD_WITH_XMLSEC1_TRUE BUILD_WITH_XMLSEC1_FALSE XMLSEC1_CONFIG XMLSEC1_CFLAGS XMLSEC1_LIBS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -22039,7 +22039,20 @@ echo "${ECHO_T}yes (version $xmlsec1_config_major_version.$xmlsec1_config_minor_ cat >>confdefs.h <<\_ACEOF #define HAVE_XMLSEC1 1 _ACEOF - CFLAGS="$CFLAGS $XMLSEC1_CPPFLAGS"; LDFLAGS="$LDFLAGS $XMLSEC1_LIBS" + + + +if true; then + BUILD_WITH_XMLSEC1_TRUE= + BUILD_WITH_XMLSEC1_FALSE='#' +else + BUILD_WITH_XMLSEC1_TRUE='#' + BUILD_WITH_XMLSEC1_FALSE= +fi + + CFLAGS="$CFLAGS $XMLSEC1_CFLAGS"; + LDFLAGS="$LDFLAGS $XMLSEC1_LIBS" + else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 @@ -22122,7 +22135,17 @@ rm -f conftest.err conftest.$ac_objext \ XMLSEC1_CFLAGS="" XMLSEC1_LIBS="" - : + + +if false; then + BUILD_WITH_XMLSEC1_TRUE= + BUILD_WITH_XMLSEC1_FALSE='#' +else + BUILD_WITH_XMLSEC1_TRUE='#' + BUILD_WITH_XMLSEC1_FALSE= +fi + + fi @@ -22242,6 +22265,20 @@ echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${BUILD_WITH_XMLSEC1_TRUE}" && test -z "${BUILD_WITH_XMLSEC1_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"BUILD_WITH_XMLSEC1\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"BUILD_WITH_XMLSEC1\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${BUILD_WITH_XMLSEC1_TRUE}" && test -z "${BUILD_WITH_XMLSEC1_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"BUILD_WITH_XMLSEC1\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"BUILD_WITH_XMLSEC1\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files @@ -22864,6 +22901,8 @@ s,@LIBNSL@,$LIBNSL,;t t s,@XML2_CONFIG@,$XML2_CONFIG,;t t s,@XML_CPPFLAGS@,$XML_CPPFLAGS,;t t s,@XML_LIBS@,$XML_LIBS,;t t +s,@BUILD_WITH_XMLSEC1_TRUE@,$BUILD_WITH_XMLSEC1_TRUE,;t t +s,@BUILD_WITH_XMLSEC1_FALSE@,$BUILD_WITH_XMLSEC1_FALSE,;t t s,@XMLSEC1_CONFIG@,$XMLSEC1_CONFIG,;t t s,@XMLSEC1_CFLAGS@,$XMLSEC1_CFLAGS,;t t s,@XMLSEC1_LIBS@,$XMLSEC1_LIBS,;t t diff --git a/configure.ac b/configure.ac index 6bcfcc9..be4e69d 100644 --- a/configure.ac +++ b/configure.ac @@ -377,7 +377,14 @@ CHECK_SSL #--------------------------------------------- # Check xmlsec1 library #--------------------------------------------- -AM_PATH_XMLSEC1(1.2.10,AC_DEFINE(HAVE_XMLSEC1,1,Define to 1 if you have requested --with-xmlsec1) CFLAGS="$CFLAGS $XMLSEC1_CPPFLAGS"; LDFLAGS="$LDFLAGS $XMLSEC1_LIBS",) +AM_PATH_XMLSEC1(1.2.10, + AC_DEFINE(HAVE_XMLSEC1,1,Define to 1 if you have requested --with-xmlsec1) + AM_CONDITIONAL(BUILD_WITH_XMLSEC1, true) + CFLAGS="$CFLAGS $XMLSEC1_CFLAGS"; + LDFLAGS="$LDFLAGS $XMLSEC1_LIBS" +, + AM_CONDITIONAL(BUILD_WITH_XMLSEC1, false) +) AC_OUTPUT(Makefile libcsoap/Makefile diff --git a/examples/csoap/simpleserver.c b/examples/csoap/simpleserver.c index c67d0e5..9a814ea 100644 --- a/examples/csoap/simpleserver.c +++ b/examples/csoap/simpleserver.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: simpleserver.c,v 1.22 2006/11/23 15:27:33 m0gg Exp $ + * $Id: simpleserver.c,v 1.23 2006/11/24 10:54:03 m0gg Exp $ * * CSOAP Project: CSOAP examples project * Copyright (C) 2003-2004 Ferhat Ayaz @@ -77,7 +77,7 @@ main(int argc, char **argv) herror_t err; struct SoapRouter *router; - // hlog_set_level(HLOG_VERBOSE); + hlog_set_level(HLOG_VERBOSE); if ((err = soap_server_init_args(argc, argv)) != H_OK) { diff --git a/libcsoap/Makefile.am b/libcsoap/Makefile.am index a0dc62e..e5518cb 100644 --- a/libcsoap/Makefile.am +++ b/libcsoap/Makefile.am @@ -13,6 +13,11 @@ libcsoap_la_HEADERS=soap-xml.h soap-fault.h soap-env.h soap-service.h \ soap-admin.h soap-addressing.h soap-transport.h \ soap-nudp.h soap-nhttp.h soap-wsil.h +if BUILD_WITH_XMLSEC1 +libcsoap_la_SOURCES+=soap-xmlsec.c +libcsoap_la_HEADERS+=soap-xmlsec.h +endif + libcsoap_la_LDFLAGS= -version-info @csoap_version@ -release @csoap_release@ libcsoap_la_CFLAGS=-I${top_srcdir} -D__CSOAP_INTERNAL=1 diff --git a/libcsoap/soap-addressing.c b/libcsoap/soap-addressing.c index dc75d18..95c47cd 100644 --- a/libcsoap/soap-addressing.c +++ b/libcsoap/soap-addressing.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-addressing.c,v 1.3 2006/11/23 15:27:33 m0gg Exp $ +* $Id: soap-addressing.c,v 1.4 2006/11/24 10:54:03 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2006 Heiko Ronsdorf @@ -83,7 +83,7 @@ _soap_addressing_generate_id(void) { uuid_t uuid; uint32_t status; - char *ret; + char *ret, *buf; uuid_create(&uuid, &status); if (status != uuid_s_ok) @@ -92,12 +92,24 @@ _soap_addressing_generate_id(void) return NULL; } - uuid_to_string(&uuid, &ret, &status); + uuid_to_string(&uuid, &buf, &status); if (status != uuid_s_ok) { log_error2("uuid_to_string failed (%s)", _soap_addressing_uuid_error(status)); return NULL; } + + if (!(ret = (char *)malloc(128))) + { + log_error2("malloc failed (%s)", strerror(errno)); + free(buf); + return NULL; + } + + sprintf(ret, "%s/%s", soap_server_get_name(), buf); + + free(buf); + return ret; } @@ -295,6 +307,8 @@ soap_addressing_set_message_id_string(struct SoapEnv *envelope, xmlChar *id) else tmp = id; + log_verbose2("setting message id = \"%s\"", tmp); + node = _soap_addressing_get_child_element(envelope->header, WSA_MESSAGE_ID); if (node == NULL) node = _soap_addressing_add_node(envelope->header, WSA_MESSAGE_ID, tmp); @@ -431,6 +445,19 @@ soap_addressing_set_from(struct SoapEnv *envelope, xmlNodePtr address) return ret; } +xmlNodePtr +soap_addressing_set_from_string(struct SoapEnv *envelope, const char *from) +{ + xmlURI *uri; + xmlNodePtr ret; + + uri = xmlParseURI(from); + ret = soap_addressing_set_from_address(envelope, uri); + xmlFreeURI(uri); + + return ret; +} + xmlURI * soap_addressing_get_from_address(struct SoapEnv *envelope) { diff --git a/libcsoap/soap-addressing.h b/libcsoap/soap-addressing.h index 224fd33..0893ac5 100644 --- a/libcsoap/soap-addressing.h +++ b/libcsoap/soap-addressing.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-addressing.h,v 1.3 2006/11/23 15:27:33 m0gg Exp $ + * $Id: soap-addressing.h,v 1.4 2006/11/24 10:54:03 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2006 Heiko Ronsdorf @@ -35,7 +35,7 @@ * in a transport-neutral manner. * * @author H. Ronsdorf - * @version $Revision: 1.3 $ + * @version $Revision: 1.4 $ * @see http://www.w3.org/TR/ws-addr-core/ * */ @@ -197,6 +197,7 @@ xmlNodePtr soap_addressing_get_metadata(xmlNodePtr endpoint_reference); xmlNodePtr soap_addressing_set_metadata(xmlNodePtr endpoint_reference, xmlNodePtr parameter); xmlURI *soap_addressing_get_message_id(struct SoapEnv *envelope); +xmlChar *soap_addressing_get_message_id_string(struct SoapEnv *envelope); xmlNodePtr soap_addressing_set_message_id(struct SoapEnv *envelope, xmlURI *id); xmlNodePtr soap_addressing_get_relates_to(struct SoapEnv *envelope); diff --git a/libcsoap/soap-env.c b/libcsoap/soap-env.c index 6bdce39..6abfb1f 100644 --- a/libcsoap/soap-env.c +++ b/libcsoap/soap-env.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-env.c,v 1.24 2006/11/23 15:27:33 m0gg Exp $ +* $Id: soap-env.c,v 1.25 2006/11/24 10:54:03 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -74,11 +74,11 @@ Parameters: "" \ - " " \ - " "\ - " "\ - " " \ - " "\ + "" \ + ""\ + ""\ + "" \ + ""\ "" @@ -96,11 +96,11 @@ Parameters: "" \ - " " \ - " "\ - " <%s xmlns=\"%s\">"\ - " " \ - " "\ + "" \ + ""\ + "<%s xmlns=\"%s\">"\ + "" \ + ""\ "" diff --git a/libcsoap/soap-fault.c b/libcsoap/soap-fault.c index 242a51a..8bb3945 100644 --- a/libcsoap/soap-fault.c +++ b/libcsoap/soap-fault.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-fault.c,v 1.13 2006/11/23 15:27:33 m0gg Exp $ +* $Id: soap-fault.c,v 1.14 2006/11/24 10:54:03 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -59,15 +59,15 @@ Parameters: " SOAP-ENV:encoding=\"%s\"" \ " xmlns:xsi=\"%s\"" \ " xmlns:xsd=\"%s\">" \ - " " \ - " " \ - " "\ - " %s"\ - " %s"\ - " %s"\ - " %s"\ - " " \ - " "\ + "" \ + "" \ + ""\ + "%s"\ + "%s"\ + "%s"\ + "%s"\ + "" \ + ""\ "" @@ -135,7 +135,7 @@ soap_fault_build(int fault_code, const char *fault_string, const char *fault_act if (fault == NULL) { - log_error1("Can not create xml document!"); + log_error1("Cannot create XML document!"); return soap_fault_build(fault_code, "Cannot create fault object in XML", soap_server_get_name(), NULL); } diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c index d8d996d..78114c2 100644 --- a/libcsoap/soap-server.c +++ b/libcsoap/soap-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-server.c,v 1.30 2006/11/23 15:27:33 m0gg Exp $ +* $Id: soap-server.c,v 1.31 2006/11/24 10:54:03 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -53,6 +53,21 @@ #include "soap-addressing.h" #include "soap-transport.h" +#ifdef HAVE_XMLSEC1 +#include "soap-xmlsec.h" +static inline herror_t +_soap_server_xmlsec_sign(struct SoapEnv *envelope) +{ + return soap_xmlsec_sign(envelope); +} +#else +static inline herror_t +_soap_server_xmlsec_sign(struct SoapEnv *envelope) +{ + return H_OK; +} +#endif + #include "soap-server.h" static SoapRouterNode *head = NULL; @@ -92,6 +107,26 @@ _soap_server_env_new_with_fault(const char *fault_string, const char *detail, st return soap_env_new_with_fault(SOAP_FAULT_RECEIVER, fault_string, soap_server_get_name(), detail, out); } +static void +_soap_server_fillup_header(struct SoapEnv *envelope) +{ + xmlURI *uri; + + log_verbose1(__FUNCTION__); + + if (!(uri = soap_addressing_get_message_id(envelope))) + soap_addressing_set_message_id_string(envelope, NULL); + else + xmlFreeURI(uri); + + if (!(uri = soap_addressing_get_from(envelope))) + soap_addressing_set_from_string(envelope, soap_server_get_name()); + else + xmlFreeURI(uri); + + return; +} + struct SoapRouter * soap_server_find_router(const char *context) { @@ -122,63 +157,67 @@ soap_server_process(struct SoapCtx *request, struct SoapCtx **response) *response = soap_ctx_new(NULL); - if (!(method = soap_env_find_methodname(request->env))) + if ((method = soap_env_find_methodname(request->env))) { - _soap_server_env_new_with_fault("No method found", "The method is missing in the SOAP envelope", &((*response)->env)); - return H_OK; - } - log_verbose2("method: \"%s\"", method); - - if (!(urn = soap_env_find_urn(request->env))) - { - _soap_server_env_new_with_fault("No URN found", "The URN is missing in the SOAP envelope", &((*response)->env)); - return H_OK; - } - log_verbose2("urn: \"%s\"", urn); - - if ((to = soap_addressing_get_to_address_string(request->env))) - { - if (!(router = soap_server_find_router(to))) + log_verbose2("method: \"%s\"", method); + if ((urn = soap_env_find_urn(request->env))) + { + log_verbose2("urn: \"%s\"", urn); + if ((to = soap_addressing_get_to_address_string(request->env))) + { + if ((router = soap_server_find_router(to))) + { + log_verbose2("router: %p", router); + if ((service = soap_router_find_service(router, urn, method))) + { + log_verbose3("service (%p) found, function (%p)", service, service->func); + if ((err = service->func(request, *response)) == H_OK) + { + if ((*response)->env == NULL) + { + sprintf(buffer, "Service \"%s\" returned no envelope", urn); + _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env)); + } + } + else + { + sprintf(buffer, "Service returned following error message: \"%s\"", herror_message(err)); + herror_release(err); + _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env)); + } + } + else + { + sprintf(buffer, "no service for URN \"%s\" found", urn); + _soap_server_env_new_with_fault(buffer, "The URN is not known by the server", &((*response)->env)); + } + } + else + { + sprintf(buffer, "no router for context \"%s\" found", to); + _soap_server_env_new_with_fault(buffer, "The method is unknown by the server", &((*response)->env)); + free(to); + } + free(to); + } + else + { + _soap_server_env_new_with_fault(buffer, "The destination address is missing", &((*response)->env)); + } + } + else { - sprintf(buffer, "no router for context \"%s\" found", to); - _soap_server_env_new_with_fault(buffer, "The method is unknown by the server", &((*response)->env)); - free(to); - return H_OK; + _soap_server_env_new_with_fault("No method found", "The method is missing in the SOAP envelope", &((*response)->env)); } - free(to); } else { - _soap_server_env_new_with_fault(buffer, "The destination address is missing", &((*response)->env)); - return H_OK; - } - log_verbose2("router: %p", router); - - if (!(service = soap_router_find_service(router, urn, method))) - { - sprintf(buffer, "no service for URN \"%s\" found", urn); - _soap_server_env_new_with_fault(buffer, "The URN is not known by the server", &((*response)->env)); - return H_OK; - } - log_verbose2("service found (%p)", service); - - log_verbose2("service function: %p", service->func); - if ((err = service->func(request, *response)) != H_OK) - { - sprintf(buffer, "Service returned following error message: \"%s\"", herror_message(err)); - herror_release(err); - _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env)); - return H_OK; + _soap_server_env_new_with_fault("No URN found", "The URN is missing in the SOAP envelope", &((*response)->env)); } - if ((*response)->env == NULL) - { - sprintf(buffer, "Service \"%s\" returned no envelope", urn); - _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env)); - return H_OK; - } + _soap_server_fillup_header((*response)->env); - return H_OK; + return _soap_server_xmlsec_sign((*response)->env); } herror_t @@ -192,6 +231,14 @@ soap_server_init_args(int argc, char **argv) return status; } +#ifdef HAVE_XMLSEC1 + if ((status = soap_xmlsec_init_args(argc, argv)) != H_OK) + { + log_error2("soap_xmlsec_init_args failed (%s)", herror_message(status)); + return status; + } +#endif + return H_OK; } diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index 45b9348..f9e56fb 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.65 2006/11/23 15:27:33 m0gg Exp $ +* $Id: nanohttp-server.c,v 1.66 2006/11/24 10:54:03 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -654,7 +654,7 @@ httpd_session_main(void *data) { char *conn_str; - httpd_request_print(req); + _httpd_request_print(req); conn_str = hpairnode_get_ignore_case(req->header, HEADER_CONNECTION); if (conn_str && strncasecmp(conn_str, "close", 6) == 0) -- cgit v1.1-32-gdbae