summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authorNick White <git@njw.name>2015-07-28 16:20:28 +0100
committerNick White <git@njw.name>2015-07-28 16:20:28 +0100
commit93d17e32d2c64a187bda4e4c7b0162072ab77c9c (patch)
treefca76e0fe070609572a676866f887eca76cd59a0 /util.c
parent0e05096f98d957d90a59eff0b5a081d112fd329f (diff)
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!
Diffstat (limited to 'util.c')
-rw-r--r--util.c92
1 files changed, 72 insertions, 20 deletions
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;
}