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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>
#include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/rand.h>
#include <event.h> #include <event2/listener.h> #include <event2/bufferevent_ssl.h>
#define SERVER_CRT "server.crt" #define SERVER_KEY "server.key" #define SERVER_PORT 9999 static void ssl_readcb(struct bufferevent * bev, void * arg) { struct evbuffer *in = bufferevent_get_input(bev);
printf("Received %zu bytes\n", evbuffer_get_length(in)); printf("----- data ----\n"); printf("%.*s\n", (int)evbuffer_get_length(in), evbuffer_pullup(in, -1));
bufferevent_write_buffer(bev, in); }
static void ssl_acceptcb(struct evconnlistener *serv, int sock, struct sockaddr *sa, int sa_len, void *arg) { struct event_base *evbase; struct bufferevent *bev; SSL_CTX *server_ctx; SSL *client_ctx;
server_ctx = (SSL_CTX *)arg; client_ctx = SSL_new(server_ctx); evbase = evconnlistener_get_base(serv);
bev = bufferevent_openssl_socket_new(evbase, sock, client_ctx, BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE);
bufferevent_enable(bev, EV_READ); bufferevent_setcb(bev, ssl_readcb, NULL, NULL, NULL); }
static SSL_CTX * evssl_init(void) { SSL_CTX *server_ctx;
SSL_load_error_strings(); SSL_library_init(); if (!RAND_poll()) return NULL;
server_ctx = SSL_CTX_new(SSLv23_server_method());
if (! SSL_CTX_use_certificate_chain_file(server_ctx, SERVER_CRT) || ! SSL_CTX_use_PrivateKey_file(server_ctx, SERVER_KEY, SSL_FILETYPE_PEM)) { puts("Couldn't read 'server.key' or 'server.crt' file. To generate a key\n" "To generate a key and certificate, run:\n" " openssl genrsa -out server.key 2048\n" " openssl req -new -key server.key -out server.crt.req\n" " openssl x509 -req -days 365 -in server.crt.req -signkey server.key -out server.crt"); return NULL; } SSL_CTX_set_options(server_ctx, SSL_OP_NO_SSLv2);
return server_ctx; }
int main(int argc, char **argv) { SSL_CTX *ctx; struct evconnlistener *listener; struct event_base *evbase; struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(SERVER_PORT); sin.sin_addr.s_addr = htonl(0x7f000001);
ctx = evssl_init(); if (ctx == NULL){ return 1; } evbase = event_base_new(); listener = evconnlistener_new_bind( evbase, ssl_acceptcb, (void *)ctx, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024, (struct sockaddr *)&sin, sizeof(sin));
event_base_loop(evbase, 0);
evconnlistener_free(listener); SSL_CTX_free(ctx);
return 0; }
|