Exemplo n.º 1
0
static int
ws_compute_handshake(struct http_client *c, unsigned char *out) {

	char buffer[16];
	md5_state_t ctx;

	// websocket handshake
	uint32_t number_1 = ws_read_key(client_get_header(c, "Sec-WebSocket-Key1"));
	uint32_t number_2 = ws_read_key(client_get_header(c, "Sec-WebSocket-Key2"));

	if(c->body_sz < 8) { /* we need at least 8 bytes */
		return -1;
	}

	/* copy number_1, number_2, and last 8 bytes of the body. */
	memcpy(buffer, &number_1, 4);
	memcpy(buffer + 4, &number_2, 4);
	memcpy(buffer + 8, c->body + c->body_sz - 8, 8);
	
	/* hash that buffer, that creates the handshake signature. */
	md5_init(&ctx);
	md5_append(&ctx, (const md5_byte_t *)buffer, sizeof(buffer));
	md5_finish(&ctx, out);

	return 0;
}
Exemplo n.º 2
0
Arquivo: acl.c Projeto: 9612jhf/webdis
int
acl_match_client(struct acl *a, struct http_client *client, in_addr_t *ip) {

	/* check HTTP Basic Auth */
	const char *auth;
	auth = client_get_header(client, "Authorization");
	if(a->http_basic_auth) {
		if(auth && strncasecmp(auth, "Basic ", 6) == 0) { /* sent auth */
			if(strcmp(auth + 6, a->http_basic_auth) != 0) { /* bad password */
				return 0;
			}
		} else { /* no auth sent, required to match this ACL */
			return 0;
		}
	}

	/* CIDR check. */
	if(a->cidr.enabled == 0) { /* none given, all match */
		return 1;
	}
	if(((*ip) & a->cidr.mask) == (a->cidr.subnet & a->cidr.mask)) {
		return 1;
	}

	return 0;
}
Exemplo n.º 3
0
static int
ws_compute_handshake(struct http_client *c, char *out, size_t *out_sz) {

	unsigned char *buffer, sha1_output[20];
	char magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
	SHA1Context ctx;
	base64_encodestate b64_ctx;
	int pos, i;

	// websocket handshake
	const char *key = client_get_header(c, "Sec-WebSocket-Key");
	size_t key_sz = key?strlen(key):0, buffer_sz = key_sz + sizeof(magic) - 1;
	buffer = calloc(buffer_sz, 1);

	// concatenate key and guid in buffer
	memcpy(buffer, key, key_sz);
	memcpy(buffer+key_sz, magic, sizeof(magic)-1);

	// compute sha-1
	SHA1Reset(&ctx);
	SHA1Input(&ctx, buffer, buffer_sz);
	SHA1Result(&ctx);
	for(i = 0; i < 5; ++i) {	// put in correct byte order before memcpy.
		ctx.Message_Digest[i] = ntohl(ctx.Message_Digest[i]);
	}
	memcpy(sha1_output, (unsigned char*)ctx.Message_Digest, 20);

	// encode `sha1_output' in base 64, into `out'.
	base64_init_encodestate(&b64_ctx);
	pos = base64_encode_block((const char*)sha1_output, 20, out, &b64_ctx);
	base64_encode_blockend(out + pos, &b64_ctx);

	// compute length, without \n
	*out_sz = strlen(out);
	if(out[*out_sz-1] == '\n')
		(*out_sz)--;

	free(buffer);

	return 0;
}
Exemplo n.º 4
0
int
ws_handshake_reply(struct http_client *c) {

	int ret;
	unsigned char md5_handshake[16];
	char *buffer = NULL, *p;
	const char *origin = NULL, *host = NULL;
	size_t origin_sz = 0, host_sz = 0, sz;

	char template0[] = "HTTP/1.1 101 Websocket Protocol Handshake\r\n"
		"Upgrade: WebSocket\r\n"
		"Connection: Upgrade\r\n"
		"Sec-WebSocket-Origin: "; /* %s */
	char template1[] = "\r\n"
		"Sec-WebSocket-Location: ws://"; /* %s%s */
	char template2[] = "\r\n"
		"Origin: http://"; /* %s */
	char template3[] = "\r\n\r\n";

	if((origin = client_get_header(c, "Origin"))) {
		origin_sz = strlen(origin);
	}
	if((host = client_get_header(c, "Host"))) {
		host_sz = strlen(host);
	}

	/* need those headers */
	if(!origin || !origin_sz || !host || !host_sz || !c->path || !c->path_sz) {
		return -1;
	}

	if(ws_compute_handshake(c, &md5_handshake[0]) != 0) {
		/* failed to compute handshake. */
		return -1;
	}

	sz = sizeof(template0)-1 + origin_sz
		+ sizeof(template1)-1 + host_sz + c->path_sz
		+ sizeof(template2)-1 + host_sz
		+ sizeof(template3)-1 + sizeof(md5_handshake);

	p = buffer = malloc(sz);

	/* Concat all */

	/* template0 */
	memcpy(p, template0, sizeof(template0)-1); 
	p += sizeof(template0)-1;
	memcpy(p, origin, origin_sz);
	p += origin_sz;

	/* template1 */
	memcpy(p, template1, sizeof(template1)-1); 
	p += sizeof(template1)-1;
	memcpy(p, host, host_sz);
	p += host_sz;
	memcpy(p, c->path, c->path_sz);
	p += c->path_sz;

	/* template2 */
	memcpy(p, template2, sizeof(template2)-1); 
	p += sizeof(template2)-1;
	memcpy(p, host, host_sz);
	p += host_sz;

	/* template3 */
	memcpy(p, template3, sizeof(template3)-1); 
	p += sizeof(template3)-1;
	memcpy(p, &md5_handshake[0], sizeof(md5_handshake));

	ret = write(c->fd, buffer, sz);
	(void)ret;
	free(buffer);

	return 0;
}