added SSL
This commit is contained in:
parent
d9ee2c56f2
commit
670e38a105
8 changed files with 142 additions and 22 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1,5 @@
|
|||
**/*.o
|
||||
**/*.swp
|
||||
**/*.pem
|
||||
asfur
|
||||
config.h
|
||||
|
|
|
|||
7
Makefile
7
Makefile
|
|
@ -3,8 +3,9 @@
|
|||
include config.mk
|
||||
|
||||
SRC = main.c\
|
||||
password.c
|
||||
HDR = config.def.h client.h
|
||||
password.c\
|
||||
network.c
|
||||
HDR = config.def.h client.h password.h network.h
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
all: options asfur
|
||||
|
|
@ -18,7 +19,7 @@ options:
|
|||
.c.o:
|
||||
${CC} -c ${CFLAGS} $<
|
||||
|
||||
${OBJ}: config.h client.h
|
||||
${OBJ}: config.h client.h password.h network.h
|
||||
|
||||
config.h:
|
||||
cp config.def.h $@
|
||||
|
|
|
|||
20
PROTOCOL
Normal file
20
PROTOCOL
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
for client:
|
||||
server parses packets from left to right like this:
|
||||
[u16 length][u8 type][char *data]
|
||||
|
||||
length: the length of the entire packet
|
||||
type:
|
||||
PACKET_ERROR = 0
|
||||
PACKET_REGISTER = 1
|
||||
PACKET_AUTHENTICATE = 2
|
||||
PACKET_JOIN = 3
|
||||
PACKET_TEXT = 4
|
||||
PACKET_LEAVE = 5
|
||||
|
||||
data: bytes of data, what it could represent depends on the packet type
|
||||
(following layouts are layouts for data byte array)
|
||||
PACKET_REGISTER : [char username[20]][char password[20]]
|
||||
PACKET_AUTHENTICATE : [char username[20]][char password[20]]
|
||||
PACKET_JOIN : []
|
||||
PACKET_TEXT :
|
||||
PACKET_LEAVE :
|
||||
4
client.h
4
client.h
|
|
@ -2,11 +2,15 @@
|
|||
#define CLIENT_H
|
||||
|
||||
#include <uv.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct client {
|
||||
uv_tcp_t handle;
|
||||
SSL *ssl;
|
||||
BIO *rbio;
|
||||
BIO *wbio;
|
||||
uint32_t user_id;
|
||||
uint32_t current_room_id;
|
||||
bool is_authenticated;
|
||||
|
|
|
|||
|
|
@ -2,3 +2,5 @@
|
|||
|
||||
#define CONFIG_ALLOW_REGISTER true
|
||||
|
||||
#define CONFIG_CERT_FILE "cert.pem"
|
||||
#define CONFIG_KEY_FILE "key.pem"
|
||||
|
|
|
|||
109
main.c
109
main.c
|
|
@ -3,46 +3,89 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
#include <pthread.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include "client.h"
|
||||
|
||||
uv_loop_t *loop;
|
||||
SSL_CTX *ctx;
|
||||
|
||||
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
|
||||
void cleanup_client(uv_handle_t *handle)
|
||||
{
|
||||
(void)handle;
|
||||
buf->base = (char*) malloc(suggested_size);
|
||||
buf->len = suggested_size;
|
||||
struct client *client = (struct client*) handle;
|
||||
if (client->ssl) {
|
||||
SSL_free(client->ssl);
|
||||
}
|
||||
free(client);
|
||||
}
|
||||
|
||||
void echo_write(uv_write_t *req, int status)
|
||||
void on_write_end(uv_write_t *req, int status)
|
||||
{
|
||||
if (status) {
|
||||
if (status < 0) {
|
||||
fprintf(stderr, "Write error %s\n", uv_strerror(status));
|
||||
}
|
||||
free(req->data);
|
||||
free(req);
|
||||
}
|
||||
|
||||
void on_close(uv_handle_t *handle)
|
||||
void flush_ssl_to_socket(struct client *client)
|
||||
{
|
||||
free(handle);
|
||||
char buf[4096];
|
||||
int pending;
|
||||
|
||||
while ((pending = BIO_pending(client->wbio)) > 0) {
|
||||
int bytes_read = BIO_read(client->wbio, buf, sizeof(buf));
|
||||
if (bytes_read > 0) {
|
||||
uv_write_t *req = malloc(sizeof(uv_write_t));
|
||||
char *send_data = malloc(bytes_read);
|
||||
memcpy(send_data, buf, bytes_read);
|
||||
|
||||
req->data = send_data;
|
||||
|
||||
uv_buf_t uvbuf = uv_buf_init(send_data, bytes_read);
|
||||
uv_write(req, (uv_stream_t*)&client->handle, &uvbuf, 1, on_write_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void on_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf)
|
||||
void ssl_write_msg(struct client *client, const char *data, size_t len)
|
||||
{
|
||||
int written = SSL_write(client->ssl, data, len);
|
||||
if (written > 0) {
|
||||
flush_ssl_to_socket(client);
|
||||
}
|
||||
}
|
||||
|
||||
void on_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
struct client *client = (struct client*) stream;
|
||||
|
||||
if (nread > 0) {
|
||||
uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t));
|
||||
uv_buf_t wrbuf = uv_buf_init(buf->base, nread);
|
||||
uv_write(req, client, &wrbuf, 1, echo_write);
|
||||
BIO_write(client->rbio, buf->base, nread);
|
||||
|
||||
char plain_buf[4096];
|
||||
int p;
|
||||
|
||||
while ((p = SSL_read(client->ssl, plain_buf, sizeof(plain_buf))) > 0) {
|
||||
ssl_write_msg(client, plain_buf, p);
|
||||
}
|
||||
|
||||
flush_ssl_to_socket(client);
|
||||
}
|
||||
if (nread < 0) {
|
||||
if (nread != UV_EOF)
|
||||
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
|
||||
uv_close((uv_handle_t*) client, on_close);
|
||||
else if (nread < 0) {
|
||||
if (nread != UV_EOF) fprintf(stderr, "Read error %s\n", uv_err_name(nread));
|
||||
uv_close((uv_handle_t*) client, cleanup_client);
|
||||
}
|
||||
|
||||
free(buf->base);
|
||||
}
|
||||
|
||||
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
|
||||
{
|
||||
buf->base = malloc(suggested_size);
|
||||
buf->len = suggested_size;
|
||||
}
|
||||
|
||||
void on_new_connection(uv_stream_t *server, int status)
|
||||
{
|
||||
if (status < 0) {
|
||||
|
|
@ -52,15 +95,43 @@ void on_new_connection(uv_stream_t *server, int status)
|
|||
|
||||
struct client *client = malloc(sizeof(struct client));
|
||||
uv_tcp_init(loop, &client->handle);
|
||||
|
||||
if (uv_accept(server, (uv_stream_t*) &client->handle) == 0) {
|
||||
client->ssl = SSL_new(ctx);
|
||||
client->rbio = BIO_new(BIO_s_mem());
|
||||
client->wbio = BIO_new(BIO_s_mem());
|
||||
SSL_set_bio(client->ssl, client->rbio, client->wbio);
|
||||
SSL_set_accept_state(client->ssl);
|
||||
|
||||
uv_read_start((uv_stream_t*) &client->handle, alloc_buffer, on_read);
|
||||
} else {
|
||||
uv_close((uv_handle_t*) &client->handle, on_close);
|
||||
uv_close((uv_handle_t*) &client->handle, cleanup_client);
|
||||
}
|
||||
}
|
||||
|
||||
void init_openssl()
|
||||
{
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_ssl_algorithms();
|
||||
ctx = SSL_CTX_new(TLS_server_method());
|
||||
if (!ctx) {
|
||||
perror("Unable to create SSL context");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
|
||||
|
||||
if (SSL_CTX_use_certificate_file(ctx, CONFIG_CERT_FILE, SSL_FILETYPE_PEM) <= 0 ||
|
||||
SSL_CTX_use_PrivateKey_file(ctx, CONFIG_KEY_FILE, SSL_FILETYPE_PEM) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
init_openssl();
|
||||
loop = uv_default_loop();
|
||||
|
||||
uv_tcp_t server;
|
||||
|
|
@ -76,5 +147,7 @@ int main()
|
|||
fprintf(stderr, "Listen error %s\n", uv_strerror(r));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("server listening on port 7000...\n");
|
||||
return uv_run(loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
|
|
|||
7
network.c
Normal file
7
network.c
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#define _GNU_SOURCE
|
||||
#include "network.h"
|
||||
|
||||
void network_parse_packet()
|
||||
{
|
||||
|
||||
}
|
||||
11
network.h
Normal file
11
network.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct packet_header {
|
||||
uint16_t size;
|
||||
uint8_t type;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue