mirror of
https://github.com/Links2004/arduinoWebSockets.git
synced 2025-07-12 23:16:29 +02:00
authentication is working
add libb64 for base64 support (todo get espressif base64 working)
This commit is contained in:
@ -25,6 +25,12 @@
|
||||
#include "WebSockets.h"
|
||||
#include "WebSocketsServer.h"
|
||||
|
||||
extern "C" {
|
||||
#include "libb64/cencode.h"
|
||||
}
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
WebSocketsServer::WebSocketsServer(uint16_t port) {
|
||||
_port = port;
|
||||
_server = new WiFiServer(port);
|
||||
@ -179,7 +185,6 @@ void WebSocketsServer::handleClientData(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
[WS-Server][0] new client from 192.168.2.23
|
||||
[WS-Server][0][handleHeader] RX: GET /test HTTP/1.1
|
||||
@ -208,7 +213,6 @@ void WebSocketsServer::handleHeader(WSclients_t * client) {
|
||||
String headerLine = client->tcp.readStringUntil('\n');
|
||||
headerLine.trim(); // remove \r
|
||||
|
||||
|
||||
if(headerLine.length() > 0) {
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine.c_str());
|
||||
|
||||
@ -226,6 +230,7 @@ void WebSocketsServer::handleHeader(WSclients_t * client) {
|
||||
} else if(headerLine.startsWith("Sec-WebSocket-Key: ")) {
|
||||
// 19 = lenght of "Sec-WebSocket-Key: "
|
||||
client->cKey = headerLine.substring(19);
|
||||
client->cKey.trim(); // see rfc6455
|
||||
} else if(headerLine.startsWith("Sec-WebSocket-Protocol: ")) {
|
||||
// 24 = lenght of "Sec-WebSocket-Protocol: "
|
||||
client->cProtocol = headerLine.substring(24);
|
||||
@ -263,12 +268,39 @@ void WebSocketsServer::handleHeader(WSclients_t * client) {
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", client->num);
|
||||
|
||||
//todo generate server key
|
||||
|
||||
//client->sKey.c_str();
|
||||
// generate Sec-WebSocket-Accept key
|
||||
uint8_t sha1HashBin[20] = {0};
|
||||
sha1(client->cKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]);
|
||||
|
||||
char sha1Base64[64] = { 0 };
|
||||
int len = 0;
|
||||
|
||||
base64_encodestate _state;
|
||||
base64_init_encodestate(&_state);
|
||||
len = base64_encode_block((const char *)&sha1HashBin[0], 20, &sha1Base64[0], &_state);
|
||||
base64_encode_blockend((sha1Base64 + len), &_state);
|
||||
|
||||
client->sKey = sha1Base64;
|
||||
client->sKey.trim();
|
||||
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - sKey: %s\n", client->num, client->sKey.c_str());
|
||||
|
||||
client->status = WSC_CONNECTED;
|
||||
|
||||
client->tcp.write("HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Server: ESP8266-WebSocketsServer\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n"
|
||||
"Sec-WebSocket-Accept: ");
|
||||
client->tcp.write(client->sKey.c_str(), client->sKey.length());
|
||||
client->tcp.write("\r\n"
|
||||
"Sec-WebSocket-Protocol: ");
|
||||
client->tcp.write(client->cProtocol.c_str(), client->cProtocol.length()); // support any protocol for now
|
||||
client->tcp.write("\r\n"
|
||||
"\r\n");
|
||||
|
||||
//client->status = WSC_CONNECTED;
|
||||
} else {
|
||||
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num);
|
||||
client->tcp.write("HTTP/1.1 400 Bad Request\r\n"
|
||||
|
7
src/libb64/AUTHORS
Normal file
7
src/libb64/AUTHORS
Normal file
@ -0,0 +1,7 @@
|
||||
libb64: Base64 Encoding/Decoding Routines
|
||||
======================================
|
||||
|
||||
Authors:
|
||||
-------
|
||||
|
||||
Chris Venter chris.venter@gmail.com http://rocketpod.blogspot.com
|
29
src/libb64/LICENSE
Normal file
29
src/libb64/LICENSE
Normal file
@ -0,0 +1,29 @@
|
||||
Copyright-Only Dedication (based on United States law)
|
||||
or Public Domain Certification
|
||||
|
||||
The person or persons who have associated work with this document (the
|
||||
"Dedicator" or "Certifier") hereby either (a) certifies that, to the best of
|
||||
his knowledge, the work of authorship identified is in the public domain of the
|
||||
country from which the work is published, or (b) hereby dedicates whatever
|
||||
copyright the dedicators holds in the work of authorship identified below (the
|
||||
"Work") to the public domain. A certifier, moreover, dedicates any copyright
|
||||
interest he may have in the associated work, and for these purposes, is
|
||||
described as a "dedicator" below.
|
||||
|
||||
A certifier has taken reasonable steps to verify the copyright status of this
|
||||
work. Certifier recognizes that his good faith efforts may not shield him from
|
||||
liability if in fact the work certified is not in the public domain.
|
||||
|
||||
Dedicator makes this dedication for the benefit of the public at large and to
|
||||
the detriment of the Dedicator's heirs and successors. Dedicator intends this
|
||||
dedication to be an overt act of relinquishment in perpetuity of all present
|
||||
and future rights under copyright law, whether vested or contingent, in the
|
||||
Work. Dedicator understands that such relinquishment of all rights includes
|
||||
the relinquishment of all rights to enforce (by lawsuit or otherwise) those
|
||||
copyrights in the Work.
|
||||
|
||||
Dedicator recognizes that, once placed in the public domain, the Work may be
|
||||
freely reproduced, distributed, transmitted, used, modified, built upon, or
|
||||
otherwise exploited by anyone for any purpose, commercial or non-commercial,
|
||||
and in any way, including by methods that have not yet been invented or
|
||||
conceived.
|
88
src/libb64/cdecode.c
Normal file
88
src/libb64/cdecode.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
cdecoder.c - c source to a base64 decoding algorithm implementation
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#include "cdecode.h"
|
||||
|
||||
int base64_decode_value(char value_in)
|
||||
{
|
||||
static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
|
||||
static const char decoding_size = sizeof(decoding);
|
||||
value_in -= 43;
|
||||
if (value_in < 0 || value_in > decoding_size) return -1;
|
||||
return decoding[(int)value_in];
|
||||
}
|
||||
|
||||
void base64_init_decodestate(base64_decodestate* state_in)
|
||||
{
|
||||
state_in->step = step_a;
|
||||
state_in->plainchar = 0;
|
||||
}
|
||||
|
||||
int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in)
|
||||
{
|
||||
const char* codechar = code_in;
|
||||
char* plainchar = plaintext_out;
|
||||
char fragment;
|
||||
|
||||
*plainchar = state_in->plainchar;
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
case step_a:
|
||||
do {
|
||||
if (codechar == code_in+length_in)
|
||||
{
|
||||
state_in->step = step_a;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (char)base64_decode_value(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar = (fragment & 0x03f) << 2;
|
||||
case step_b:
|
||||
do {
|
||||
if (codechar == code_in+length_in)
|
||||
{
|
||||
state_in->step = step_b;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (char)base64_decode_value(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x030) >> 4;
|
||||
*plainchar = (fragment & 0x00f) << 4;
|
||||
case step_c:
|
||||
do {
|
||||
if (codechar == code_in+length_in)
|
||||
{
|
||||
state_in->step = step_c;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (char)base64_decode_value(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x03c) >> 2;
|
||||
*plainchar = (fragment & 0x003) << 6;
|
||||
case step_d:
|
||||
do {
|
||||
if (codechar == code_in+length_in)
|
||||
{
|
||||
state_in->step = step_d;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (char)base64_decode_value(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x03f);
|
||||
}
|
||||
}
|
||||
/* control should not reach here */
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
|
28
src/libb64/cdecode.h
Normal file
28
src/libb64/cdecode.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
cdecode.h - c header for a base64 decoding algorithm
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#ifndef BASE64_CDECODE_H
|
||||
#define BASE64_CDECODE_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
step_a, step_b, step_c, step_d
|
||||
} base64_decodestep;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
base64_decodestep step;
|
||||
char plainchar;
|
||||
} base64_decodestate;
|
||||
|
||||
void base64_init_decodestate(base64_decodestate* state_in);
|
||||
|
||||
int base64_decode_value(char value_in);
|
||||
|
||||
int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in);
|
||||
|
||||
#endif /* BASE64_CDECODE_H */
|
109
src/libb64/cencode.c
Normal file
109
src/libb64/cencode.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
cencoder.c - c source to a base64 encoding algorithm implementation
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#include "cencode.h"
|
||||
|
||||
const int CHARS_PER_LINE = 72;
|
||||
|
||||
void base64_init_encodestate(base64_encodestate* state_in)
|
||||
{
|
||||
state_in->step = step_A;
|
||||
state_in->result = 0;
|
||||
state_in->stepcount = 0;
|
||||
}
|
||||
|
||||
char base64_encode_value(char value_in)
|
||||
{
|
||||
static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
if (value_in > 63) return '=';
|
||||
return encoding[(int)value_in];
|
||||
}
|
||||
|
||||
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
|
||||
{
|
||||
const char* plainchar = plaintext_in;
|
||||
const char* const plaintextend = plaintext_in + length_in;
|
||||
char* codechar = code_out;
|
||||
char result;
|
||||
char fragment;
|
||||
|
||||
result = state_in->result;
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
case step_A:
|
||||
if (plainchar == plaintextend)
|
||||
{
|
||||
state_in->result = result;
|
||||
state_in->step = step_A;
|
||||
return codechar - code_out;
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result = (fragment & 0x0fc) >> 2;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x003) << 4;
|
||||
case step_B:
|
||||
if (plainchar == plaintextend)
|
||||
{
|
||||
state_in->result = result;
|
||||
state_in->step = step_B;
|
||||
return codechar - code_out;
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result |= (fragment & 0x0f0) >> 4;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x00f) << 2;
|
||||
case step_C:
|
||||
if (plainchar == plaintextend)
|
||||
{
|
||||
state_in->result = result;
|
||||
state_in->step = step_C;
|
||||
return codechar - code_out;
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result |= (fragment & 0x0c0) >> 6;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x03f) >> 0;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
|
||||
++(state_in->stepcount);
|
||||
if (state_in->stepcount == CHARS_PER_LINE/4)
|
||||
{
|
||||
*codechar++ = '\n';
|
||||
state_in->stepcount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* control should not reach here */
|
||||
return codechar - code_out;
|
||||
}
|
||||
|
||||
int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
|
||||
{
|
||||
char* codechar = code_out;
|
||||
|
||||
switch (state_in->step)
|
||||
{
|
||||
case step_B:
|
||||
*codechar++ = base64_encode_value(state_in->result);
|
||||
*codechar++ = '=';
|
||||
*codechar++ = '=';
|
||||
break;
|
||||
case step_C:
|
||||
*codechar++ = base64_encode_value(state_in->result);
|
||||
*codechar++ = '=';
|
||||
break;
|
||||
case step_A:
|
||||
break;
|
||||
}
|
||||
*codechar++ = '\n';
|
||||
|
||||
return codechar - code_out;
|
||||
}
|
||||
|
31
src/libb64/cencode.h
Normal file
31
src/libb64/cencode.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
cencode.h - c header for a base64 encoding algorithm
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#ifndef BASE64_CENCODE_H
|
||||
#define BASE64_CENCODE_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
step_A, step_B, step_C
|
||||
} base64_encodestep;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
base64_encodestep step;
|
||||
char result;
|
||||
int stepcount;
|
||||
} base64_encodestate;
|
||||
|
||||
void base64_init_encodestate(base64_encodestate* state_in);
|
||||
|
||||
char base64_encode_value(char value_in);
|
||||
|
||||
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
|
||||
|
||||
int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
|
||||
|
||||
#endif /* BASE64_CENCODE_H */
|
Reference in New Issue
Block a user