From 93d17e32d2c64a187bda4e4c7b0162072ab77c9c Mon Sep 17 00:00:00 2001 From: Nick White Date: Tue, 28 Jul 2015 16:20:28 +0100 Subject: Add SSL support using OpenSSL, and enable it for getgbook. This fixes the problem with getgbook not finding any books, and also obviously adds SSL, which is great! --- util.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 20 deletions(-) (limited to 'util.c') diff --git a/util.c b/util.c index 238dc8e..eaee2d5 100644 --- a/util.c +++ b/util.c @@ -14,17 +14,20 @@ #endif /* plundered from suckless' sic */ -int dial(char *host, char *port) +conn *dial(char *host, char *port, int ssl) { static struct addrinfo hints; int srv; struct addrinfo *res, *r; + conn *c; + c = malloc(sizeof(conn)); + c->fd = -1; #ifdef WINVER WSADATA w; if(WSAStartup(MAKEWORD(2,2), &w)!= 0) { fprintf(stderr, "error: failed to start winsock\n"); - return -1; + return c; } #endif @@ -33,7 +36,7 @@ int dial(char *host, char *port) hints.ai_socktype = SOCK_STREAM; if(getaddrinfo(host, port, &hints, &res) != 0) { fprintf(stderr, "error: cannot resolve hostname %s\n", host); - return -1; + return c; } for(r = res; r; r = r->ai_next) { if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) @@ -45,31 +48,80 @@ int dial(char *host, char *port) freeaddrinfo(res); if(!r) { fprintf(stderr, "error: cannot connect to host %s\n", host); - return -1; + return c; } - return srv; + + c->fd = srv; + c->sslcontext = NULL; + c->sslhandle = NULL; + + if(ssl) { + SSL_load_error_strings(); + SSL_library_init(); + if((c->sslcontext = SSL_CTX_new(SSLv23_client_method())) == NULL) { + /*if((c->sslcontext = SSL_CTX_new(TLS_client_method())) == NULL) {*/ + ERR_print_errors_fp(stderr); + } + if((c->sslhandle = SSL_new(c->sslcontext)) == NULL) { + ERR_print_errors_fp(stderr); + } + if(SSL_set_fd(c->sslhandle, c->fd) != 1) { + ERR_print_errors_fp(stderr); + } + if(SSL_connect(c->sslhandle) != 1) { + ERR_print_errors_fp(stderr); + } + + } + return c; } -int request(char *host, char *request, char *savecookie, char **body, int istext) +int request(char *host, int ssl, char *request, char *savecookie, char **body, int istext) { size_t l, res; - int fd, i, p; + int i, p; char m[256]; - char c[COOKIEMAX] = ""; + char cookie[COOKIEMAX] = ""; + char port[4]; char *headpos; size_t headsize, bodysize; char headline[BUFSIZ] = ""; char *buf, *cur, *pos; + conn *c; - if((fd = dial(host, "80")) == -1) return 0; + if(ssl) { + strcpy(port, "443"); + } else { + strcpy(port, "80"); + } + c = dial(host, port, ssl); + if(c->fd == -1) { + return 0; + } - if(!send(fd, request, strlen(request), 0)) return 0; + if(ssl) { + if(!SSL_write(c->sslhandle, request, strlen(request))) { + ERR_print_errors_fp(stderr); + return 0; + } + } else { + if(!write(c->fd, request, strlen(request))) { + return 0; + } + } /* download everything into buf */ l = 0; buf = malloc(sizeof(char *) * BUFSIZ); - for(; buf != NULL && (res = recv(fd, buf+l, BUFSIZ, 0)) > 0; l+=res) - buf = realloc(buf, sizeof(char *) * (l+BUFSIZ)); + /* TODO: rewrite this so it's clear that only the read call differs, e.g. with + * macros as ii does it, or maybe as a function pointer or something */ + if(ssl) { + for(; buf != NULL && (res = SSL_read(c->sslhandle, buf+l, BUFSIZ)) > 0; l+=res) + buf = realloc(buf, sizeof(char *) * (l+BUFSIZ)); + } else { + for(; buf != NULL && (res = read(c->fd, buf+l, BUFSIZ)) > 0; l+=res) + buf = realloc(buf, sizeof(char *) * (l+BUFSIZ)); + } /* strstr to find end of header */ if((headpos = strstr(buf, "\r\n\r\n")) == NULL) { @@ -109,8 +161,8 @@ int request(char *host, char *request, char *savecookie, char **body, int istext return 0; } - if(savecookie != NULL && sscanf(headline, m, c)) { - strncat(savecookie, c, COOKIEMAX - strlen(savecookie) - 1); + if(savecookie != NULL && sscanf(headline, m, cookie)) { + strncat(savecookie, cookie, COOKIEMAX - strlen(savecookie) - 1); } } @@ -119,7 +171,7 @@ int request(char *host, char *request, char *savecookie, char **body, int istext return l; } -int get(char *host, char *path, char *sendcookie, char *savecookie, char **body, int istext) +int get(char *host, int ssl, char *path, char *sendcookie, char *savecookie, char **body, int istext) { char h[BUFSIZ] = ""; char c[COOKIEMAX] = ""; @@ -129,10 +181,10 @@ int get(char *host, char *path, char *sendcookie, char *savecookie, char **body, snprintf(h, BUFSIZ, "GET %s HTTP/1.0\r\nUser-Agent: getxbook-"VERSION \ " (not mozilla)\r\nHost: %s%s\r\n\r\n", path, host, c); - return request(host, h, savecookie, body, istext); + return request(host, ssl, h, savecookie, body, istext); } -int post(char *host, char *path, char *sendcookie, char *savecookie, char *data, char **body, int istext) +int post(char *host, int ssl, char *path, char *sendcookie, char *savecookie, char *data, char **body, int istext) { char h[BUFSIZ] = ""; char c[COOKIEMAX] = ""; @@ -145,16 +197,16 @@ int post(char *host, char *path, char *sendcookie, char *savecookie, char *data, "Host: %s%s\r\n\r\n%s\r\n", path, (int)strlen(data), host, c, data); - return request(host, h, savecookie, body, istext); + return request(host, ssl, h, savecookie, body, istext); } -int gettofile(char *host, char *url, char *sendcookie, char *savecookie, char *savepath, int istext) +int gettofile(char *host, int ssl, char *url, char *sendcookie, char *savecookie, char *savepath, int istext) { char *buf = 0; FILE *f; size_t i, l; - if(!(l = get(host, url, sendcookie, savecookie, &buf, istext))) { + if(!(l = get(host, ssl, url, sendcookie, savecookie, &buf, istext))) { fprintf(stderr, "Could not download %s\n", url); return 1; } -- cgit v1.2.3