Browse Source

Remove duplicates

tags/v0.0.62
Peter Vivell 6 years ago
parent
commit
68b2ff22e7

+ 0
- 1
config/60-kromek-radangel.rules View File

@@ -1 +0,0 @@
1
-SUBSYSTEM=="usb", ATTR{idVendor}=="04d8", ATTR{idProduct}=="0100", MODE="0666"

+ 0
- 123
config/nginx-default-datasrc-location.conf View File

@@ -1,123 +0,0 @@
1
-##
2
-# You should look at the following URL's in order to grasp a solid understanding
3
-# of Nginx configuration files in order to fully unleash the power of Nginx.
4
-# https://www.nginx.com/resources/wiki/start/
5
-# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
6
-# https://wiki.debian.org/Nginx/DirectoryStructure
7
-#
8
-# In most cases, administrators will remove this file from sites-enabled/ and
9
-# leave it as reference inside of sites-available where it will continue to be
10
-# updated by the nginx packaging team.
11
-#
12
-# This file will automatically load configuration files provided by other
13
-# applications, such as Drupal or Wordpress. These applications will be made
14
-# available underneath a path with that package name, such as /drupal8.
15
-#
16
-# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
17
-##
18
-
19
-# Default server configuration
20
-#
21
-server {
22
-	listen 80 default_server;
23
-	listen [::]:80 default_server;
24
-
25
-	# SSL configuration
26
-	#
27
-	# listen 443 ssl default_server;
28
-	# listen [::]:443 ssl default_server;
29
-	#
30
-	# Note: You should disable gzip for SSL traffic.
31
-	# See: https://bugs.debian.org/773332
32
-	#
33
-	# Read up on ssl_ciphers to ensure a secure configuration.
34
-	# See: https://bugs.debian.org/765782
35
-	#
36
-	# Self signed certs generated by the ssl-cert package
37
-	# Don't use them in a production server!
38
-	#
39
-	# include snippets/snakeoil.conf;
40
-
41
-	root /var/www/html;
42
-
43
-	# Add index.php to the list if you are using PHP
44
-	index index.html index.htm index.nginx-debian.html;
45
-
46
-	server_name _;
47
-
48
-	location / {
49
-		# First attempt to serve request as file, then
50
-		# as directory, then fall back to displaying a 404.
51
-		try_files $uri $uri/ =404;
52
-	}
53
-
54
-	# pass PHP scripts to FastCGI server
55
-	#
56
-	#location ~ \.php$ {
57
-	#	include snippets/fastcgi-php.conf;
58
-	#
59
-	#	# With php-fpm (or other unix sockets):
60
-	#	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
61
-	#	# With php-cgi (or other tcp sockets):
62
-	#	fastcgi_pass 127.0.0.1:9000;
63
-	#}
64
-
65
-	# deny access to .htaccess files, if Apache's document root
66
-	# concurs with nginx's one
67
-	#
68
-	#location ~ /\.ht {
69
-	#	deny all;
70
-	#}
71
-
72
-    ## <DATASRC> ##
73
-
74
-    location /data/hist.tsv {
75
-        alias /tmp/stats.tsv;
76
-    }
77
-
78
-    location /data/stream.tsv { 
79
-        alias /tmp/event.tsv;
80
-    }
81
-
82
-    location /data/stream.ws {
83
-        proxy_http_version 1.1;
84
-        proxy_set_header Upgrade         $http_upgrade;
85
-        proxy_set_header Connection      "upgrade";
86
-
87
-        proxy_set_header Host            $host; # $http_host;
88
-        proxy_set_header X-Real-IP       $remote_addr;
89
-        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
90
-        proxy_set_header X-NginX-Proxy   true;
91
-
92
-        proxy_read_timeout 3600;
93
-        proxy_buffering off;
94
-        tcp_nodelay on;
95
-
96
-        error_page 502 = /data/stream.tsv; # serve http for non-ws clients
97
-
98
-        proxy_pass http://127.0.0.1:5800/websockify;
99
-    }
100
-
101
-    ## </DATASRC> ##
102
-
103
-}
104
-
105
-
106
-# Virtual Host configuration for example.com
107
-#
108
-# You can move that to a different file under sites-available/ and symlink that
109
-# to sites-enabled/ to enable it.
110
-#
111
-#server {
112
-#	listen 80;
113
-#	listen [::]:80;
114
-#
115
-#	server_name example.com;
116
-#
117
-#	root /var/www/example.com;
118
-#	index index.html;
119
-#
120
-#	location / {
121
-#		try_files $uri $uri/ =404;
122
-#	}
123
-#}

+ 0
- 14
src/contrib/Makefile View File

@@ -1,14 +0,0 @@
1
-TARGETS=websockify
2
-CFLAGS += -fPIC
3
-
4
-all: $(TARGETS)
5
-
6
-websockify: websockify.o websocket.o
7
-	$(CC) $(LDFLAGS) $^ -lssl -lcrypto -o $@
8
-
9
-websocket.o: websocket.c websocket.h
10
-websockify.o: websockify.c websocket.h
11
-
12
-clean:
13
-	rm -f websockify *.o
14
-

+ 0
- 914
src/contrib/websocket.c View File

@@ -1,914 +0,0 @@
1
-/*
2
- * WebSocket lib with support for "wss://" encryption.
3
- * Copyright 2010 Joel Martin
4
- * Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
5
- *
6
- * You can make a cert/key with openssl using:
7
- * openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
8
- * as taken from http://docs.python.org/dev/library/ssl.html#certificates
9
- */
10
-#include <unistd.h>
11
-#include <stdio.h>
12
-#include <stdlib.h>
13
-#include <errno.h>
14
-#include <string.h>
15
-#include <sys/types.h> 
16
-#include <sys/socket.h>
17
-#include <sys/stat.h>
18
-#include <netinet/in.h>
19
-#include <arpa/inet.h>
20
-#include <netdb.h>
21
-#include <signal.h> // daemonizing
22
-#include <fcntl.h>  // daemonizing
23
-#include <openssl/err.h>
24
-#include <openssl/ssl.h>
25
-#include <openssl/bio.h> /* base64 encode/decode */
26
-#include <openssl/md5.h> /* md5 hash */
27
-#include <openssl/sha.h> /* sha1 hash */
28
-#include "websocket.h"
29
-
30
-/*
31
- * Global state
32
- *
33
- *   Warning: not thread safe
34
- */
35
-int ssl_initialized = 0;
36
-int pipe_error = 0;
37
-settings_t settings;
38
-
39
-
40
-void traffic(const char * token) {
41
-    if ((settings.verbose) && (! settings.daemon)) {
42
-        fprintf(stdout, "%s", token);
43
-        fflush(stdout);
44
-    }
45
-}
46
-
47
-void error(char *msg)
48
-{
49
-    perror(msg);
50
-}
51
-
52
-void fatal(char *msg)
53
-{
54
-    perror(msg);
55
-    exit(1);
56
-}
57
-
58
-/* resolve host with also IP address parsing */ 
59
-int resolve_host(struct in_addr *sin_addr, const char *hostname) 
60
-{ 
61
-    if (!inet_aton(hostname, sin_addr)) { 
62
-        struct addrinfo *ai, *cur; 
63
-        struct addrinfo hints; 
64
-        memset(&hints, 0, sizeof(hints)); 
65
-        hints.ai_family = AF_INET; 
66
-        if (getaddrinfo(hostname, NULL, &hints, &ai)) 
67
-            return -1; 
68
-        for (cur = ai; cur; cur = cur->ai_next) { 
69
-            if (cur->ai_family == AF_INET) { 
70
-                *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr; 
71
-                freeaddrinfo(ai); 
72
-                return 0; 
73
-            } 
74
-        } 
75
-        freeaddrinfo(ai); 
76
-        return -1; 
77
-    } 
78
-    return 0; 
79
-} 
80
-
81
-
82
-/*
83
- * SSL Wrapper Code
84
- */
85
-
86
-ssize_t ws_recv(ws_ctx_t *ctx, void *buf, size_t len) {
87
-    if (ctx->ssl) {
88
-        //handler_msg("SSL recv\n");
89
-        return SSL_read(ctx->ssl, buf, len);
90
-    } else {
91
-        return recv(ctx->sockfd, buf, len, 0);
92
-    }
93
-}
94
-
95
-ssize_t ws_send(ws_ctx_t *ctx, const void *buf, size_t len) {
96
-    if (ctx->ssl) {
97
-        //handler_msg("SSL send\n");
98
-        return SSL_write(ctx->ssl, buf, len);
99
-    } else {
100
-        return send(ctx->sockfd, buf, len, 0);
101
-    }
102
-}
103
-
104
-ws_ctx_t *alloc_ws_ctx() {
105
-    ws_ctx_t *ctx;
106
-    if (! (ctx = malloc(sizeof(ws_ctx_t))) )
107
-        { fatal("malloc()"); }
108
-
109
-    if (! (ctx->cin_buf = malloc(BUFSIZE)) )
110
-        { fatal("malloc of cin_buf"); }
111
-    if (! (ctx->cout_buf = malloc(BUFSIZE)) )
112
-        { fatal("malloc of cout_buf"); }
113
-    if (! (ctx->tin_buf = malloc(BUFSIZE)) )
114
-        { fatal("malloc of tin_buf"); }
115
-    if (! (ctx->tout_buf = malloc(BUFSIZE)) )
116
-        { fatal("malloc of tout_buf"); }
117
-
118
-    ctx->headers = malloc(sizeof(headers_t));
119
-    ctx->ssl = NULL;
120
-    ctx->ssl_ctx = NULL;
121
-    return ctx;
122
-}
123
-
124
-void free_ws_ctx(ws_ctx_t *ctx) {
125
-    free(ctx->cin_buf);
126
-    free(ctx->cout_buf);
127
-    free(ctx->tin_buf);
128
-    free(ctx->tout_buf);
129
-    free(ctx);
130
-}
131
-
132
-ws_ctx_t *ws_socket(ws_ctx_t *ctx, int socket) {
133
-    ctx->sockfd = socket;
134
-    return ctx;
135
-}
136
-
137
-ws_ctx_t *ws_socket_ssl(ws_ctx_t *ctx, int socket, char * certfile, char * keyfile) {
138
-    int ret;
139
-    char msg[1024];
140
-    char * use_keyfile;
141
-    ws_socket(ctx, socket);
142
-
143
-    if (keyfile && (keyfile[0] != '\0')) {
144
-        // Separate key file
145
-        use_keyfile = keyfile;
146
-    } else {
147
-        // Combined key and cert file
148
-        use_keyfile = certfile;
149
-    }
150
-
151
-    // Initialize the library
152
-    if (! ssl_initialized) {
153
-        SSL_library_init();
154
-        OpenSSL_add_all_algorithms();
155
-        SSL_load_error_strings();
156
-        ssl_initialized = 1;
157
-
158
-    }
159
-
160
-    //ctx->ssl_ctx = SSL_CTX_new(TLSv1_server_method());
161
-    ctx->ssl_ctx = SSL_CTX_new(TLS_server_method());
162
-    if (ctx->ssl_ctx == NULL) {
163
-        ERR_print_errors_fp(stderr);
164
-        fatal("Failed to configure SSL context");
165
-    }
166
-
167
-    if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, use_keyfile,
168
-                                    SSL_FILETYPE_PEM) <= 0) {
169
-        sprintf(msg, "Unable to load private key file %s\n", use_keyfile);
170
-        fatal(msg);
171
-    }
172
-
173
-    if (SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certfile) <= 0) {
174
-        sprintf(msg, "Unable to load certificate file %s\n", certfile);
175
-        fatal(msg);
176
-    }
177
-
178
-//    if (SSL_CTX_set_cipher_list(ctx->ssl_ctx, "DEFAULT") != 1) {
179
-//        sprintf(msg, "Unable to set cipher\n");
180
-//        fatal(msg);
181
-//    }
182
-
183
-    // Associate socket and ssl object
184
-    ctx->ssl = SSL_new(ctx->ssl_ctx);
185
-    SSL_set_fd(ctx->ssl, socket);
186
-
187
-    ret = SSL_accept(ctx->ssl);
188
-    if (ret < 0) {
189
-        ERR_print_errors_fp(stderr);
190
-        return NULL;
191
-    }
192
-
193
-    return ctx;
194
-}
195
-
196
-void ws_socket_free(ws_ctx_t *ctx) {
197
-    if (ctx->ssl) {
198
-        SSL_free(ctx->ssl);
199
-        ctx->ssl = NULL;
200
-    }
201
-    if (ctx->ssl_ctx) {
202
-        SSL_CTX_free(ctx->ssl_ctx);
203
-        ctx->ssl_ctx = NULL;
204
-    }
205
-    if (ctx->sockfd) {
206
-        shutdown(ctx->sockfd, SHUT_RDWR);
207
-        close(ctx->sockfd);
208
-        ctx->sockfd = 0;
209
-    }
210
-}
211
-
212
-int ws_b64_ntop(const unsigned char const * src, size_t srclen, char * dst, size_t dstlen) {
213
-    int len = 0;
214
-    int total_len = 0;
215
-
216
-    BIO *buff, *b64f;
217
-    BUF_MEM *ptr;
218
-
219
-    b64f = BIO_new(BIO_f_base64());
220
-    buff = BIO_new(BIO_s_mem());
221
-    buff = BIO_push(b64f, buff);
222
-
223
-    BIO_set_flags(buff, BIO_FLAGS_BASE64_NO_NL);
224
-    BIO_set_close(buff, BIO_CLOSE);
225
-    do {
226
-        len = BIO_write(buff, src + total_len, srclen - total_len);
227
-        if (len > 0)
228
-            total_len += len;
229
-    } while (len && BIO_should_retry(buff));
230
-
231
-    BIO_flush(buff);
232
-
233
-    BIO_get_mem_ptr(buff, &ptr);
234
-    len = ptr->length;
235
-
236
-    memcpy(dst, ptr->data, dstlen < len ? dstlen : len);
237
-    dst[dstlen < len ? dstlen : len] = '\0';
238
-
239
-    BIO_free_all(buff);
240
-
241
-    if (dstlen < len)
242
-        return -1;
243
-
244
-    return len;
245
-}
246
-
247
-int ws_b64_pton(const char const * src, unsigned char * dst, size_t dstlen) {
248
-    int len = 0;
249
-    int total_len = 0;
250
-    int pending = 0;
251
-
252
-    BIO *buff, *b64f;
253
-
254
-    b64f = BIO_new(BIO_f_base64());
255
-    buff = BIO_new_mem_buf(src, -1);
256
-    buff = BIO_push(b64f, buff);
257
-
258
-    BIO_set_flags(buff, BIO_FLAGS_BASE64_NO_NL);
259
-    BIO_set_close(buff, BIO_CLOSE);
260
-    do {
261
-        len = BIO_read(buff, dst + total_len, dstlen - total_len);
262
-        if (len > 0)
263
-            total_len += len;
264
-    } while (len && BIO_should_retry(buff));
265
-
266
-    dst[total_len] = '\0';
267
-
268
-    pending = BIO_ctrl_pending(buff);
269
-
270
-    BIO_free_all(buff);
271
-
272
-    if (pending)
273
-        return -1;
274
-
275
-    return len;
276
-}
277
-
278
-/* ------------------------------------------------------- */
279
-
280
-
281
-int encode_hixie(u_char const *src, size_t srclength,
282
-                 char *target, size_t targsize) {
283
-    int sz = 0, len = 0;
284
-    target[sz++] = '\x00';
285
-    len = ws_b64_ntop(src, srclength, target+sz, targsize-sz);
286
-    if (len < 0) {
287
-        return len;
288
-    }
289
-    sz += len;
290
-    target[sz++] = '\xff';
291
-    return sz;
292
-}
293
-
294
-int decode_hixie(char *src, size_t srclength,
295
-                 u_char *target, size_t targsize,
296
-                 unsigned int *opcode, unsigned int *left) {
297
-    char *start, *end, cntstr[4];
298
-    int i, len, framecount = 0, retlen = 0;
299
-    unsigned char chr;
300
-    if ((src[0] != '\x00') || (src[srclength-1] != '\xff')) {
301
-        handler_emsg("WebSocket framing error\n");
302
-        return -1;
303
-    }
304
-    *left = srclength;
305
-
306
-    if (srclength == 2 &&
307
-        (src[0] == '\xff') && 
308
-        (src[1] == '\x00')) {
309
-        // client sent orderly close frame
310
-        *opcode = 0x8; // Close frame
311
-        return 0;
312
-    }
313
-    *opcode = 0x1; // Text frame
314
-
315
-    start = src+1; // Skip '\x00' start
316
-    do {
317
-        /* We may have more than one frame */
318
-        end = (char *)memchr(start, '\xff', srclength);
319
-        *end = '\x00';
320
-        len = ws_b64_pton(start, target+retlen, targsize-retlen);
321
-        if (len < 0) {
322
-            return len;
323
-        }
324
-        retlen += len;
325
-        start = end + 2; // Skip '\xff' end and '\x00' start 
326
-        framecount++;
327
-    } while (end < (src+srclength-1));
328
-    if (framecount > 1) {
329
-        //snprintf(cntstr, 3, "%d", framecount);
330
-        snprintf(cntstr, 4, "%d",  framecount > 999 ? 999 : framecount);
331
-        traffic(cntstr);
332
-    }
333
-    *left = 0;
334
-    return retlen;
335
-}
336
-
337
-int encode_hybi(u_char const *src, size_t srclength,
338
-                char *target, size_t targsize, unsigned int opcode)
339
-{
340
-    unsigned long long payload_offset = 2;
341
-    int len = 0;
342
-
343
-    if (opcode != OPCODE_TEXT && opcode != OPCODE_BINARY) {
344
-        handler_emsg("Invalid opcode. Opcode must be 0x01 for text mode, or 0x02 for binary mode.\n");
345
-        return -1;
346
-    }
347
-
348
-    target[0] = (char)((opcode & 0x0F) | 0x80);
349
-
350
-    if ((int)srclength <= 0) {
351
-        return 0;
352
-    }
353
-
354
-    if (opcode & OPCODE_TEXT) {
355
-        len = ((srclength - 1) / 3) * 4 + 4;
356
-    } else {
357
-        len = srclength;
358
-    }
359
-
360
-    if (len <= 125) {
361
-        target[1] = (char) len;
362
-        payload_offset = 2;
363
-    } else if ((len > 125) && (len < 65536)) {
364
-        target[1] = (char) 126;
365
-        *(u_short*)&(target[2]) = htons(len);
366
-        payload_offset = 4;
367
-    } else {
368
-        handler_emsg("Sending frames larger than 65535 bytes not supported\n");
369
-        return -1;
370
-        //target[1] = (char) 127;
371
-        //*(u_long*)&(target[2]) = htonl(b64_sz);
372
-        //payload_offset = 10;
373
-    }
374
-
375
-    if (opcode & OPCODE_TEXT) {
376
-        len = ws_b64_ntop(src, srclength, target+payload_offset, targsize-payload_offset);
377
-    } else {
378
-        memcpy(target+payload_offset, src, srclength);
379
-        len = srclength;
380
-    }
381
-
382
-    if (len < 0) {
383
-        return len;
384
-    }
385
-
386
-    return len + payload_offset;
387
-}
388
-
389
-int decode_hybi(unsigned char *src, size_t srclength,
390
-                u_char *target, size_t targsize,
391
-                unsigned int *opcode, unsigned int *left)
392
-{
393
-    unsigned char *frame, *mask, *payload, save_char;
394
-    char cntstr[4];
395
-    int masked = 0;
396
-    int i = 0, len, framecount = 0;
397
-    size_t remaining;
398
-    unsigned int target_offset = 0, hdr_length = 0, payload_length = 0;
399
-    
400
-    *left = srclength;
401
-    frame = src;
402
-
403
-    //printf("Deocde new frame\n");
404
-    while (1) {
405
-        // Need at least two bytes of the header
406
-        // Find beginning of next frame. First time hdr_length, masked and
407
-        // payload_length are zero
408
-        frame += hdr_length + 4*masked + payload_length;
409
-        //printf("frame[0..3]: 0x%x 0x%x 0x%x 0x%x (tot: %d)\n",
410
-        //       (unsigned char) frame[0],
411
-        //       (unsigned char) frame[1],
412
-        //       (unsigned char) frame[2],
413
-        //       (unsigned char) frame[3], srclength);
414
-
415
-        if (frame > src + srclength) {
416
-            //printf("Truncated frame from client, need %d more bytes\n", frame - (src + srclength) );
417
-            break;
418
-        }
419
-        remaining = (src + srclength) - frame;
420
-        if (remaining < 2) {
421
-            //printf("Truncated frame header from client\n");
422
-            break;
423
-        }
424
-        framecount ++;
425
-
426
-        *opcode = frame[0] & 0x0f;
427
-        masked = (frame[1] & 0x80) >> 7;
428
-
429
-        if (*opcode == 0x8) {
430
-            // client sent orderly close frame
431
-            break;
432
-        }
433
-
434
-        payload_length = frame[1] & 0x7f;
435
-        if (payload_length < 126) {
436
-            hdr_length = 2;
437
-            //frame += 2 * sizeof(char);
438
-        } else if (payload_length == 126) {
439
-            payload_length = (frame[2] << 8) + frame[3];
440
-            hdr_length = 4;
441
-        } else {
442
-            handler_emsg("Receiving frames larger than 65535 bytes not supported\n");
443
-            return -1;
444
-        }
445
-        if ((hdr_length + 4*masked + payload_length) > remaining) {
446
-            continue;
447
-        }
448
-        //printf("    payload_length: %u, raw remaining: %u\n", payload_length, remaining);
449
-        payload = frame + hdr_length + 4*masked;
450
-
451
-        if (*opcode != OPCODE_TEXT && *opcode != OPCODE_BINARY) {
452
-            handler_msg("Ignoring non-data frame, opcode 0x%x\n", *opcode);
453
-            continue;
454
-        }
455
-
456
-        if (payload_length == 0) {
457
-            handler_msg("Ignoring empty frame\n");
458
-            continue;
459
-        }
460
-
461
-        if ((payload_length > 0) && (!masked)) {
462
-            handler_emsg("Received unmasked payload from client\n");
463
-            return -1;
464
-        }
465
-
466
-        // Terminate with a null for base64 decode
467
-        save_char = payload[payload_length];
468
-        payload[payload_length] = '\0';
469
-
470
-        // unmask the data
471
-        mask = payload - 4;
472
-        for (i = 0; i < payload_length; i++) {
473
-            payload[i] ^= mask[i%4];
474
-        }
475
-
476
-        if (*opcode & OPCODE_TEXT) {
477
-            // base64 decode the data
478
-            len = ws_b64_pton((const char*)payload, target+target_offset, targsize);
479
-        } else {
480
-            memcpy(target+target_offset, payload, payload_length);
481
-            len = payload_length;
482
-        }
483
-
484
-        // Restore the first character of the next frame
485
-        payload[payload_length] = save_char;
486
-        if (len < 0) {
487
-            handler_emsg("Base64 decode error code %d", len);
488
-            return len;
489
-        }
490
-        target_offset += len;
491
-
492
-        //printf("    len %d, raw %s\n", len, frame);
493
-    }
494
-
495
-    if (framecount > 1) {
496
-        //snprintf(cntstr, 3, "%d", framecount);
497
-        snprintf(cntstr, 4, "%d",  framecount > 999 ? 999 : framecount);
498
-        traffic(cntstr);
499
-    }
500
-    
501
-    *left = remaining;
502
-    return target_offset;
503
-}
504
-
505
-
506
-
507
-int parse_handshake(ws_ctx_t *ws_ctx, char *handshake) {
508
-    char *start, *end;
509
-    headers_t *headers = ws_ctx->headers;
510
-
511
-    headers->key1[0] = '\0';
512
-    headers->key2[0] = '\0';
513
-    headers->key3[0] = '\0';
514
-    
515
-    if ((strlen(handshake) < 92) || (bcmp(handshake, "GET ", 4) != 0)) {
516
-        return 0;
517
-    }
518
-    start = handshake+4;
519
-    end = strstr(start, " HTTP/1.1");
520
-    if (!end) { return 0; }
521
-    strncpy(headers->path, start, end-start);
522
-    headers->path[end-start] = '\0';
523
-
524
-    start = strstr(handshake, "\r\nHost: ");
525
-    if (!start) { return 0; }
526
-    start += 8;
527
-    end = strstr(start, "\r\n");
528
-    strncpy(headers->host, start, end-start);
529
-    headers->host[end-start] = '\0';
530
-
531
-    headers->origin[0] = '\0';
532
-    start = strstr(handshake, "\r\nOrigin: ");
533
-    if (start) {
534
-        start += 10;
535
-    } else {
536
-        start = strstr(handshake, "\r\nSec-WebSocket-Origin: ");
537
-        if (!start) { return 0; }
538
-        start += 24;
539
-    }
540
-    end = strstr(start, "\r\n");
541
-    strncpy(headers->origin, start, end-start);
542
-    headers->origin[end-start] = '\0';
543
-   
544
-    start = strstr(handshake, "\r\nSec-WebSocket-Version: ");
545
-    if (start) {
546
-        // HyBi/RFC 6455
547
-        start += 25;
548
-        end = strstr(start, "\r\n");
549
-        strncpy(headers->version, start, end-start);
550
-        headers->version[end-start] = '\0';
551
-        ws_ctx->hixie = 0;
552
-        ws_ctx->hybi = strtol(headers->version, NULL, 10);
553
-
554
-        start = strstr(handshake, "\r\nSec-WebSocket-Key: ");
555
-        if (!start) { return 0; }
556
-        start += 21;
557
-        end = strstr(start, "\r\n");
558
-        strncpy(headers->key1, start, end-start);
559
-        headers->key1[end-start] = '\0';
560
-   
561
-        start = strstr(handshake, "\r\nConnection: ");
562
-        if (!start) { return 0; }
563
-        start += 14;
564
-        end = strstr(start, "\r\n");
565
-        strncpy(headers->connection, start, end-start);
566
-        headers->connection[end-start] = '\0';
567
-   
568
-        start = strstr(handshake, "\r\nSec-WebSocket-Protocol: ");
569
-        if (!start) { return 0; }
570
-        start += 26;
571
-        end = strstr(start, "\r\n");
572
-        strncpy(headers->protocols, start, end-start);
573
-        headers->protocols[end-start] = '\0';
574
-    } else {
575
-        // Hixie 75 or 76
576
-        ws_ctx->hybi = 0;
577
-
578
-        start = strstr(handshake, "\r\n\r\n");
579
-        if (!start) { return 0; }
580
-        start += 4;
581
-        if (strlen(start) == 8) {
582
-            ws_ctx->hixie = 76;
583
-            strncpy(headers->key3, start, 8);
584
-            headers->key3[8] = '\0';
585
-
586
-            start = strstr(handshake, "\r\nSec-WebSocket-Key1: ");
587
-            if (!start) { return 0; }
588
-            start += 22;
589
-            end = strstr(start, "\r\n");
590
-            strncpy(headers->key1, start, end-start);
591
-            headers->key1[end-start] = '\0';
592
-        
593
-            start = strstr(handshake, "\r\nSec-WebSocket-Key2: ");
594
-            if (!start) { return 0; }
595
-            start += 22;
596
-            end = strstr(start, "\r\n");
597
-            strncpy(headers->key2, start, end-start);
598
-            headers->key2[end-start] = '\0';
599
-        } else {
600
-            ws_ctx->hixie = 75;
601
-        }
602
-
603
-    }
604
-
605
-    return 1;
606
-}
607
-
608
-int parse_hixie76_key(char * key) {
609
-    unsigned long i, spaces = 0, num = 0;
610
-    for (i=0; i < strlen(key); i++) {
611
-        if (key[i] == ' ') {
612
-            spaces += 1;
613
-        }
614
-        if ((key[i] >= 48) && (key[i] <= 57)) {
615
-            num = num * 10 + (key[i] - 48);
616
-        }
617
-    }
618
-    return num / spaces;
619
-}
620
-
621
-int gen_md5(headers_t *headers, char *target) {
622
-    unsigned long key1 = parse_hixie76_key(headers->key1);
623
-    unsigned long key2 = parse_hixie76_key(headers->key2);
624
-    char *key3 = headers->key3;
625
-
626
-    MD5_CTX c;
627
-    char in[HIXIE_MD5_DIGEST_LENGTH] = {
628
-        key1 >> 24, key1 >> 16, key1 >> 8, key1,
629
-        key2 >> 24, key2 >> 16, key2 >> 8, key2,
630
-        key3[0], key3[1], key3[2], key3[3],
631
-        key3[4], key3[5], key3[6], key3[7]
632
-    };
633
-
634
-    MD5_Init(&c);
635
-    MD5_Update(&c, (void *)in, sizeof in);
636
-    MD5_Final((void *)target, &c);
637
-
638
-    target[HIXIE_MD5_DIGEST_LENGTH] = '\0';
639
-
640
-    return 1;
641
-}
642
-
643
-static void gen_sha1(headers_t *headers, char *target) {
644
-    SHA_CTX c;
645
-    unsigned char hash[SHA_DIGEST_LENGTH];
646
-    int r;
647
-
648
-    SHA1_Init(&c);
649
-    SHA1_Update(&c, headers->key1, strlen(headers->key1));
650
-    SHA1_Update(&c, HYBI_GUID, 36);
651
-    SHA1_Final(hash, &c);
652
-
653
-    r = ws_b64_ntop(hash, sizeof hash, target, HYBI10_ACCEPTHDRLEN);
654
-    //assert(r == HYBI10_ACCEPTHDRLEN - 1);
655
-}
656
-
657
-
658
-ws_ctx_t *do_handshake(int sock) {
659
-    char handshake[4096], response[4096], sha1[29], trailer[17];
660
-    char *scheme, *pre;
661
-    headers_t *headers;
662
-    int len, ret, i, offset;
663
-    ws_ctx_t * ws_ctx;
664
-    char *response_protocol;
665
-
666
-    // Peek, but don't read the data
667
-    len = recv(sock, handshake, 1024, MSG_PEEK);
668
-    handshake[len] = 0;
669
-    if (len == 0) {
670
-        handler_msg("ignoring empty handshake\n");
671
-        return NULL;
672
-    } else if ((bcmp(handshake, "\x16", 1) == 0) ||
673
-               (bcmp(handshake, "\x80", 1) == 0)) {
674
-        // SSL
675
-        if (!settings.cert) {
676
-            handler_msg("SSL connection but no cert specified\n");
677
-            return NULL;
678
-        } else if (access(settings.cert, R_OK) != 0) {
679
-            handler_msg("SSL connection but '%s' not found\n",
680
-                        settings.cert);
681
-            return NULL;
682
-        }
683
-        ws_ctx = alloc_ws_ctx();
684
-        ws_socket_ssl(ws_ctx, sock, settings.cert, settings.key);
685
-        if (! ws_ctx) { return NULL; }
686
-        scheme = "wss";
687
-        handler_msg("using SSL socket\n");
688
-    } else if (settings.ssl_only) {
689
-        handler_msg("non-SSL connection disallowed\n");
690
-        return NULL;
691
-    } else {
692
-        ws_ctx = alloc_ws_ctx();
693
-        ws_socket(ws_ctx, sock);
694
-        if (! ws_ctx) { return NULL; }
695
-        scheme = "ws";
696
-        handler_msg("using plain (not SSL) socket\n");
697
-    }
698
-    offset = 0;
699
-    for (i = 0; i < 10; i++) {
700
-        /* (offset + 1): reserve one byte for the trailing '\0' */
701
-        if (0 > (len = ws_recv(ws_ctx, handshake + offset, sizeof(handshake) - (offset + 1)))) {
702
-            handler_emsg("Read error during handshake: %m\n");
703
-            free_ws_ctx(ws_ctx);
704
-            return NULL;
705
-        } else if (0 == len) {
706
-            handler_emsg("Client closed during handshake\n");
707
-            free_ws_ctx(ws_ctx);
708
-            return NULL;
709
-        }
710
-        offset += len;
711
-        handshake[offset] = 0;
712
-        if (strstr(handshake, "\r\n\r\n")) {
713
-            break;
714
-        } else if (sizeof(handshake) <= (size_t)(offset + 1)) {
715
-            handler_emsg("Oversized handshake\n");
716
-            free_ws_ctx(ws_ctx);
717
-            return NULL;
718
-        } else if (9 == i) {
719
-            handler_emsg("Incomplete handshake\n");
720
-            free_ws_ctx(ws_ctx);
721
-            return NULL;
722
-        }
723
-        usleep(10);
724
-    }
725
-
726
-    //handler_msg("handshake: %s\n", handshake);
727
-    if (!parse_handshake(ws_ctx, handshake)) {
728
-        handler_emsg("Invalid WS request\n");
729
-        free_ws_ctx(ws_ctx);
730
-        return NULL;
731
-    }
732
-
733
-    headers = ws_ctx->headers;
734
-
735
-    response_protocol = strtok(headers->protocols, ",");
736
-    if (!response_protocol || !strlen(response_protocol)) {
737
-        ws_ctx->opcode = OPCODE_BINARY;
738
-        response_protocol = "null";
739
-    } else if (!strcmp(response_protocol, "base64")) {
740
-      ws_ctx->opcode = OPCODE_TEXT;
741
-    } else {
742
-        ws_ctx->opcode = OPCODE_BINARY;
743
-    }
744
-
745
-    if (ws_ctx->hybi > 0) {
746
-        handler_msg("using protocol HyBi/IETF 6455 %d\n", ws_ctx->hybi);
747
-        gen_sha1(headers, sha1);
748
-        snprintf(response, sizeof(response), SERVER_HANDSHAKE_HYBI, sha1, response_protocol);
749
-    } else {
750
-        if (ws_ctx->hixie == 76) {
751
-            handler_msg("using protocol Hixie 76\n");
752
-            gen_md5(headers, trailer);
753
-            pre = "Sec-";
754
-        } else {
755
-            handler_msg("using protocol Hixie 75\n");
756
-            trailer[0] = '\0';
757
-            pre = "";
758
-        }
759
-        snprintf(response, sizeof(response), SERVER_HANDSHAKE_HIXIE, pre, headers->origin,
760
-                 pre, scheme, headers->host, headers->path, pre, "base64", trailer);
761
-    }
762
-    
763
-    //handler_msg("response: %s\n", response);
764
-    ws_send(ws_ctx, response, strlen(response));
765
-
766
-    return ws_ctx;
767
-}
768
-
769
-void signal_handler(int sig) {
770
-    switch (sig) {
771
-        case SIGHUP: break; // ignore for now
772
-        case SIGPIPE: pipe_error = 1; break; // handle inline
773
-        case SIGTERM: exit(0); break;
774
-    }
775
-}
776
-
777
-void daemonize(int keepfd) {
778
-    int pid, i;
779
-
780
-    umask(0);
781
-    if (!chdir("/")) { handler_emsg("Unable to chdir(\"/\").\n"); }
782
-    if (!setgid(getgid())) { handler_emsg("Unable to setgid().\n"); }
783
-    if (!setuid(getuid())) { handler_emsg("Unable to setuid().\n"); }
784
-
785
-    /* Double fork to daemonize */
786
-    pid = fork();
787
-    if (pid<0) { fatal("fork error"); }
788
-    if (pid>0) { exit(0); }  // parent exits
789
-    setsid();                // Obtain new process group
790
-    pid = fork();
791
-    if (pid<0) { fatal("fork error"); }
792
-    if (pid>0) { exit(0); }  // parent exits
793
-
794
-    /* Signal handling */
795
-    signal(SIGHUP, signal_handler);   // catch HUP
796
-    signal(SIGTERM, signal_handler);  // catch kill
797
-
798
-    /* Close open files */
799
-    for (i=getdtablesize(); i>=0; --i) {
800
-        if (i != keepfd) {
801
-            close(i);
802
-        } else if (settings.verbose) {
803
-            printf("keeping fd %d\n", keepfd);
804
-        }
805
-    }
806
-    i=open("/dev/null", O_RDWR);  // Redirect stdin
807
-    if (!dup(i)) { handler_emsg("Unable redirect stdout.\n"); } // Redirect stdout
808
-    if (!dup(i)) { handler_emsg("Unable redirect stderr.\n"); } // Redirect stderr
809
-}
810
-
811
-
812
-void start_server() {
813
-    int lsock, csock, pid, sopt = 1, i;
814
-    struct sockaddr_in serv_addr, cli_addr;
815
-    socklen_t clilen;
816
-    ws_ctx_t *ws_ctx;
817
-
818
-
819
-    /* Initialize buffers */
820
-    lsock = socket(AF_INET, SOCK_STREAM, 0);
821
-    if (lsock < 0) { error("ERROR creating listener socket"); }
822
-    bzero((char *) &serv_addr, sizeof(serv_addr));
823
-    serv_addr.sin_family = AF_INET;
824
-    serv_addr.sin_port = htons(settings.listen_port);
825
-
826
-    /* Resolve listen address */
827
-    if (settings.listen_host && (settings.listen_host[0] != '\0')) {
828
-        if (resolve_host(&serv_addr.sin_addr, settings.listen_host) < -1) {
829
-            fatal("Could not resolve listen address");
830
-        }
831
-    } else {
832
-        serv_addr.sin_addr.s_addr = INADDR_ANY;
833
-    }
834
-
835
-    setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *)&sopt, sizeof(sopt));
836
-    if (bind(lsock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
837
-        fatal("ERROR on binding listener socket");
838
-    }
839
-    listen(lsock,100);
840
-
841
-    signal(SIGPIPE, signal_handler);  // catch pipe
842
-
843
-    if (settings.daemon) {
844
-        daemonize(lsock);
845
-    }
846
-
847
-
848
-    // Reep zombies
849
-    signal(SIGCHLD, SIG_IGN);
850
-
851
-    printf("Waiting for connections on %s:%d\n",
852
-            settings.listen_host, settings.listen_port);
853
-
854
-    while (1) {
855
-        clilen = sizeof(cli_addr);
856
-        pipe_error = 0;
857
-        pid = 0;
858
-        csock = accept(lsock, 
859
-                       (struct sockaddr *) &cli_addr, 
860
-                       &clilen);
861
-        if (csock < 0) {
862
-            error("ERROR on accept");
863
-            continue;
864
-        }
865
-        handler_msg("got client connection from %s\n",
866
-                    inet_ntoa(cli_addr.sin_addr));
867
-
868
-        if (!settings.run_once) {
869
-            handler_msg("forking handler process\n");
870
-            pid = fork();
871
-        }
872
-
873
-        if (pid == 0) {  // handler process
874
-            ws_ctx = do_handshake(csock);
875
-            if (settings.run_once) {
876
-                if (ws_ctx == NULL) {
877
-                    // Not a real WebSocket connection
878
-                    continue;
879
-                } else {
880
-                    // Successful connection, stop listening for new
881
-                    // connections
882
-                    close(lsock);
883
-                }
884
-            }
885
-            if (ws_ctx == NULL) {
886
-                handler_msg("No connection after handshake\n");
887
-                break;   // Child process exits
888
-            }
889
-
890
-            settings.handler(ws_ctx);
891
-            if (pipe_error) {
892
-                handler_emsg("Closing due to SIGPIPE\n");
893
-            }
894
-            break;   // Child process exits
895
-        } else {         // parent process
896
-            settings.handler_id += 1;
897
-            close(csock);
898
-        }
899
-    }
900
-    if (pid == 0) {
901
-        if (ws_ctx) {
902
-            ws_socket_free(ws_ctx);
903
-            free_ws_ctx(ws_ctx);
904
-        } else {
905
-            shutdown(csock, SHUT_RDWR);
906
-            close(csock);
907
-        }
908
-        handler_msg("handler exit\n");
909
-    } else {
910
-        handler_msg("websockify exit\n");
911
-    }
912
-
913
-}
914
-

+ 0
- 104
src/contrib/websocket.h View File

@@ -1,104 +0,0 @@
1
-#include <openssl/ssl.h>
2
-
3
-#define BUFSIZE 65536
4
-#define DBUFSIZE (BUFSIZE * 3) / 4 - 20
5
-
6
-#define SERVER_HANDSHAKE_HIXIE "HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
7
-Upgrade: WebSocket\r\n\
8
-Connection: Upgrade\r\n\
9
-%sWebSocket-Origin: %s\r\n\
10
-%sWebSocket-Location: %s://%s%s\r\n\
11
-%sWebSocket-Protocol: %s\r\n\
12
-\r\n%s"
13
-
14
-#define SERVER_HANDSHAKE_HYBI "HTTP/1.1 101 Switching Protocols\r\n\
15
-Upgrade: websocket\r\n\
16
-Connection: Upgrade\r\n\
17
-Sec-WebSocket-Accept: %s\r\n\
18
-Sec-WebSocket-Protocol: %s\r\n\
19
-\r\n"
20
-
21
-#define HYBI_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
22
-
23
-#define HYBI10_ACCEPTHDRLEN 29
24
-
25
-#define HIXIE_MD5_DIGEST_LENGTH 16
26
-
27
-#define POLICY_RESPONSE "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>\n"
28
-
29
-#define OPCODE_TEXT    0x01
30
-#define OPCODE_BINARY  0x02
31
-
32
-typedef struct {
33
-    char path[1024+1];
34
-    char host[1024+1];
35
-    char origin[1024+1];
36
-    char version[1024+1];
37
-    char connection[1024+1];
38
-    char protocols[1024+1];
39
-    char key1[1024+1];
40
-    char key2[1024+1];
41
-    char key3[8+1];
42
-} headers_t;
43
-
44
-typedef struct {
45
-    int        sockfd;
46
-    SSL_CTX   *ssl_ctx;
47
-    SSL       *ssl;
48
-    int        hixie;
49
-    int        hybi;
50
-    int        opcode;
51
-    headers_t *headers;
52
-    char      *cin_buf;
53
-    char      *cout_buf;
54
-    char      *tin_buf;
55
-    char      *tout_buf;
56
-} ws_ctx_t;
57
-
58
-typedef struct {
59
-    int verbose;
60
-    char listen_host[256];
61
-    int listen_port;
62
-    void (*handler)(ws_ctx_t*);
63
-    int handler_id;
64
-    char *cert;
65
-    char *key;
66
-    int ssl_only;
67
-    int daemon;
68
-    int run_once;
69
-} settings_t;
70
-
71
-
72
-int resolve_host(struct in_addr *sin_addr, const char *hostname);
73
-
74
-ssize_t ws_recv(ws_ctx_t *ctx, void *buf, size_t len);
75
-
76
-ssize_t ws_send(ws_ctx_t *ctx, const void *buf, size_t len);
77
-
78
-/* base64.c declarations */
79
-//int b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize);
80
-//int b64_pton(char const *src, u_char *target, size_t targsize);
81
-
82
-#define gen_handler_msg(stream, ...) \
83
-    if (! settings.daemon) { \
84
-        fprintf(stream, "  %d: ", settings.handler_id); \
85
-        fprintf(stream, __VA_ARGS__); \
86
-    }
87
-
88
-#define handler_msg(...) gen_handler_msg(stdout, __VA_ARGS__);
89
-#define handler_emsg(...) gen_handler_msg(stderr, __VA_ARGS__);
90
-
91
-void traffic(const char * token);
92
-
93
-int encode_hixie(u_char const *src, size_t srclength,
94
-                 char *target, size_t targsize);
95
-int decode_hixie(char *src, size_t srclength,
96
-                 u_char *target, size_t targsize,
97
-                 unsigned int *opcode, unsigned int *left);
98
-int encode_hybi(u_char const *src, size_t srclength,
99
-                char *target, size_t targsize, unsigned int opcode);
100
-int decode_hybi(unsigned char *src, size_t srclength,
101
-                u_char *target, size_t targsize,
102
-                unsigned int *opcode, unsigned int *left);
103
-
104
-void start_server();

+ 0
- 388
src/contrib/websockify.c View File

@@ -1,388 +0,0 @@
1
-/*
2
- * A WebSocket to TCP socket proxy with support for "wss://" encryption.
3
- * Copyright 2010 Joel Martin
4
- * Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
5
- *
6
- * You can make a cert/key with openssl using:
7
- * openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
8
- * as taken from http://docs.python.org/dev/library/ssl.html#certificates
9
- */
10
-#include <stdio.h>
11
-#include <errno.h>
12
-#include <limits.h>
13
-#include <getopt.h>
14
-#include <string.h>
15
-#include <sys/socket.h>
16
-#include <netinet/in.h>
17
-#include <netdb.h>
18
-#include <sys/select.h>
19
-#include <fcntl.h>
20
-#include <unistd.h>
21
-#include <sys/stat.h>
22
-#include "websocket.h"
23
-
24
-char traffic_legend[] = "\n\
25
-Traffic Legend:\n\
26
-    }  - Client receive\n\
27
-    }. - Client receive partial\n\
28
-    {  - Target receive\n\
29
-\n\
30
-    >  - Target send\n\
31
-    >. - Target send partial\n\
32
-    <  - Client send\n\
33
-    <. - Client send partial\n\
34
-";
35
-
36
-char USAGE[] = "Usage: [options] " \
37
-               "[source_addr:]source_port target_addr:target_port\n\n" \
38
-               "  --verbose|-v       verbose messages and per frame traffic\n" \
39
-               "  --daemon|-D        become a daemon (background process)\n" \
40
-               "  --run-once         handle a single WebSocket connection and exit\n" \
41
-               "  --cert CERT        SSL certificate file\n" \
42
-               "  --key KEY          SSL key file (if separate from cert)\n" \
43
-               "  --ssl-only         disallow non-encrypted connections";
44
-
45
-#define usage(fmt, args...) \
46
-    fprintf(stderr, "%s\n\n", USAGE); \
47
-    fprintf(stderr, fmt , ## args); \
48
-    exit(1);
49
-
50
-char target_host[256];
51
-int target_port;
52
-
53
-extern int pipe_error;
54
-extern settings_t settings;
55
-
56
-void do_proxy(ws_ctx_t *ws_ctx, int target) {
57
-    fd_set rlist, wlist, elist;
58
-    struct timeval tv;
59
-    int i, maxfd, client = ws_ctx->sockfd;
60
-    unsigned int opcode, left, ret;
61
-    unsigned int tout_start, tout_end, cout_start, cout_end;
62
-    unsigned int tin_start, tin_end;
63
-    ssize_t len, bytes;
64
-
65
-    tout_start = tout_end = cout_start = cout_end;
66
-    tin_start = tin_end = 0;
67
-    maxfd = client > target ? client+1 : target+1;
68
-
69
-    while (1) {
70
-        tv.tv_sec = 1;
71
-        tv.tv_usec = 0;
72
-
73
-        FD_ZERO(&rlist);
74
-        FD_ZERO(&wlist);
75
-        FD_ZERO(&elist);
76
-
77
-        FD_SET(client, &elist);
78
-        FD_SET(target, &elist);
79
-
80
-        if (tout_end == tout_start) {
81
-            // Nothing queued for target, so read from client
82
-            FD_SET(client, &rlist);
83
-        } else {
84
-            // Data queued for target, so write to it
85
-            FD_SET(target, &wlist);
86
-        }
87
-        if (cout_end == cout_start) {
88
-            // Nothing queued for client, so read from target
89
-            FD_SET(target, &rlist);
90
-        } else {
91
-            // Data queued for client, so write to it
92
-            FD_SET(client, &wlist);
93
-        }
94
-
95
-        ret = select(maxfd, &rlist, &wlist, &elist, &tv);
96
-        if (pipe_error) { break; }
97
-
98
-        if (FD_ISSET(target, &elist)) {
99
-            handler_emsg("target exception\n");
100
-            break;
101
-        }
102
-        if (FD_ISSET(client, &elist)) {
103
-            handler_emsg("client exception\n");
104
-            break;
105
-        }
106
-
107
-        if (ret == -1) {
108
-            handler_emsg("select(): %s\n", strerror(errno));
109
-            break;
110
-        } else if (ret == 0) {
111
-            //handler_emsg("select timeout\n");
112
-            continue;
113
-        }
114
-
115
-        if (FD_ISSET(target, &wlist)) {
116
-            len = tout_end-tout_start;
117
-            bytes = send(target, ws_ctx->tout_buf + tout_start, len, 0);
118
-            if (pipe_error) { break; }
119
-            if (bytes < 0) {
120
-                handler_emsg("target connection error: %s\n",
121
-                             strerror(errno));
122
-                break;
123
-            }
124
-            tout_start += bytes;
125
-            if (tout_start >= tout_end) {
126
-                tout_start = tout_end = 0;
127
-                traffic(">");
128
-            } else {
129
-                traffic(">.");
130
-            }
131
-        }
132
-
133
-        if (FD_ISSET(client, &wlist)) {
134
-            len = cout_end-cout_start;
135
-            bytes = ws_send(ws_ctx, ws_ctx->cout_buf + cout_start, len);
136
-            if (pipe_error) { break; }
137
-            if (len < 3) {
138
-                handler_emsg("len: %d, bytes: %d: %d\n",
139
-                             (int) len, (int) bytes,
140
-                             (int) *(ws_ctx->cout_buf + cout_start));
141
-            }
142
-            cout_start += bytes;
143
-            if (cout_start >= cout_end) {
144
-                cout_start = cout_end = 0;
145
-                traffic("<");
146
-            } else {
147
-                traffic("<.");
148
-            }
149
-        }
150
-
151
-        if (FD_ISSET(target, &rlist)) {
152
-            bytes = recv(target, ws_ctx->cin_buf, DBUFSIZE , 0);
153
-            if (pipe_error) { break; }
154
-            if (bytes <= 0) {
155
-                handler_emsg("target closed connection\n");
156
-                break;
157
-            }
158
-            cout_start = 0;
159
-            if (ws_ctx->hybi) {
160
-                cout_end = encode_hybi(ws_ctx->cin_buf, bytes,
161
-                                   ws_ctx->cout_buf, BUFSIZE, ws_ctx->opcode);
162
-            } else {
163
-                cout_end = encode_hixie(ws_ctx->cin_buf, bytes,
164
-                                    ws_ctx->cout_buf, BUFSIZE);
165
-            }
166
-            /*
167
-            printf("encoded: ");
168
-            for (i=0; i< cout_end; i++) {
169
-                printf("%u,", (unsigned char) *(ws_ctx->cout_buf+i));
170
-            }
171
-            printf("\n");
172
-            */
173
-            if (cout_end < 0) {
174
-                handler_emsg("encoding error\n");
175
-                break;
176
-            }
177
-            traffic("{");
178
-        }
179
-
180
-        if (FD_ISSET(client, &rlist)) {
181
-            bytes = ws_recv(ws_ctx, ws_ctx->tin_buf + tin_end, BUFSIZE-1);
182
-            if (pipe_error) { break; }
183
-            if (bytes <= 0) {
184
-                handler_emsg("client closed connection\n");
185
-                break;
186
-            }
187
-            tin_end += bytes;
188
-            /*
189
-            printf("before decode: ");
190
-            for (i=0; i< bytes; i++) {
191
-                printf("%u,", (unsigned char) *(ws_ctx->tin_buf+i));
192
-            }
193
-            printf("\n");
194
-            */
195
-            if (ws_ctx->hybi) {
196
-                len = decode_hybi(ws_ctx->tin_buf + tin_start,
197
-                                  tin_end-tin_start,
198
-                                  ws_ctx->tout_buf, BUFSIZE-1,
199
-                                  &opcode, &left);
200
-            } else {
201
-                len = decode_hixie(ws_ctx->tin_buf + tin_start,
202
-                                   tin_end-tin_start,
203
-                                   ws_ctx->tout_buf, BUFSIZE-1,
204
-                                   &opcode, &left);
205
-            }
206
-
207
-            if (opcode == 8) {
208
-                handler_msg("client sent orderly close frame\n");
209
-                break;
210
-            }
211
-
212
-            /*
213
-            printf("decoded: ");
214
-            for (i=0; i< len; i++) {
215
-                printf("%u,", (unsigned char) *(ws_ctx->tout_buf+i));
216
-            }
217
-            printf("\n");
218
-            */
219
-            if (len < 0) {
220
-                handler_emsg("decoding error\n");
221
-                break;
222
-            }
223
-            if (left) {
224
-                tin_start = tin_end - left;
225
-                //printf("partial frame from client");
226
-            } else {
227
-                tin_start = 0;
228
-                tin_end = 0;
229
-            }
230
-
231
-            traffic("}");
232
-            tout_start = 0;
233
-            tout_end = len;
234
-        }
235
-    }
236
-}
237
-
238
-void proxy_handler(ws_ctx_t *ws_ctx) {
239
-    int tsock = 0;
240
-    struct sockaddr_in taddr;
241
-
242
-    handler_msg("connecting to: %s:%d\n", target_host, target_port);
243
-
244
-    tsock = socket(AF_INET, SOCK_STREAM, 0);
245
-    if (tsock < 0) {
246
-        handler_emsg("Could not create target socket: %s\n",
247
-                     strerror(errno));
248
-        return;
249
-    }
250
-    bzero((char *) &taddr, sizeof(taddr));
251
-    taddr.sin_family = AF_INET;
252
-    taddr.sin_port = htons(target_port);
253
-
254
-    /* Resolve target address */
255
-    if (resolve_host(&taddr.sin_addr, target_host) < -1) {
256
-        handler_emsg("Could not resolve target address: %s\n",
257
-                     strerror(errno));
258
-    }
259
-
260
-    if (connect(tsock, (struct sockaddr *) &taddr, sizeof(taddr)) < 0) {
261
-        handler_emsg("Could not connect to target: %s\n",
262
-                     strerror(errno));
263
-        close(tsock);
264
-        return;
265
-    }
266
-
267
-    if ((settings.verbose) && (! settings.daemon)) {
268
-        printf("%s", traffic_legend);
269
-    }
270
-
271
-    do_proxy(ws_ctx, tsock);
272
-
273
-    shutdown(tsock, SHUT_RDWR);
274
-    close(tsock);
275
-}
276
-
277
-int main(int argc, char *argv[])
278
-{
279
-    int fd, c, option_index = 0;
280
-    static int ssl_only = 0, daemon = 0, run_once = 0, verbose = 0;
281
-    char *found;
282
-    static struct option long_options[] = {
283
-        {"verbose",    no_argument,       &verbose,    'v'},
284
-        {"ssl-only",   no_argument,       &ssl_only,    1 },
285
-        {"daemon",     no_argument,       &daemon,     'D'},
286
-        /* ---- */
287
-        {"run-once",   no_argument,       0,           'r'},
288
-        {"cert",       required_argument, 0,           'c'},
289
-        {"key",        required_argument, 0,           'k'},
290
-        {0, 0, 0, 0}
291
-    };
292
-
293
-    settings.cert = realpath("self.pem", NULL);
294
-    if (!settings.cert) {
295
-        /* Make sure it's always set to something */
296
-        settings.cert = "self.pem";
297
-    }
298
-    settings.key = "";
299
-
300
-    while (1) {
301
-        c = getopt_long (argc, argv, "vDrc:k:",
302
-                         long_options, &option_index);
303
-
304
-        /* Detect the end */
305
-        if (c == -1) { break; }
306
-
307
-        switch (c) {
308
-            case 0:
309
-                break; // ignore
310
-            case 1:
311
-                break; // ignore
312
-            case 'v':
313
-                verbose = 1;
314
-                break;
315
-            case 'D':
316
-                daemon = 1;
317
-                break;
318
-            case 'r':
319
-                run_once = 1;
320
-                break;
321
-            case 'c':
322
-                settings.cert = realpath(optarg, NULL);
323
-                if (! settings.cert) {
324
-                    usage("No cert file at %s\n", optarg);
325
-                }
326
-                break;
327
-            case 'k':
328
-                settings.key = realpath(optarg, NULL);
329
-                if (! settings.key) {
330
-                    usage("No key file at %s\n", optarg);
331
-                }
332
-                break;
333
-            default:
334
-                usage("\n");
335
-        }
336
-    }
337
-    settings.verbose      = verbose;
338
-    settings.ssl_only     = ssl_only;
339
-    settings.daemon       = daemon;
340
-    settings.run_once     = run_once;
341
-
342
-    if ((argc-optind) != 2) {
343
-        usage("Invalid number of arguments\n");
344
-    }
345
-
346
-    found = strstr(argv[optind], ":");
347
-    if (found) {
348
-        memcpy(settings.listen_host, argv[optind], found-argv[optind]);
349
-        settings.listen_port = strtol(found+1, NULL, 10);
350
-    } else {
351
-        settings.listen_host[0] = '\0';
352
-        settings.listen_port = strtol(argv[optind], NULL, 10);
353
-    }
354
-    optind++;
355
-    if (settings.listen_port == 0) {
356
-        usage("Could not parse listen_port\n");
357
-    }
358
-
359
-    found = strstr(argv[optind], ":");
360
-    if (found) {
361
-        memcpy(target_host, argv[optind], found-argv[optind]);
362
-        target_port = strtol(found+1, NULL, 10);
363
-    } else {
364
-        usage("Target argument must be host:port\n");
365
-    }
366
-    if (target_port == 0) {
367
-        usage("Could not parse target port\n");
368
-    }
369
-
370
-    if (ssl_only) {
371
-        if (access(settings.cert, R_OK) != 0) {
372
-            usage("SSL only and cert file '%s' not found\n", settings.cert);
373
-        }
374
-    } else if (access(settings.cert, R_OK) != 0) {
375
-        fprintf(stderr, "Warning: '%s' not found\n", settings.cert);
376
-    }
377
-
378
-    //printf("  verbose: %d\n",   settings.verbose);
379
-    //printf("  ssl_only: %d\n",  settings.ssl_only);
380
-    //printf("  daemon: %d\n",    settings.daemon);
381
-    //printf("  run_once: %d\n",  settings.run_once);
382
-    //printf("  cert: %s\n",      settings.cert);
383
-    //printf("  key: %s\n",       settings.key);
384
-
385
-    settings.handler = proxy_handler; 
386
-    start_server();
387
-
388
-}

Loading…
Cancel
Save