diff options
Diffstat (limited to 'examples/xkms-server.c')
-rw-r--r-- | examples/xkms-server.c | 447 |
1 files changed, 232 insertions, 215 deletions
diff --git a/examples/xkms-server.c b/examples/xkms-server.c index 1021b182..188d5c73 100644 --- a/examples/xkms-server.c +++ b/examples/xkms-server.c @@ -4,10 +4,10 @@ * Starts XKMS server on specified port. * * Usage: - * ./xkms-server [--port <port>] [--format plain|soap-1.1|soap-1.2] <keys-file> + * ./xkms-server [--port <port>] [--format plain|soap-1.1|soap-1.2] <keys-file> * * Example: - * ./xkms-server --port 8080 --format soap-1.1 keys.xml + * ./xkms-server --port 8080 --format soap-1.1 keys.xml * * This is free software; see Copyright file in the source * distribution for preciese wording. @@ -23,8 +23,8 @@ #ifdef XMLSEC_NO_XKMS int main(int argc, char** argv) { - fprintf(stderr, "ERROR: XKMS is disabled.\n"); - return 1; + fprintf(stderr, "ERROR: XKMS is disabled.\n"); + return 1; } #else /* XMLSEC_NO_XKMS */ @@ -35,6 +35,7 @@ int main(int argc, char** argv) { #ifndef XMLSEC_NO_XSLT #include <libxslt/xslt.h> +#include <libxslt/security.h> #endif /* XMLSEC_NO_XSLT */ #include <xmlsec/xmlsec.h> @@ -64,13 +65,13 @@ int main(int argc, char** argv) { #endif /* WIN32_SOCKETS */ #endif /* UNIX_SOCKETS */ -#define DEFAULT_PORT 1234 -#define PENDING_QUEUE_SIZE 100 +#define DEFAULT_PORT 1234 +#define PENDING_QUEUE_SIZE 100 -#define LOG_LEVEL_SILENT 0 -#define LOG_LEVEL_INFO 1 -#define LOG_LEVEL_DATA 2 -#define LOG_LEVEL_DEBUG 3 +#define LOG_LEVEL_SILENT 0 +#define LOG_LEVEL_INFO 1 +#define LOG_LEVEL_DATA 2 +#define LOG_LEVEL_DEBUG 3 #ifdef UNIX_SOCKETS static int sockfd = -1; @@ -91,7 +92,7 @@ static const xmlChar* my_strnstr(const xmlChar* str, xmlSecSize strLen, const xm static int handle_connection(int fd, xmlSecXkmsServerCtxPtr xkmsCtx, xmlSecXkmsServerFormat format); static int read_request(int fd, const char* in_ip, xmlSecBufferPtr buffer); static int send_response(int fd, const char* in_ip, int resp_code, - const char* body, int body_size); + const char* body, int body_size); static char usage[] = "[--port <port>] [--format plain|soap-1.1|soap-1.2] <keys-file>"; static char http_header[] = @@ -105,6 +106,9 @@ static char http_503[] = int main(int argc, char** argv) { int argpos; unsigned short port = DEFAULT_PORT; +#ifndef XMLSEC_NO_XSLT + xsltSecurityPrefsPtr xsltSecPrefs = NULL; +#endif /* XMLSEC_NO_XSLT */ xmlSecKeysMngrPtr mngr = NULL; xmlSecXkmsServerCtxPtr xkmsCtx = NULL; xmlSecXkmsServerFormat format = xmlSecXkmsServerFormatPlain; @@ -120,17 +124,29 @@ int main(int argc, char** argv) { #ifndef XMLSEC_NO_XSLT xmlIndentTreeOutput = 1; #endif /* XMLSEC_NO_XSLT */ - + + /* Init libxslt */ +#ifndef XMLSEC_NO_XSLT + /* disable everything */ + xsltSecPrefs = xsltNewSecurityPrefs(); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid); + xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid); + xsltSetDefaultSecurityPrefs(xsltSecPrefs); +#endif /* XMLSEC_NO_XSLT */ + /* Init xmlsec library */ if(xmlSecInit() < 0) { - fprintf(stderr, "Error %d: xmlsec initialization failed.\n", errno); - return(-1); + fprintf(stderr, "Error %d: xmlsec initialization failed.\n", errno); + return(-1); } /* Check loaded library version */ if(xmlSecCheckVersion() != 1) { - fprintf(stderr, "Error %d: loaded xmlsec library version is not compatible.\n", errno); - return(-1); + fprintf(stderr, "Error %d: loaded xmlsec library version is not compatible.\n", errno); + return(-1); } /* Load default crypto engine if we are supporting dynamic @@ -140,115 +156,115 @@ int main(int argc, char** argv) { */ #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) { - fprintf(stderr, "Error %d: unable to load default xmlsec-crypto library. Make sure\n" - "that you have it installed and check shared libraries path\n" - "(LD_LIBRARY_PATH) envornment variable.\n", errno); - return(-1); + fprintf(stderr, "Error %d: unable to load default xmlsec-crypto library. Make sure\n" + "that you have it installed and check shared libraries path\n" + "(LD_LIBRARY_PATH) envornment variable.\n", errno); + return(-1); } #endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */ /* Init crypto library */ if(xmlSecCryptoAppInit(NULL) < 0) { - fprintf(stderr, "Error %d: crypto initialization failed.\n", errno); - return(-1); + fprintf(stderr, "Error %d: crypto initialization failed.\n", errno); + return(-1); } /* Init xmlsec-crypto library */ if(xmlSecCryptoInit() < 0) { - fprintf(stderr, "Error %d: xmlsec-crypto initialization failed.\n", errno); - return(-1); + fprintf(stderr, "Error %d: xmlsec-crypto initialization failed.\n", errno); + return(-1); } /* Create and initialize keys manager */ mngr = xmlSecKeysMngrCreate(); if(mngr == NULL) { - fprintf(stderr, "Error %d: failed to create keys manager.\n", errno); - goto done; + fprintf(stderr, "Error %d: failed to create keys manager.\n", errno); + goto done; } if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) { - fprintf(stderr, "Error %d: failed to initialize keys manager.\n", errno); - goto done; + fprintf(stderr, "Error %d: failed to initialize keys manager.\n", errno); + goto done; } /* Create XKMS server context */ xkmsCtx = xmlSecXkmsServerCtxCreate(mngr); if(xkmsCtx == NULL) { - fprintf(stderr, "Error %d: XKMS server context initialization failed\n", errno); - goto done; + fprintf(stderr, "Error %d: XKMS server context initialization failed\n", errno); + goto done; } /* Process input parameters */ for(argpos = 1; (argpos < argc) && (argv[argpos][0] == '-'); argpos++) { - if((strcmp(argv[argpos], "--port") == 0) || (strcmp(argv[argpos], "-p") == 0)) { - argpos++; - port = atoi(argv[argpos]); - if(port == 0) { - fprintf(stderr, "Error %d: invalid port number \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); - goto done; - } - } else if((strcmp(argv[argpos], "--format") == 0) || (strcmp(argv[argpos], "-f") == 0)) { - argpos++; - format = xmlSecXkmsServerFormatFromString(BAD_CAST argv[argpos]); - if(format == xmlSecXkmsServerFormatUnknown) { - fprintf(stderr, "Error %d: invalid format \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); - goto done; - } - } else if((strcmp(argv[argpos], "--log-level") == 0) || (strcmp(argv[argpos], "-l") == 0)) { - argpos++; - log_level = atoi(argv[argpos]); - } else { - fprintf(stderr, "Error %d: unknown parameter \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); - goto done; - } + if((strcmp(argv[argpos], "--port") == 0) || (strcmp(argv[argpos], "-p") == 0)) { + argpos++; + port = atoi(argv[argpos]); + if(port == 0) { + fprintf(stderr, "Error %d: invalid port number \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); + goto done; + } + } else if((strcmp(argv[argpos], "--format") == 0) || (strcmp(argv[argpos], "-f") == 0)) { + argpos++; + format = xmlSecXkmsServerFormatFromString(BAD_CAST argv[argpos]); + if(format == xmlSecXkmsServerFormatUnknown) { + fprintf(stderr, "Error %d: invalid format \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); + goto done; + } + } else if((strcmp(argv[argpos], "--log-level") == 0) || (strcmp(argv[argpos], "-l") == 0)) { + argpos++; + log_level = atoi(argv[argpos]); + } else { + fprintf(stderr, "Error %d: unknown parameter \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); + goto done; + } } if(argpos >= argc) { - fprintf(stderr, "Error %d: keys file is not specified.\nUsage: %s %s\n", errno, argv[0], usage); - goto done; + fprintf(stderr, "Error %d: keys file is not specified.\nUsage: %s %s\n", errno, argv[0], usage); + goto done; } /* Load keys */ for(; argpos < argc; argpos++) { if(xmlSecCryptoAppDefaultKeysMngrLoad(mngr, argv[argpos]) < 0) { - fprintf(stderr, "Error %d: failed to load xml keys file \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); - goto done; - } - if(log_level >= LOG_LEVEL_INFO) { - fprintf(stdout, "Log: loaded keys from \"%s\"\n", argv[argpos]); - } + fprintf(stderr, "Error %d: failed to load xml keys file \"%s\".\nUsage: %s %s\n", errno, argv[argpos], argv[0], usage); + goto done; + } + if(log_level >= LOG_LEVEL_INFO) { + fprintf(stdout, "Log: loaded keys from \"%s\"\n", argv[argpos]); + } } /* Startup TCP server */ if(init_server(port) < 0) { - fprintf(stderr, "Error, errno: server initialization failed\n", errno); - goto done; + fprintf(stderr, "Error, errno: server initialization failed\n", errno); + goto done; } assert(sockfd != -1); /* main loop: accept connections and process requests */ while(finished == 0) { - fd_set fds; + fd_set fds; struct timeval timeout; - - /* Set up polling using select() */ - FD_ZERO(&fds); - FD_SET(sockfd, &fds); - memset(&timeout, 0, sizeof(timeout)); - timeout.tv_sec = 1; - ret = select(sockfd + 1, &fds, NULL, NULL, &timeout); - if((ret <= 0) || !FD_ISSET(sockfd, &fds)) { - /* error, timed out or not our socket: try again */ - continue; - } - - if(handle_connection(sockfd, xkmsCtx, format) < 0) { - fprintf(stderr, "Error %d: unable to accept incomming connection\n"); - goto done; - } + + /* Set up polling using select() */ + FD_ZERO(&fds); + FD_SET(sockfd, &fds); + memset(&timeout, 0, sizeof(timeout)); + timeout.tv_sec = 1; + ret = select(sockfd + 1, &fds, NULL, NULL, &timeout); + if((ret <= 0) || !FD_ISSET(sockfd, &fds)) { + /* error, timed out or not our socket: try again */ + continue; + } + + if(handle_connection(sockfd, xkmsCtx, format) < 0) { + fprintf(stderr, "Error %d: unable to accept incomming connection\n"); + goto done; + } } done: if(log_level >= LOG_LEVEL_INFO) { - fprintf(stdout, "Log: server is shutting down\n"); + fprintf(stdout, "Log: server is shutting down\n"); } /* Shutdown TCP server */ @@ -256,14 +272,14 @@ done: /* Destroy xkms server context */ if(xkmsCtx != NULL) { - xmlSecXkmsServerCtxDestroy(xkmsCtx); - xkmsCtx = NULL; + xmlSecXkmsServerCtxDestroy(xkmsCtx); + xkmsCtx = NULL; } /* Destroy keys manager */ if(mngr != NULL) { xmlSecKeysMngrDestroy(mngr); - mngr = NULL; + mngr = NULL; } /* Shutdown xmlsec-crypto library */ @@ -277,6 +293,7 @@ done: /* Shutdown libxslt/libxml */ #ifndef XMLSEC_NO_XSLT + xsltFreeSecurityPrefs(xsltSecPrefs); xsltCleanupGlobals(); #endif /* XMLSEC_NO_XSLT */ xmlCleanupParser(); @@ -287,7 +304,7 @@ done: /** * init_server: - * @port: the server'xmlSecBufferGetData(buffer) TCP port number. + * @port: the server'xmlSecBufferGetData(buffer) TCP port number. * * Starts up a TCP server listening on given @port. * @@ -303,8 +320,8 @@ init_server(unsigned short port) { #ifdef WIN32_SOCKETS if(WSAStartup(MAKEWORD(1,1), &data)) { - fprintf(stderr, "Error %d: WSAStartup() failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: WSAStartup() failed\n", errno); + return(-1); } #endif /* WIN32_SOCKETS */ @@ -318,44 +335,44 @@ init_server(unsigned short port) { if(sockfd == INVALID_SOCKET) { #endif /* WIN32_SOCKETS */ - fprintf(stderr, "Error %d: socket() failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: socket() failed\n", errno); + return(-1); } /* enable reuse of address */ flags = 1; if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&flags, sizeof(flags)) != 0) { - fprintf(stderr, "Error %d: setsockopt(SO_REUSEADDR) failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: setsockopt(SO_REUSEADDR) failed\n", errno); + return(-1); } #ifdef UNIX_SOCKETS /* set non-blocking */ flags = fcntl(sockfd, F_GETFL); if(flags < 0) { - fprintf(stderr, "Error %d: fcntl(F_GETFL) failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: fcntl(F_GETFL) failed\n", errno); + return(-1); } if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) { - fprintf(stderr, "Error %d: fcntl(F_SETFL) failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: fcntl(F_SETFL) failed\n", errno); + return(-1); } #endif /* UNIX_SOCKETS */ /* preset socket structure for socket binding */ memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(port); - saddr.sin_addr.s_addr = INADDR_ANY; + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + saddr.sin_addr.s_addr = INADDR_ANY; if(bind(sockfd, (struct sockaddr *)&saddr, sizeof(struct sockaddr)) != 0) { - fprintf(stderr, "Error %d: bind() failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: bind() failed\n", errno); + return(-1); } /* prepare for listening */ if(listen(sockfd, PENDING_QUEUE_SIZE) != 0) { - fprintf(stderr, "Error %d: listen() failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: listen() failed\n", errno); + return(-1); } #ifdef UNIX_SOCKETS @@ -386,8 +403,8 @@ stop_server() { #ifdef WIN32_SOCKETS if(sockfd != -1) { - close(sockfd); - sockfd = -1; + close(sockfd); + sockfd = -1; } #endif /* WIN32_SOCKETS */ if(log_level >= LOG_LEVEL_INFO) { @@ -397,7 +414,7 @@ stop_server() { /** * int_signal_handler: - * @sig_num: the signal number. + * @sig_num: the signal number. * * Unix's Ctrl-C signal handler that stops the server. */ @@ -411,9 +428,9 @@ int_signal_handler(int sig_num) { /** * handle_connection: - * @sockfd: the server's socket. - * @xkmsCtx: the template XKMS server context. - * @format: the expected format of XKMS requests. + * @sockfd: the server's socket. + * @xkmsCtx: the template XKMS server context. + * @format: the expected format of XKMS requests. * * Establishs a connection, forks a child process (onUnix), reads the request, * processes it and writes back the response. @@ -457,8 +474,8 @@ handle_connection(int sockfd, xmlSecXkmsServerCtxPtr xkmsCtx, xmlSecXkmsServerFo if(sockfd == INVALID_SOCKET) { #endif /* WIN32_SOCKETS */ - fprintf(stderr, "Error %d: accept() failed\n", errno); - return(-1); + fprintf(stderr, "Error %d: accept() failed\n", errno); + return(-1); } if(log_level >= LOG_LEVEL_INFO) { fprintf(stdout, "Log [%s]: got connection\n", inet_ntoa(saddr.sin_addr)); @@ -467,19 +484,19 @@ handle_connection(int sockfd, xmlSecXkmsServerCtxPtr xkmsCtx, xmlSecXkmsServerFo /* Create a copy of XKMS server context */ xkmsCtx2 = xmlSecXkmsServerCtxCreate(NULL); if(xkmsCtx2 == NULL) { - fprintf(stderr, "Error %d [%s]: a copy of XKMS server context initialization failed\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: a copy of XKMS server context initialization failed\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } if(xmlSecXkmsServerCtxCopyUserPref(xkmsCtx2, xkmsCtx) < 0) { - fprintf(stderr, "Error %d [%s]: XKMS server context copy failed\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: XKMS server context copy failed\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } #ifdef UNIX_SOCKETS /* on Unix we use child process to process requests */ if(fork()) { - /* parent process */ - return(0); + /* parent process */ + return(0); } /* child process */ @@ -489,36 +506,36 @@ handle_connection(int sockfd, xmlSecXkmsServerCtxPtr xkmsCtx, xmlSecXkmsServerFo buffer = xmlSecBufferCreate(0); if(buffer == NULL) { - fprintf(stderr, "Error %d [%s]: xmlSecBufferCreate() failed\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: xmlSecBufferCreate() failed\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } /* read input request */ ret = read_request(fd, inet_ntoa(saddr.sin_addr), buffer); if(ret < 0) { - fprintf(stderr, "Error %d [%s]: read_request() failed\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: read_request() failed\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } /* parse request */ inDoc = xmlParseMemory(xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer) ); if((inDoc == NULL) || (xmlDocGetRootElement(inDoc) == NULL)) { - fprintf(stderr, "Error %d [%s]: failed to parse request\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: failed to parse request\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } xmlSecBufferEmpty(buffer); /* prepare result document */ outDoc = xmlNewDoc(BAD_CAST "1.0"); if(outDoc == NULL) { - fprintf(stderr, "Error %d [%s]: failed to create result doc\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: failed to create result doc\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } result = xmlSecXkmsServerCtxProcess(xkmsCtx2, xmlDocGetRootElement(inDoc), format, outDoc); if(result == NULL) { - fprintf(stderr, "Error %d [%s]: failed to process xkms server request\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: failed to process xkms server request\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } /* apppend returned result node to the output document */ @@ -527,8 +544,8 @@ handle_connection(int sockfd, xmlSecXkmsServerCtxPtr xkmsCtx, xmlSecXkmsServerFo /* create LibXML2 output buffer */ output = xmlSecBufferCreateOutputBuffer(buffer); if(output == NULL) { - fprintf(stderr, "Error %d [%s]: xmlSecBufferCreateOutputBuffer() failed\n", errno, inet_ntoa(saddr.sin_addr)); - goto done; + fprintf(stderr, "Error %d [%s]: xmlSecBufferCreateOutputBuffer() failed\n", errno, inet_ntoa(saddr.sin_addr)); + goto done; } xmlNodeDumpOutput(output, result->doc, result, 0, 0, NULL); @@ -537,72 +554,72 @@ handle_connection(int sockfd, xmlSecXkmsServerCtxPtr xkmsCtx, xmlSecXkmsServerFo done: /* send back response */ if((resp_ready == 1) && (xmlSecBufferGetData(buffer) != NULL)) { - ret = send_response(fd, inet_ntoa(saddr.sin_addr), 200, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer)); - if(log_level >= LOG_LEVEL_INFO) { - fprintf(stdout, "Log [%s]: processed request\n", inet_ntoa(saddr.sin_addr)); - } + ret = send_response(fd, inet_ntoa(saddr.sin_addr), 200, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer)); + if(log_level >= LOG_LEVEL_INFO) { + fprintf(stdout, "Log [%s]: processed request\n", inet_ntoa(saddr.sin_addr)); + } } else if(fd >= 0) { - ret = send_response(fd, inet_ntoa(saddr.sin_addr), 503, http_503, strlen(http_503)); + ret = send_response(fd, inet_ntoa(saddr.sin_addr), 503, http_503, strlen(http_503)); if(log_level >= LOG_LEVEL_INFO) { - fprintf(stdout, "Log [%s]: failed to process request\n", inet_ntoa(saddr.sin_addr)); - } + fprintf(stdout, "Log [%s]: failed to process request\n", inet_ntoa(saddr.sin_addr)); + } } else { - ret = -1; + ret = -1; } if(ret < 0) { - fprintf(stderr, "Error %d [%s]: send_response() failed\n", errno, inet_ntoa(saddr.sin_addr)); + fprintf(stderr, "Error %d [%s]: send_response() failed\n", errno, inet_ntoa(saddr.sin_addr)); } /* cleanup */ if(output != NULL) { - xmlOutputBufferClose(output); - output = NULL; + xmlOutputBufferClose(output); + output = NULL; } if(outDoc != NULL) { - xmlFreeDoc(outDoc); - outDoc = NULL; + xmlFreeDoc(outDoc); + outDoc = NULL; } if(inDoc != NULL) { - xmlFreeDoc(inDoc); - inDoc = NULL; + xmlFreeDoc(inDoc); + inDoc = NULL; } if(buffer != NULL) { - xmlSecBufferDestroy(buffer); - buffer = NULL; + xmlSecBufferDestroy(buffer); + buffer = NULL; } if(xkmsCtx2 != NULL) { - xmlSecXkmsServerCtxDestroy(xkmsCtx2); - xkmsCtx2 = NULL; + xmlSecXkmsServerCtxDestroy(xkmsCtx2); + xkmsCtx2 = NULL; } if(fd >= 0) { #ifdef UNIX_SOCKETS - shutdown(fd, SHUT_RDWR); - close(fd); + shutdown(fd, SHUT_RDWR); + close(fd); #endif /* UNIX_SCOKETS */ #ifdef WIN32_SOCKETS - close(fd); + close(fd); #endif /* WIN32_SCOKETS */ - fd = -1; + fd = -1; } if(in_child_process) { - exit(0); + exit(0); } return(0); } /** * read_request: - * @fd: the request's socket. - * @in_ip: the request's IP address (for logging). - * @buffer: the output buffer. + * @fd: the request's socket. + * @in_ip: the request's IP address (for logging). + * @buffer: the output buffer. * * Reads the request from socket @fd and stores it in the @buffer. * @@ -625,16 +642,16 @@ read_request(int fd, const char* in_ip, xmlSecBufferPtr buffer) { /* first read the http headers */ counter = 5; while(my_strnstr(xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), BAD_CAST "\r\n\r\n", 4) == NULL) { - nread = recv(fd, buf, sizeof(buf), 0); - if(nread < 0) { - fprintf(stderr, "Error %d [%s]: read() failed\n", errno, in_ip); - return(-1); - } + nread = recv(fd, buf, sizeof(buf), 0); + if(nread < 0) { + fprintf(stderr, "Error %d [%s]: read() failed\n", errno, in_ip); + return(-1); + } - if((nread > 0) && (xmlSecBufferAppend(buffer, buf, nread) < 0)) { - fprintf(stderr, "Error %d [%s]: xmlSecBufferAppend(%d) failed\n", errno, in_ip, nread); - return(-1); - } + if((nread > 0) && (xmlSecBufferAppend(buffer, buf, nread) < 0)) { + fprintf(stderr, "Error %d [%s]: xmlSecBufferAppend(%d) failed\n", errno, in_ip, nread); + return(-1); + } if(nread < sizeof(buffer)) { counter--; @@ -646,13 +663,13 @@ read_request(int fd, const char* in_ip, xmlSecBufferPtr buffer) { if(xmlSecBufferGetData(buffer) == NULL) { fprintf(stderr, "Error %d [%s]: no bytes read\n", errno, in_ip); - return(-1); + return(-1); } if(log_level >= LOG_LEVEL_DEBUG) { - xmlSecBufferAppend(buffer, BAD_CAST "\0", 1); + xmlSecBufferAppend(buffer, BAD_CAST "\0", 1); fprintf(stdout, "Debug [%s]: request headers:\n%s\n", in_ip, xmlSecBufferGetData(buffer)); - xmlSecBufferRemoveTail(buffer, 1); + xmlSecBufferRemoveTail(buffer, 1); } /* Parse the request and extract the body. We expect the request to look @@ -660,37 +677,37 @@ read_request(int fd, const char* in_ip, xmlSecBufferPtr buffer) { * POST <path> HTTP/1.x\r\n * <header1>\r\n * <header2>\r\n - * ... + * ... * <headerN>\r\n - * \r\n - * <body> + * \r\n + * <body> */ /* analyze the first line */ p = my_strnstr(xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), BAD_CAST "\r\n", 2); if(p == NULL) { - fprintf(stderr, "Error %d [%s]: there is no HTTP header\n", errno, in_ip); - return(-1); + fprintf(stderr, "Error %d [%s]: there is no HTTP header\n", errno, in_ip); + return(-1); } if(xmlStrncasecmp(xmlSecBufferGetData(buffer), BAD_CAST "POST ", 5) != 0) { - fprintf(stderr, "Error %d [%s]: not a POST request\n", errno, in_ip); - return(-1); + fprintf(stderr, "Error %d [%s]: not a POST request\n", errno, in_ip); + return(-1); } /* "POST " + " HTTP/1.x" == 14 */ s = xmlSecBufferGetData(buffer); if(p - s <= 14) { - fprintf(stderr, "Error %d [%s]: first line has bad length\n", errno, in_ip); - return(-1); + fprintf(stderr, "Error %d [%s]: first line has bad length\n", errno, in_ip); + return(-1); } if((xmlStrncasecmp(p - 9, BAD_CAST " HTTP/1.0", 9) != 0) && (xmlStrncasecmp(p - 9, BAD_CAST " HTTP/1.1", 9) != 0)) { - + fprintf(stderr, "Error %d [%s]: first line does not end with \" HTTP/1.x\"\n", errno, in_ip); - return(-1); + return(-1); } if(xmlSecBufferRemoveHead(buffer, p - xmlSecBufferGetData(buffer) + 2) < 0) { - fprintf(stderr, "Error %d [%s]: failed to skip first line\n", errno, in_ip); - return(-1); + fprintf(stderr, "Error %d [%s]: failed to skip first line\n", errno, in_ip); + return(-1); } /* now skip all the headers (i.e. everything until empty line) */ @@ -699,19 +716,19 @@ read_request(int fd, const char* in_ip, xmlSecBufferPtr buffer) { p = my_strnstr(xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer), BAD_CAST "\r\n", 2); if(p == NULL) { fprintf(stderr, "Error %d [%s]: there is no HTTP body\n", errno, in_ip); - return(-1); - } - - if(p == xmlSecBufferGetData(buffer)) { - found = 1; - } else if(xmlStrncasecmp(xmlSecBufferGetData(buffer), BAD_CAST "Content-length: ", 16) == 0) { - length = atoi(xmlSecBufferGetData(buffer) + 16); - } - - if(xmlSecBufferRemoveHead(buffer, p - xmlSecBufferGetData(buffer) + 2) < 0) { - fprintf(stderr, "Error %d [%s]: failed to skip header line\n", errno, in_ip); - return(-1); - } + return(-1); + } + + if(p == xmlSecBufferGetData(buffer)) { + found = 1; + } else if(xmlStrncasecmp(xmlSecBufferGetData(buffer), BAD_CAST "Content-length: ", 16) == 0) { + length = atoi(xmlSecBufferGetData(buffer) + 16); + } + + if(xmlSecBufferRemoveHead(buffer, p - xmlSecBufferGetData(buffer) + 2) < 0) { + fprintf(stderr, "Error %d [%s]: failed to skip header line\n", errno, in_ip); + return(-1); + } } /* remove the trailing \0 we added */ @@ -720,16 +737,16 @@ read_request(int fd, const char* in_ip, xmlSecBufferPtr buffer) { /* now read the body */ counter = 5; while(xmlSecBufferGetSize(buffer) < length) { - nread = recv(fd, buf, sizeof(buf), 0); - if(nread < 0) { - fprintf(stderr, "Error %d [%s]: read() failed\n", errno, in_ip); - return(-1); - } - - if((nread > 0) && (xmlSecBufferAppend(buffer, buf, nread) < 0)) { - fprintf(stderr, "Error %d [%s]: xmlSecBufferAppend(%d) failed\n", errno, in_ip, nread); - return(-1); - } + nread = recv(fd, buf, sizeof(buf), 0); + if(nread < 0) { + fprintf(stderr, "Error %d [%s]: read() failed\n", errno, in_ip); + return(-1); + } + + if((nread > 0) && (xmlSecBufferAppend(buffer, buf, nread) < 0)) { + fprintf(stderr, "Error %d [%s]: xmlSecBufferAppend(%d) failed\n", errno, in_ip, nread); + return(-1); + } if(nread < sizeof(buffer)) { counter--; if(counter <= 0) { @@ -738,23 +755,23 @@ read_request(int fd, const char* in_ip, xmlSecBufferPtr buffer) { } } if(log_level >= LOG_LEVEL_INFO) { - fprintf(stdout, "Log [%s]: body size is %d bytes\n", in_ip, xmlSecBufferGetSize(buffer)); + fprintf(stdout, "Log [%s]: body size is %d bytes\n", in_ip, xmlSecBufferGetSize(buffer)); } if(log_level >= LOG_LEVEL_DATA) { - xmlSecBufferAppend(buffer, BAD_CAST "\0", 1); + xmlSecBufferAppend(buffer, BAD_CAST "\0", 1); fprintf(stdout, "Log [%s]: request body:\n%s\n", in_ip, xmlSecBufferGetData(buffer)); - xmlSecBufferRemoveTail(buffer, 1); + xmlSecBufferRemoveTail(buffer, 1); } return(0); } /** * send_response: - * @fd: the request's socket. - * @in_ip: the request's IP address (for logging). - * @resp_code: the HTTP response code. - * @body: the response body. - * @body_len: the response body length. + * @fd: the request's socket. + * @in_ip: the request's IP address (for logging). + * @resp_code: the HTTP response code. + * @body: the response body. + * @body_len: the response body length. * * Writes HTTP response headers and @body to the @socket. * @@ -772,20 +789,20 @@ send_response(int fd, const char* in_ip, int resp_code, const char* body, int bo /* prepare and send http header */ sprintf(header, http_header, resp_code, body_size); if(send(fd, header, strlen(header), 0) == -1) { - fprintf(stderr, "Error %d [%s]: send(header) failed\n", errno, in_ip); - return(-1); + fprintf(stderr, "Error %d [%s]: send(header) failed\n", errno, in_ip); + return(-1); } if(log_level >= LOG_LEVEL_DATA) { - xmlChar* tmp = xmlStrndup(body, body_size); + xmlChar* tmp = xmlStrndup(body, body_size); fprintf(stdout, "Log [%s]: response is\n%s\n", in_ip, tmp); - xmlFree(tmp); + xmlFree(tmp); } /* send body */ if(send(fd, body, body_size, 0) == -1) { - fprintf(stderr, "Error %d [%s]: send(body) failed\n", errno, in_ip); - return(-1); + fprintf(stderr, "Error %d [%s]: send(body) failed\n", errno, in_ip); + return(-1); } return(0); |