Changed way handshake info is extracted (functions instead of struct); tried to implement HyBi, not working yet with IE Html5Labs

This commit is contained in:
Hans-Peter Gygax 2011-06-05 22:53:24 +02:00
parent 2c757ed9a4
commit e101b3bace
6 changed files with 463 additions and 97 deletions

320
other/sha-1.c Normal file
View File

@ -0,0 +1,320 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#include <sys/types.h>
#ifdef _WIN32
typedef unsigned char u_int8_t;
typedef unsigned int u_int32_t;
typedef unsigned __int64 u_int64_t;
typedef void* caddr_t;
#undef __P
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
#else
#include <sys/cdefs.h>
#include <sys/time.h>
#endif
#include <string.h>
struct sha1_ctxt {
union {
u_int8_t b8[20];
u_int32_t b32[5];
} h;
union {
u_int8_t b8[8];
u_int64_t b64[1];
} c;
union {
u_int8_t b8[64];
u_int32_t b32[16];
} m;
u_int8_t count;
};
/* sanity check */
#if BYTE_ORDER != BIG_ENDIAN
# if BYTE_ORDER != LITTLE_ENDIAN
# define unsupported 1
# endif
#endif
#ifndef unsupported
/* constant table */
static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
#define K(t) _K[(t) / 20]
#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
#define F1(b, c, d) (((b) ^ (c)) ^ (d))
#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define F3(b, c, d) (((b) ^ (c)) ^ (d))
#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
#define H(n) (ctxt->h.b32[(n)])
#define COUNT (ctxt->count)
#define BCOUNT (ctxt->c.b64[0] / 8)
#define W(n) (ctxt->m.b32[(n)])
#define PUTBYTE(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
ctxt->c.b64[0] += 8; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
#define PUTPAD(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
static void sha1_step __P((struct sha1_ctxt *));
static void
sha1_step(struct sha1_ctxt *ctxt)
{
u_int32_t a, b, c, d, e;
size_t t, s;
u_int32_t tmp;
#if BYTE_ORDER == LITTLE_ENDIAN
struct sha1_ctxt tctxt;
memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64);
ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
#endif
a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
for (t = 0; t < 20; t++) {
s = t & 0x0f;
if (t >= 16)
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 20; t < 40; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 40; t < 60; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 60; t < 80; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
H(0) = H(0) + a;
H(1) = H(1) + b;
H(2) = H(2) + c;
H(3) = H(3) + d;
H(4) = H(4) + e;
bzero(&ctxt->m.b8[0], 64);
}
/*------------------------------------------------------------*/
void
sha1_init(struct sha1_ctxt *ctxt)
{
bzero(ctxt, sizeof(struct sha1_ctxt));
H(0) = 0x67452301;
H(1) = 0xefcdab89;
H(2) = 0x98badcfe;
H(3) = 0x10325476;
H(4) = 0xc3d2e1f0;
}
void
sha1_pad(struct sha1_ctxt *ctxt)
{
size_t padlen; /*pad length in bytes*/
size_t padstart;
PUTPAD(0x80);
padstart = COUNT % 64;
padlen = 64 - padstart;
if (padlen < 8) {
bzero(&ctxt->m.b8[padstart], padlen);
COUNT += padlen;
COUNT %= 64;
sha1_step(ctxt);
padstart = COUNT % 64; /* should be 0 */
padlen = 64 - padstart; /* should be 64 */
}
bzero(&ctxt->m.b8[padstart], padlen - 8);
COUNT += (padlen - 8);
COUNT %= 64;
#if BYTE_ORDER == BIG_ENDIAN
PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
#else
PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
#endif
}
void
sha1_loop(struct sha1_ctxt *ctxt, const u_int8_t *input, size_t len)
{
size_t gaplen;
size_t gapstart;
size_t off;
size_t copysiz;
off = 0;
while (off < len) {
gapstart = COUNT % 64;
gaplen = 64 - gapstart;
copysiz = (gaplen < len - off) ? gaplen : len - off;
memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz);
COUNT += copysiz;
COUNT %= 64;
ctxt->c.b64[0] += copysiz * 8;
if (COUNT % 64 == 0)
sha1_step(ctxt);
off += copysiz;
}
}
void
sha1_result(struct sha1_ctxt *ctxt, caddr_t digest0)
{
u_int8_t *digest;
digest = (u_int8_t *)digest0;
sha1_pad(ctxt);
#if BYTE_ORDER == BIG_ENDIAN
memcpy(digest, &ctxt->h.b8[0], 20);
#else
digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
#endif
}
/*
* This should look and work like the libcrypto implementation
*/
unsigned char *
SHA1(const unsigned char *d, size_t n, unsigned char *md)
{
struct sha1_ctxt ctx;
sha1_init(&ctx);
sha1_loop(&ctx, d, n);
sha1_result(&ctx, (caddr_t)md);
return md;
}
#endif /*unsupported*/

View File

@ -35,16 +35,73 @@
#include "md5.h" #include "md5.h"
#include "websocket.h" #include "websocket.h"
const char server_handshake[] = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n\ const char server_handshake_hixie[] = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
Upgrade: WebSocket\r\n\ Upgrade: WebSocket\r\n\
Connection: Upgrade\r\n\ Connection: Upgrade\r\n\
%sWebSocket-Origin: %s\r\n\ %sWebSocket-Origin: %.*s\r\n\
%sWebSocket-Location: %s://%s%s\r\n\ %sWebSocket-Location: %s://%.*s%.*s\r\n\
%sWebSocket-Protocol: base64\r\n\ %sWebSocket-Protocol: base64\r\n\
\r\n%s"; \r\n%s";
const char server_handshake_hybi[] = "HTTP/1.1 101 Switching Protocols\r\n\
Upgrade: websocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Accept: %s\r\n\
Sec-WebSocket-Protocol: %.*s\r\n\
\r\n\
";
const char policy_response[] = "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\n"; const char policy_response[] = "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\n";
/*
* Get the path from the handhake header.
*/
static int get_path(const char *handshake, const char* *value, size_t *len) {
const char *start, *end;
if ((strlen(handshake) < 92) || (memcmp(handshake, "GET ", 4) != 0)) {
return 0;
}
start = handshake+4;
end = strstr(start, " HTTP/1.1");
if (!end) { return 0; }
*value = start;
*len = end - start;
return *len;
}
/*
* Gets a header field from an HTTP header.
* Returns non-zero if successful, 0 if the header does not contain
* the specified field.
*/
static int get_header_field(const char *handshake, const char *name, const char* *value, size_t *len) {
char key[64];
const char *p, *q;
size_t lk;
lk = sprintf_s(key, sizeof(key), "\r\n%s: ", name );
p = strstr(handshake, key);
if (p) {
*value = p + lk;
q = strstr(*value, "\r\n");
if (!q) return 0;
return (*len = (q - *value));
}
else return 0;
}
static const char * skip_header(const char *handshake) {
const char *p;
p = strstr(handshake, "\r\n\r\n");
if (!p) return 0;
return p + 4;
}
/* /*
* Global state * Global state
* *
@ -248,81 +305,32 @@ int decode(char *src, size_t srclength, u_char *target, size_t targsize) {
return retlen; return retlen;
} }
int parse_handshake(char *handshake, headers_t *headers) { int gen_md5(const char *handshake, char *target) {
char *start, *end;
if ((strlen(handshake) < 92) || (memcmp(handshake, "GET ", 4) != 0)) {
return 0;
}
start = handshake+4;
end = strstr(start, " HTTP/1.1");
if (!end) { return 0; }
strncpy(headers->path, start, end-start);
headers->path[end-start] = '\0';
start = strstr(handshake, "\r\nHost: ");
if (!start) { return 0; }
start += 8;
end = strstr(start, "\r\n");
strncpy(headers->host, start, end-start);
headers->host[end-start] = '\0';
start = strstr(handshake, "\r\nOrigin: ");
if (!start) { return 0; }
start += 10;
end = strstr(start, "\r\n");
strncpy(headers->origin, start, end-start);
headers->origin[end-start] = '\0';
start = strstr(handshake, "\r\n\r\n");
if (!start) { return 0; }
start += 4;
if (strlen(start) == 8) {
strncpy(headers->key3, start, 8);
headers->key3[8] = '\0';
start = strstr(handshake, "\r\nSec-WebSocket-Key1: ");
if (!start) { return 0; }
start += 22;
end = strstr(start, "\r\n");
strncpy(headers->key1, start, end-start);
headers->key1[end-start] = '\0';
start = strstr(handshake, "\r\nSec-WebSocket-Key2: ");
if (!start) { return 0; }
start += 22;
end = strstr(start, "\r\n");
strncpy(headers->key2, start, end-start);
headers->key2[end-start] = '\0';
} else {
headers->key1[0] = '\0';
headers->key2[0] = '\0';
headers->key3[0] = '\0';
}
return 1;
}
int gen_md5(headers_t *headers, char *target) {
unsigned int i, spaces1 = 0, spaces2 = 0; unsigned int i, spaces1 = 0, spaces2 = 0;
unsigned long num1 = 0, num2 = 0; unsigned long num1 = 0, num2 = 0;
unsigned char buf[17]; unsigned char buf[17];
for (i=0; i < strlen(headers->key1); i++) { const char *value;
if (headers->key1[i] == ' ') { size_t len;
if (!get_header_field(handshake, "Sec-WebSocket-Key1", &value, &len)) return 0;
for (i=0; i < len; i++) {
if (value[i] == ' ') {
spaces1 += 1; spaces1 += 1;
} }
if ((headers->key1[i] >= 48) && (headers->key1[i] <= 57)) { if ((value[i] >= 48) && (value[i] <= 57)) {
num1 = num1 * 10 + (headers->key1[i] - 48); num1 = num1 * 10 + (value[i] - 48);
} }
} }
num1 = num1 / spaces1; num1 = num1 / spaces1;
for (i=0; i < strlen(headers->key2); i++) { if (!get_header_field(handshake, "Sec-WebSocket-Key2", &value, &len)) return 0;
if (headers->key2[i] == ' ') { for (i=0; i < len; i++) {
if (value[i] == ' ') {
spaces2 += 1; spaces2 += 1;
} }
if ((headers->key2[i] >= 48) && (headers->key2[i] <= 57)) { if ((value[i] >= 48) && (value[i] <= 57)) {
num2 = num2 * 10 + (headers->key2[i] - 48); num2 = num2 * 10 + (value[i] - 48);
} }
} }
num2 = num2 / spaces2; num2 = num2 / spaces2;
@ -338,7 +346,8 @@ int gen_md5(headers_t *headers, char *target) {
buf[6] = (num2 & 0xff00) >> 8; buf[6] = (num2 & 0xff00) >> 8;
buf[7] = num2 & 0xff; buf[7] = num2 & 0xff;
strncpy(buf+8, headers->key3, 8); if (!(value = skip_header(handshake))) return 0;
strncpy(buf+8, value, 8);
buf[16] = '\0'; buf[16] = '\0';
md5_buffer(buf, 16, target); md5_buffer(buf, 16, target);
@ -350,15 +359,18 @@ int gen_md5(headers_t *headers, char *target) {
ws_ctx_t *do_handshake(int sock) { ws_ctx_t *do_handshake(int sock) {
char handshake[4096], response[4096], trailer[17]; char handshake[4096], response[4096], trailer[17], keynguid[1024+36+1], hash[20+1], accept[30+1];
char *scheme, *pre; char *scheme, *pre, *protocol;
headers_t headers;
int len; int len;
ws_ctx_t * ws_ctx; ws_ctx_t * ws_ctx;
const char *value;
size_t vlen;
size_t rlen;
// Peek, but don't read the data // Peek, but don't read the data
len = recv(sock, handshake, 1024, MSG_PEEK); len = recv(sock, handshake, 1024, MSG_PEEK);
handshake[len] = 0; handshake[len] = 0;
printf("Handshake:\n%s\n", handshake);
if (len == 0) { if (len == 0) {
handler_msg("ignoring empty handshake\n"); handler_msg("ignoring empty handshake\n");
return NULL; return NULL;
@ -398,25 +410,46 @@ ws_ctx_t *do_handshake(int sock) {
} }
handshake[len] = 0; handshake[len] = 0;
if (!parse_handshake(handshake, &headers)) { // HyBi/IETF version of the protocol ?
handler_emsg("Invalid WS request\n"); if (get_header_field(handshake, "Sec-WebSocket-Version", &value, &vlen)) {
return NULL; int ver;
} const char *key, *protocol;
size_t kl, el, pl;
ver = atoi(value);
if (!get_header_field(handshake, "Sec-WebSocket-Protocol", &protocol, &pl)) return 0;
ws_ctx->protocol = strncmp(protocol, "base64", pl) == 0 ? base64 : binary;
if (!get_header_field(handshake, "Sec-WebSocket-Key", &key, &kl)) return 0;
strncpy_s(keynguid, sizeof(keynguid), key, kl);
strcat_s(keynguid, sizeof(keynguid), "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
SHA1((const unsigned char*)keynguid, strlen(keynguid), hash);
b64_ntop(hash, 20, accept, sizeof(accept));
rlen = sprintf(response, server_handshake_hybi, accept, pl, protocol);
}
else // Hixie version of the protocol (75 or 76)
{
const char *key3, *orig, *host, *path;
size_t kl, ol, hl, pl;
key3 = skip_header(handshake);
if (key3 && *key3) {
gen_md5(handshake, trailer);
pre = "Sec-";
handler_msg("using protocol version 76\n");
} else {
trailer[0] = '\0';
pre = "";
handler_msg("using protocol version 75\n");
}
ws_ctx->protocol = base64;
if (!get_header_field(handshake, "Origin", &orig, &ol)) return NULL;
if (!get_header_field(handshake, "Host", &host, &hl)) return NULL;
if (!get_path(handshake, &path, &pl)) return NULL;
rlen = sprintf(response, server_handshake_hixie, pre, ol, orig, pre, scheme,
hl, host, pl, path, pre, trailer);
}
printf("\nResponse:\n%s\n--------------------------\n", response);
if (headers.key3[0] != '\0') {
gen_md5(&headers, trailer);
pre = "Sec-";
handler_msg("using protocol version 76\n");
} else {
trailer[0] = '\0';
pre = "";
handler_msg("using protocol version 75\n");
}
sprintf(response, server_handshake, pre, headers.origin, pre, scheme,
headers.host, headers.path, pre, trailer);
//handler_msg("response: %s\n", response); //handler_msg("response: %s\n", response);
ws_send(ws_ctx, response, strlen(response)); ws_send(ws_ctx, response, rlen);
return ws_ctx; return ws_ctx;
} }

View File

@ -1,9 +1,12 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
typedef enum { binary = 1, base64 } protocol_t;
typedef struct { typedef struct {
int sockfd; int sockfd;
SSL_CTX *ssl_ctx; SSL_CTX *ssl_ctx;
SSL *ssl; SSL *ssl;
protocol_t protocol;
} ws_ctx_t; } ws_ctx_t;
typedef struct { typedef struct {
@ -18,14 +21,19 @@ typedef struct {
int daemon; int daemon;
} settings_t; } settings_t;
/*
typedef struct { typedef struct {
char path[1024+1]; char path[1024+1];
char host[1024+1]; char host[1024+1];
char origin[1024+1]; char origin[1024+1];
char protocols[512+1];
char key[1024+1];
char key1[1024+1]; char key1[1024+1];
char key2[1024+1]; char key2[1024+1];
char key3[8+1]; char key3[8+1];
char version[4+1];
} headers_t; } headers_t;
*/
// 2011-06-01 gygax@practicomp.ch Better way ? // 2011-06-01 gygax@practicomp.ch Better way ?
#ifndef ssize_t #ifndef ssize_t

View File

@ -80,6 +80,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\other\md5.c" /> <ClCompile Include="..\other\md5.c" />
<ClCompile Include="..\other\sha-1.c" />
<ClCompile Include="..\other\websocket.c" /> <ClCompile Include="..\other\websocket.c" />
<ClCompile Include="..\other\websockify.c" /> <ClCompile Include="..\other\websockify.c" />
<ClCompile Include="..\other\win32\base64.c" /> <ClCompile Include="..\other\win32\base64.c" />

View File

@ -36,6 +36,9 @@
<ClCompile Include="..\other\win32\base64.c"> <ClCompile Include="..\other\win32\base64.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\other\sha-1.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\other\md5.h"> <ClInclude Include="..\other\md5.h">

View File

@ -1,3 +1,4 @@
<!DOCTYPE html>
<html> <html>
<head> <head>