From 4def48b8811f210ed849f42f908aae0755d40cb8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 24 Apr 2014 20:58:23 +0500 Subject: [PATCH] revert --- src/mod/xml_int/mod_xml_rpc/ws.c | 477 +++++++------------------------ src/mod/xml_int/mod_xml_rpc/ws.h | 60 ++-- 2 files changed, 127 insertions(+), 410 deletions(-) diff --git a/src/mod/xml_int/mod_xml_rpc/ws.c b/src/mod/xml_int/mod_xml_rpc/ws.c index 98c00032cc..7247ddb4ba 100644 --- a/src/mod/xml_int/mod_xml_rpc/ws.c +++ b/src/mod/xml_int/mod_xml_rpc/ws.c @@ -1,18 +1,11 @@ #include "ws.h" -#include #ifndef _MSC_VER #include #endif -#ifndef _MSC_VER -#define ms_sleep(x) usleep( x * 1000); -#else -#define ms_sleep(x) Sleep( x ); -#endif - #define SHA1_HASH_SIZE 20 -struct ws_globals_s ws_globals; +struct globals_s globals; #ifndef WSS_STANDALONE @@ -89,20 +82,20 @@ void init_ssl(void) { OpenSSL_add_all_algorithms(); /* load & register cryptos */ SSL_load_error_strings(); /* load all error messages */ - ws_globals.ssl_method = TLSv1_server_method(); /* create server instance */ - ws_globals.ssl_ctx = SSL_CTX_new(ws_globals.ssl_method); /* create context */ - assert(ws_globals.ssl_ctx); + globals.ssl_method = TLSv1_server_method(); /* create server instance */ + globals.ssl_ctx = SSL_CTX_new(globals.ssl_method); /* create context */ + assert(globals.ssl_ctx); /* set the local certificate from CertFile */ - SSL_CTX_use_certificate_file(ws_globals.ssl_ctx, ws_globals.cert, SSL_FILETYPE_PEM); + SSL_CTX_use_certificate_file(globals.ssl_ctx, globals.cert, SSL_FILETYPE_PEM); /* set the private key from KeyFile */ - SSL_CTX_use_PrivateKey_file(ws_globals.ssl_ctx, ws_globals.key, SSL_FILETYPE_PEM); + SSL_CTX_use_PrivateKey_file(globals.ssl_ctx, globals.key, SSL_FILETYPE_PEM); /* verify private key */ - if ( !SSL_CTX_check_private_key(ws_globals.ssl_ctx) ) { + if ( !SSL_CTX_check_private_key(globals.ssl_ctx) ) { abort(); - } + } - SSL_CTX_set_cipher_list(ws_globals.ssl_ctx, "HIGH:!DSS:!aNULL@STRENGTH"); + SSL_CTX_set_cipher_list(globals.ssl_ctx, "HIGH:!DSS:!aNULL@STRENGTH"); thread_setup(); } @@ -126,28 +119,28 @@ static int cheezy_get_var(char *data, char *name, char *buf, size_t buflen) */ do { - if(!strncmp(p,name,strlen(name)) && *(p+strlen(name))==':') break; + if(!strncmp(p,name,strlen(name)) && *(p+strlen(name))==':') break; } while((p = (strstr(p,"\n")+1))!=(char *)1); if (p != (char *)1 && *p!='\0') { - char *v, *e = 0; + char *v, *e = 0; - v = strchr(p, ':'); - if (v) { - v++; - while(v && *v == ' ') { + v = strchr(p, ':'); + if (v) { + v++; + while(v && *v == ' ') { v++; - } - if (v) { + } + if (v) { e = strchr(v, '\r'); if (!e) { e = strchr(v, '\n'); } - } + } - if (v && e) { - int cplen; + if (v && e) { + size_t cplen; size_t len = e - v; if (len > buflen - 1) { @@ -159,9 +152,9 @@ static int cheezy_get_var(char *data, char *name, char *buf, size_t buflen) strncpy(buf, v, cplen); *(buf+cplen) = '\0'; return 1; - } - - } + } + + } } return 0; } @@ -224,89 +217,44 @@ static void sha1_digest(unsigned char *digest, char *in) #endif -int ws_handshake(wsh_t *wsh) +int ws_handshake_kvp(wsh_t *wsh, char *key, char *version, char *proto) { - char key[256] = ""; - char version[5] = ""; - char proto[256] = ""; - char proto_buf[384] = ""; - char uri[256] = ""; char input[256] = ""; unsigned char output[SHA1_HASH_SIZE] = ""; char b64[256] = ""; char respond[512] = ""; - ssize_t bytes; - char *p, *e = 0; - if (wsh->sock == ws_sock_invalid) { + if (!wsh->tsession) { return -3; } - while((bytes = ws_raw_read(wsh, wsh->buffer + wsh->datalen, wsh->buflen - wsh->datalen)) > 0) { - wsh->datalen += bytes; - if (strstr(wsh->buffer, "\r\n\r\n") || strstr(wsh->buffer, "\n\n")) { - break; - } - } - - if (bytes > sizeof(wsh->buffer) -1) { + if (!*key || !*version || !*proto) { goto err; } - *(wsh->buffer+bytes) = '\0'; - - if (strncasecmp(wsh->buffer, "GET ", 4)) { - goto err; - } - - p = wsh->buffer + 4; - - e = strchr(p, ' '); - if (!e) { - goto err; - } - - strncpy(uri, p, e-p); - - cheezy_get_var(wsh->buffer, "Sec-WebSocket-Key", key, sizeof(key)); - cheezy_get_var(wsh->buffer, "Sec-WebSocket-Version", version, sizeof(version)); - cheezy_get_var(wsh->buffer, "Sec-WebSocket-Protocol", proto, sizeof(proto)); - - if (!*key) { - goto err; - } - snprintf(input, sizeof(input), "%s%s", key, WEBSOCKET_GUID); sha1_digest(output, input); b64encode((unsigned char *)output, SHA1_HASH_SIZE, (unsigned char *)b64, sizeof(b64)); - if (*proto) { - snprintf(proto_buf, sizeof(proto_buf), "Sec-WebSocket-Protocol: %s\r\n", proto); - } - snprintf(respond, sizeof(respond), "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: %s\r\n" - "%s\r\n", + "Sec-WebSocket-Protocol: %s\r\n\r\n", b64, - proto_buf); + proto); - - ws_raw_write(wsh, respond, strlen(respond)); - wsh->handshake = 1; - - return 0; + if (ws_raw_write(wsh, respond, strlen(respond))) { + wsh->handshake = 1; + return 0; + } err: snprintf(respond, sizeof(respond), "HTTP/1.1 400 Bad Request\r\n" "Sec-WebSocket-Version: 13\r\n\r\n"); - //printf("ERR:\n%s\n", respond); - - ws_raw_write(wsh, respond, strlen(respond)); ws_close(wsh, WS_NONE); @@ -315,238 +263,85 @@ int ws_handshake(wsh_t *wsh) } -ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes) +issize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes) { - ssize_t r; - int err = 0; + issize_t r; + TConn *conn = wsh->tsession->connP; - if (wsh->ssl) { - do { - r = SSL_read(wsh->ssl, data, bytes); -#ifndef _MSC_VER - if (wsh->x++) usleep(10000); -#else - if (wsh->x++) Sleep(10); -#endif - if (r == -1) { - err = SSL_get_error(wsh->ssl, r); + if (!wsh->handshake) { + r = wsh->tsession->connP->buffersize; + memcpy(data, conn->buffer.b, r); + printf("%s\n", conn->buffer.t); + ConnReadInit(conn); + return r; + } else { + const char *readError = NULL; - if (wsh->handshake && err == SSL_ERROR_WANT_READ) { - r = -2; - goto end; - } + // printf(" pos=%d size=%d need=%d\n", conn->bufferpos, conn->buffersize, bytes); + + r = conn->buffersize - conn->bufferpos; + + if (r < 0) { + printf("286 Read Error %d!\n", r); + return 0; + } else if (r == 0) { + ConnRead(conn, 2, NULL, NULL, &readError); + + if (readError) { + // printf("292 Read Error %s\n", readError); + free((void *)readError); + return 0; } - } while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 100); + r = conn->buffersize - conn->bufferpos; + } + + if (r <= (issize_t)bytes) { + memcpy(data, conn->buffer.b + conn->bufferpos, r); + // ConnReadInit(conn); + conn->bufferpos = conn->buffersize; + ConnReadInit(conn); + return r; + } else { + memcpy(data, conn->buffer.b + conn->bufferpos, bytes); + conn->bufferpos += (uint32_t)bytes; + return (issize_t)bytes; + } - goto end; } - do { - r = recv(wsh->sock, data, bytes, 0); -#ifndef _MSC_VER - if (wsh->x++) usleep(10000); -#else - if (wsh->x++) Sleep(10); -#endif - } while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 100); - - if (wsh->x >= 100) { - r = -1; - } - - end: - - if (r > 0) { - *((char *)data + r) = '\0'; - } - - if (r >= 0) { - wsh->x = 0; - } - - return r; } -ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) +issize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) { size_t r; if (wsh->ssl) { do { - r = SSL_write(wsh->ssl, data, bytes); - } while (r == -1 && SSL_get_error(wsh->ssl, r) == SSL_ERROR_WANT_WRITE); + r = SSL_write(wsh->ssl, data, (int)bytes); + } while (r == -1 && SSL_get_error(wsh->ssl, (int)r) == SSL_ERROR_WANT_WRITE); - return r; + return (issize_t)r; } - do { - r = send(wsh->sock, data, bytes, 0); - } while (r == -1 && xp_is_blocking(xp_errno())); - - //if (r<0) { - //printf("wRITE FAIL: %s\n", strerror(errno)); - //} - - return r; -} - -#ifdef _MSC_VER -static int setup_socket(ws_socket_t sock) -{ - unsigned long v = 1; - - if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) { - return -1; - } - - return 0; - -} - -static int restore_socket(ws_socket_t sock) -{ - unsigned long v = 0; - - if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR) { - return -1; - } - - return 0; - -} - -#else - -static int setup_socket(ws_socket_t sock) -{ - int flags = fcntl(sock, F_GETFL, 0); - return fcntl(sock, F_SETFL, flags | O_NONBLOCK); -} - -static int restore_socket(ws_socket_t sock) -{ - int flags = fcntl(sock, F_GETFL, 0); - - flags &= ~O_NONBLOCK; - - return fcntl(sock, F_SETFL, flags); - -} - -#endif - - -static int establish_logical_layer(wsh_t *wsh) -{ - - if (!wsh->sanity) { - return -1; - } - - if (wsh->logical_established) { + if (ConnWrite(wsh->tsession->connP, data, (uint32_t)bytes)) { + return (issize_t)bytes; + } else { return 0; } - - if (wsh->secure && !wsh->secure_established) { - int code; - - if (!wsh->ssl) { - wsh->ssl = SSL_new(wsh->ssl_ctx); - assert(wsh->ssl); - - SSL_set_fd(wsh->ssl, wsh->sock); - } - - do { - code = SSL_accept(wsh->ssl); - - if (code == 1) { - wsh->secure_established = 1; - break; - } - - if (code == 0) { - return -1; - } - - if (code < 0) { - if (code == -1 && SSL_get_error(wsh->ssl, code) != SSL_ERROR_WANT_READ) { - return -1; - } - } - - if (wsh->block) { - ms_sleep(10); - } else { - ms_sleep(1); - } - - wsh->sanity--; - - if (!wsh->block) { - return -2; - } - - } while (wsh->sanity > 0); - - if (!wsh->sanity) { - return -1; - } - - } - - while (!wsh->down && !wsh->handshake) { - int r = ws_handshake(wsh); - - if (r < 0) { - wsh->down = 1; - return -1; - } - - if (!wsh->handshake && !wsh->block) { - return -2; - } - - } - - wsh->logical_established = 1; - - return 0; } - -int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock, int block) +wsh_t * ws_init(ws_tsession_t *tsession) { + wsh_t *wsh = (wsh_t *)malloc(sizeof(*wsh)); + + if (!wsh) return NULL; + memset(wsh, 0, sizeof(*wsh)); - - wsh->sock = sock; - wsh->block = block; - wsh->sanity = 5000; - wsh->ssl_ctx = ssl_ctx; - - if (!ssl_ctx) { - ssl_ctx = ws_globals.ssl_ctx; - } - - if (close_sock) { - wsh->close_sock = 1; - } - + wsh->tsession = tsession; wsh->buflen = sizeof(wsh->buffer); - wsh->secure = ssl_ctx ? 1 : 0; - setup_socket(sock); - - if (establish_logical_layer(wsh) == -1) { - return -1; - } - - if (wsh->down) { - return -1; - } - - return 0; + return wsh; } void ws_destroy(wsh_t *wsh) @@ -577,7 +372,7 @@ void ws_destroy(wsh_t *wsh) } } -ssize_t ws_close(wsh_t *wsh, int16_t reason) +issize_t ws_close(wsh_t *wsh, int16_t reason) { if (wsh->down) { @@ -585,46 +380,21 @@ ssize_t ws_close(wsh_t *wsh, int16_t reason) } wsh->down = 1; - - if (reason && wsh->sock != ws_sock_invalid) { - uint16_t *u16; - uint8_t fr[4] = {WSOC_CLOSE | 0x80, 2, 0}; - - u16 = (uint16_t *) &fr[2]; - *u16 = htons((int16_t)reason); - ws_raw_write(wsh, fr, 4); - } - - restore_socket(wsh->sock); - - if (wsh->close_sock && wsh->sock != ws_sock_invalid) { - close(wsh->sock); - } - - wsh->sock = ws_sock_invalid; return reason * -1; - } -ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) +issize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) { - ssize_t need = 2; + issize_t need = 2; char *maskp; - int ll = 0; again: need = 2; maskp = NULL; *data = NULL; - ll = establish_logical_layer(wsh); - - if (ll < 0) { - return ll; - } - if (wsh->down) { return -1; } @@ -633,16 +403,11 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) return ws_close(wsh, WS_PROTO_ERR); } - if ((wsh->datalen = ws_raw_read(wsh, wsh->buffer, 9)) < 0) { - if (wsh->datalen == -2) { - return -2; - } - return ws_close(wsh, WS_PROTO_ERR); - } - - if (wsh->datalen < need) { - if ((wsh->datalen += ws_raw_read(wsh, wsh->buffer + wsh->datalen, 9 - wsh->datalen)) < need) { - /* too small - protocol err */ + if ((wsh->datalen = ws_raw_read(wsh, wsh->buffer, 14)) < need) { + while (!wsh->down && (wsh->datalen += ws_raw_read(wsh, wsh->buffer + wsh->datalen, 14 - wsh->datalen)) < need) ; + + if (0 && (wsh->datalen += ws_raw_read(wsh, wsh->buffer + wsh->datalen, 14 - wsh->datalen)) < need) { + /* too small - protocol err */ return ws_close(wsh, WS_PROTO_ERR); } } @@ -678,7 +443,7 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) wsh->plen = wsh->buffer[1] & 0x7f; wsh->payload = &wsh->buffer[2]; - + if (wsh->plen == 127) { uint64_t *u64; @@ -718,13 +483,7 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) need = (wsh->plen - (wsh->datalen - need)); - if (need < 0) { - /* invalid read - protocol err .. */ - *oc = WSOC_CLOSE; - return ws_close(wsh, WS_PROTO_ERR); - } - - if ((need + wsh->datalen) > (ssize_t)wsh->buflen) { + if ((need + wsh->datalen) > (issize_t)wsh->buflen) { /* too big - Ain't nobody got time fo' dat */ *oc = WSOC_CLOSE; return ws_close(wsh, WS_DATA_TOO_BIG); @@ -733,7 +492,7 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) wsh->rplen = wsh->plen - need; while(need) { - ssize_t r = ws_raw_read(wsh, wsh->payload + wsh->rplen, need); + issize_t r = ws_raw_read(wsh, wsh->payload + wsh->rplen, need); if (r < 1) { /* invalid read - protocol err .. */ @@ -747,7 +506,7 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) } if (mask && maskp) { - ssize_t i; + issize_t i; for (i = 0; i < wsh->datalen; i++) { wsh->payload[i] ^= maskp[i % 4]; @@ -780,7 +539,7 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data) } } -ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes) +issize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes) { if (bytes + wsh->wdatalen > wsh->buflen) { @@ -789,14 +548,14 @@ ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes) memcpy(wsh->wbuffer + wsh->wdatalen, data, bytes); - wsh->wdatalen += bytes; + wsh->wdatalen += (issize_t)bytes; - return bytes; + return (issize_t)bytes; } -ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc) +issize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc) { - ssize_t r = 0; + issize_t r = 0; if (!wsh->wdatalen) { return -1; @@ -810,7 +569,7 @@ ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc) } -ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes) +issize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes) { uint8_t hdr[14] = { 0 }; size_t hlen = 2; @@ -844,39 +603,15 @@ ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes) *u64 = htonl(bytes); } - if (ws_raw_write(wsh, (void *) &hdr[0], hlen) != (ssize_t)hlen) { + if (ws_raw_write(wsh, (void *) &hdr[0], hlen) != (issize_t)hlen) { return -1; } - if (ws_raw_write(wsh, data, bytes) != (ssize_t)bytes) { + if (ws_raw_write(wsh, data, bytes) != (issize_t)bytes) { return -2; } - return bytes; + return (issize_t)bytes; } -#ifdef _MSC_VER -int xp_errno(void) -{ - return WSAGetLastError(); -} - -int xp_is_blocking(int errcode) -{ - return errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS; -} - -#else - -int xp_errno(void) -{ - return errno; -} - -int xp_is_blocking(int errcode) -{ - return errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EINTR || errcode == ETIMEDOUT; -} - -#endif diff --git a/src/mod/xml_int/mod_xml_rpc/ws.h b/src/mod/xml_int/mod_xml_rpc/ws.h index b9621b3824..8b34844f15 100644 --- a/src/mod/xml_int/mod_xml_rpc/ws.h +++ b/src/mod/xml_int/mod_xml_rpc/ws.h @@ -13,40 +13,30 @@ #include #else #pragma warning(disable:4996) +#define snprintf _snprintf #endif #include -#include #include #include #include #include #include #include -//#include "sha1.h" #include +#include <../lib/abyss/src/session.h> +#include <../lib/abyss/src/conn.h> -#ifdef _MSC_VER -#define strncasecmp _strnicmp -#define snprintf _snprintf -#ifdef _WIN64 -#define WS_SSIZE_T __int64 -#elif _MSC_VER >= 1400 -#define WS_SSIZE_T __int32 __w64 -#else -#define WS_SSIZE_T __int32 -#endif -typedef WS_SSIZE_T ssize_t; -#endif +typedef TSession ws_tsession_t; +typedef int issize_t; - -struct ws_globals_s { +struct globals_s { const SSL_METHOD *ssl_method; SSL_CTX *ssl_ctx; char cert[512]; char key[512]; }; -extern struct ws_globals_s ws_globals; +// extern struct globals_s globals; typedef int ws_socket_t; #define ws_sock_invalid -1 @@ -69,44 +59,36 @@ typedef enum { } ws_opcode_t; typedef struct wsh_s { - ws_socket_t sock; + ws_tsession_t *tsession; char buffer[65536]; char wbuffer[65536]; size_t buflen; - ssize_t datalen; - ssize_t wdatalen; + issize_t datalen; + issize_t wdatalen; char *payload; - ssize_t plen; - ssize_t rplen; + issize_t plen; + issize_t rplen; SSL *ssl; int handshake; uint8_t down; int secure; uint8_t close_sock; - SSL_CTX *ssl_ctx; - int block; - int sanity; - int secure_established; - int logical_established; - int x; } wsh_t; -ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc); -ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes); +issize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc); +issize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes); -ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes); -ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes); -ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data); -ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes); -int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock, int block); -ssize_t ws_close(wsh_t *wsh, int16_t reason); +issize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes); +issize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes); +issize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data); +issize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes); +wsh_t * ws_init(ws_tsession_t *tsession); +issize_t ws_close(wsh_t *wsh, int16_t reason); void ws_destroy(wsh_t *wsh); void init_ssl(void); void deinit_ssl(void); -int xp_errno(void); -int xp_is_blocking(int errcode); - +int ws_handshake_kvp(wsh_t *wsh, char *key, char *version, char *proto); #ifndef _MSC_VER