temporary-satori-hole/src/websock/websock_handshake.c
2023-12-27 01:35:22 +01:00

72 lines
2.4 KiB
C

#include <sys/random.h>
#include "websock.h"
#define SAT_WEBSOCK_HANDSHAKE_UNIQUE "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
#define SAT_WEBSOCK_HANDSHAKE_VERSION_10 "HTTP/1.0 "
#define SAT_WEBSOCK_HANDSHAKE_VERSION_11 "HTTP/1.1 "
#define SAT_WEBSOCK_HANDSHAKE_LINE_END (0x0D0A)
sat_websock_handshake_ptr sat_websock_handshake_alloc(void) {
sat_websock_handshake_ptr hs = malloc(sizeof(sat_websock_handshake));
memset(hs, 0, sizeof(sat_websock_handshake));
return hs;
}
void sat_websock_handshake_free(sat_websock_handshake_ptr hs, bool freeArg) {
if(hs == NULL) return;
if(freeArg) free(hs);
}
int sat_websock_handshake_gen_key(sat_websock_handshake_ptr hs) {
return getrandom(hs->key, 16, 0);
}
int sat_websock_handshake_send(sat_websock_handshake_ptr hs) {
char buffer[1024] = {0};
size_t count = 0;
count += sprintf(buffer + count, "GET %s HTTP/1.1\r\n", hs->path);
count += sprintf(buffer + count, "Host: %s\r\n", hs->host);
count += sprintf(buffer + count, "Upgrade: websocket\r\n");
count += sprintf(buffer + count, "Connection: Upgrade\r\n");
count += sprintf(buffer + count, "Sec-WebSocket-Version: 13\r\n");
count += sprintf(buffer + count, "Sec-WebSocket-Key: %s\r\n", hs->key);
if(hs->origin != NULL) count += sprintf(buffer + count, "Origin: %s\r\n", hs->origin);
if(hs->protocol != NULL) count += sprintf(buffer + count, "Sec-WebSocket-Protocol: %s\r\n", hs->protocol);
count += sprintf(buffer + count, "\r\n");
return sat_websock_send(hs->websock, (uint8_t*)buffer, count);
}
int sat_websock_handshake_recv(sat_websock_handshake_ptr hs) {
char buffer[1024] = {0};
sat_websock_buffer(hs->websock, 100);
int expect = strlen(SAT_WEBSOCK_HANDSHAKE_VERSION_11);
int read = sat_websock_recv(hs->websock, (uint8_t*)buffer, expect);
if(read != expect) return -1;
if(strcmp(SAT_WEBSOCK_HANDSHAKE_VERSION_11, buffer) != 0
&& strcmp(SAT_WEBSOCK_HANDSHAKE_VERSION_10, buffer) != 0)
return -2;
uint16_t checkCrLf = 0;
int i;
for(i = 0; i < sizeof buffer && checkCrLf != SAT_WEBSOCK_HANDSHAKE_LINE_END; ++i) {
buffer[i] = sat_buffer_getc(hs->websock->buffer);
checkCrLf <<= 8;
checkCrLf |= buffer[i];
}
buffer[i] = '\0';
if(sscanf(buffer, "%hd %s", &hs->statusCode, hs->statusReason) != 2)
return -3;
hs->completed = true;
hs->upgraded = hs->statusCode == 101;
return 0;
}