summaryrefslogtreecommitdiff
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
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!
-rw-r--r--config.mk8
-rw-r--r--getabook.c7
-rw-r--r--getbnbook.c7
-rw-r--r--getgbook.c9
-rw-r--r--util.c92
-rw-r--r--util.h15
6 files changed, 101 insertions, 37 deletions
diff --git a/config.mk b/config.mk
index d366072..948e8b4 100644
--- a/config.mk
+++ b/config.mk
@@ -6,6 +6,8 @@ RELDATE = 2013-10-13
PREFIX = /usr/local
MANPREFIX = $(PREFIX)/share/man
+LIBS = -lssl -lcrypto
+
CFLAGS = -std=c99 -pedantic -Wall -Wextra -Werror -g -D_POSIX_C_SOURCE=200112L \
-DVERSION=\"$(VERSION)\"
@@ -13,16 +15,16 @@ W32TCLKIT = tclkit-8.5.9-win32.upx.exe
# glibc dynamic
CC = cc
-LDFLAGS =
+LDFLAGS = $(LIBS)
# musl static
#CC = musl-gcc
-#LDFLAGS = -static #-s
+#LDFLAGS = $(LIBS) -static #-s
# mingw
#CC = i686-w64-mingw32-gcc
#AR = i686-w64-mingw32-ar
#CFLAGS = -ansi -Wall -DVERSION=\"$(VERSION)\" -DWINVER=0x0501
-#LDFLAGS = -lws2_32
+#LDFLAGS = $(LIBS) -lws2_32
LD = $(CC)
diff --git a/getabook.c b/getabook.c
index db4ca96..5f85143 100644
--- a/getabook.c
+++ b/getabook.c
@@ -15,6 +15,7 @@
" -n download pages from numbers in stdin\n" \
" otherwise, all available pages will be downloaded\n"
+#define USESSL 0
#define URLMAX 1024
#define STRMAX 1024
#define MAXPAGES 9999
@@ -74,7 +75,7 @@ int getpagelist()
snprintf(url, URLMAX, "/gp/search-inside/service-data?method=getBookData&asin=%s", bookid);
- if(!get("www.amazon.com", url, NULL, NULL, &buf, 1))
+ if(!get("www.amazon.com", USESSL, url, NULL, NULL, &buf, 1))
return 1;
/* amazon have a canonical asin, which is needed to get all available pages */
@@ -132,7 +133,7 @@ int getpageurls(int pagenum)
strncpy(url, "/gp/search-inside/service-data", URLMAX);
snprintf(query, URLMAX, "method=goToPage&asin=%s&page=%d", bookid, pagenum);
- if(!post("www.amazon.com", url, NULL, NULL, query, &buf, 1))
+ if(!post("www.amazon.com", USESSL, url, NULL, NULL, query, &buf, 1))
return 1;
fillurls(buf);
@@ -158,7 +159,7 @@ int getpage(Page *page)
return 1;
}
- if(gettofile(host, page->url, NULL, NULL, path, 0)) {
+ if(gettofile(host, USESSL, page->url, NULL, NULL, path, 0)) {
fprintf(stderr, "%d failed\n", page->num);
return 1;
}
diff --git a/getbnbook.c b/getbnbook.c
index 6fa247f..a63416d 100644
--- a/getbnbook.c
+++ b/getbnbook.c
@@ -15,6 +15,7 @@
" -n download pages from numbers in stdin\n" \
" otherwise, all available pages will be downloaded\n"
+#define USESSL 0
#define URLMAX 1024
#define STRMAX 1024
#define MAXPAGES 9999
@@ -38,7 +39,7 @@ int getpagelist()
snprintf(url, URLMAX, "/DigBooks/viewer/bookviewmanager.aspx?op=getbookinfo&ean=%s", bookid);
- if(!get("search2.barnesandnoble.com", url, cookies, NULL, &buf, 1))
+ if(!get("search2.barnesandnoble.com", USESSL, url, cookies, NULL, &buf, 1))
return 1;
/* find page url structure */
@@ -81,7 +82,7 @@ int getpage(int pagenum)
s=strchr(urlpath+7, '/');
snprintf(pageurl, STRMAX, s, pagenum);
- if(gettofile("search2.barnesandnoble.com", pageurl, cookies, NULL, path, 0)) {
+ if(gettofile("search2.barnesandnoble.com", USESSL, pageurl, cookies, NULL, path, 0)) {
fprintf(stderr, "%d failed\n", pagenum);
return 1;
}
@@ -113,7 +114,7 @@ int main(int argc, char *argv[])
bookdir = argv[argc-1];
/* get cookie */
- if(get("www.barnesandnoble.com", "/", NULL, cookies, &tmp, 0))
+ if(get("www.barnesandnoble.com", USESSL, "/", NULL, cookies, &tmp, 0))
free(tmp);
if(getpagelist()) {
diff --git a/getgbook.c b/getgbook.c
index e6e15af..5e36c04 100644
--- a/getgbook.c
+++ b/getgbook.c
@@ -16,6 +16,7 @@
" -n download pages from numbers in stdin\n" \
" otherwise, all available pages will be downloaded\n"
+#define USESSL 1
#define URLMAX 1024
#define STRMAX 1024
#define MAXPAGES 9999
@@ -44,7 +45,7 @@ int getpagelist()
snprintf(url, URLMAX, "/books?id=%s&printsec=frontcover&redir_esc=y", bookid);
- if(!get("books.google.com", url, NULL, NULL, &buf, 1))
+ if(!get("books.google.com", USESSL, url, NULL, NULL, &buf, 1))
return 1;
if((s = strstr(buf, "_OC_Run({\"page\":[")) == NULL)
@@ -83,7 +84,7 @@ int getpageurls(char *pagecode, char *cookie)
snprintf(url, URLMAX, "/books?id=%s&pg=%s&jscmd=click3&q=subject:a&redir_esc=y", bookid, pagecode);
- if(!get("books.google.com", url, cookie, NULL, &buf, 1))
+ if(!get("books.google.com", USESSL, url, cookie, NULL, &buf, 1))
return 1;
c = buf;
@@ -137,7 +138,7 @@ int getpage(Page *page)
return 1;
}
- if(gettofile("books.google.com", page->url, page->cookie, NULL, path, 0)) {
+ if(gettofile("books.google.com", USESSL, page->url, page->cookie, NULL, path, 0)) {
fprintf(stderr, "%s failed\n", page->name);
return 1;
}
@@ -188,7 +189,7 @@ int main(int argc, char *argv[])
/* get cookies */
for(i=0;i<COOKIENUM;i++) {
- if(get("books.google.com", "/", NULL, cookies[i], &tmp, 0))
+ if(get("books.google.com", USESSL, "/", NULL, cookies[i], &tmp, 0))
free(tmp);
}
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;
}
diff --git a/util.h b/util.h
index 6959ddc..a48a12e 100644
--- a/util.h
+++ b/util.h
@@ -1,7 +1,14 @@
/* See COPYING file for copyright and license details. */
#define COOKIEMAX 1024
-int dial(char *host, char *port);
-int get(char *host, char *path, char *sendcookie, char *savecookie, char **body, int istext);
-int post(char *host, char *path, char *sendcookie, char *savecookie, char *data, char **body, int istext);
-int gettofile(char *host, char *url, char *sendcookie, char *savecookie, char *savepath, int istext);
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+typedef struct {
+ int fd;
+ SSL *sslhandle;
+ SSL_CTX *sslcontext;
+} conn;
+conn *dial(char *host, char *port, int ssl);
+int get(char *host, int ssl, char *path, char *sendcookie, char *savecookie, char **body, int istext);
+int post(char *host, int ssl, char *path, char *sendcookie, char *savecookie, char *data, char **body, int istext);
+int gettofile(char *host, int ssl, char *url, char *sendcookie, char *savecookie, char *savepath, int istext);
int renameifjpg(char *path);