Created
February 13, 2015 12:27
-
-
Save komeda-shinji/c23a5f0d57886f36b53e to your computer and use it in GitHub Desktop.
corkscrewをSSLなプロキシに対応させた ref: http://qiita.com/komeda-shinji/items/8a78f07cc7d0d75d37c0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
usage: corkscrew [-ssl] <proxyhost> <proxyport> <desthost> <destport> [authfile] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
make LDADD="-lcrypto -lssl" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% diff -u corkscrew-2.0/corkscrew.c corkscrew-2.0/corkscrew.c | |
--- corkscrew-2.0/corkscrew.c 2001-08-24 03:27:32.000000000 +0900 | |
+++ corkscrew-2.0/corkscrew.c 2014-11-11 19:35:08.000000000 +0900 | |
@@ -12,6 +12,12 @@ | |
#include <sys/types.h> | |
#include <unistd.h> | |
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
+#include <openssl/ssl.h> | |
+#include <openssl/err.h> | |
+ | |
+#define CHK_NULL(x) if ((x)==NULL) { fprintf(stderr, "NULL pointer\n"); exit(-1); } | |
+ | |
#if HAVE_SYS_FILIO_H | |
#include <sys/filio.h> | |
#endif | |
@@ -27,7 +33,7 @@ | |
char *base64_encodei PARAMS((char *in)); | |
void usage PARAMS((void)); | |
-int sock_connect PARAMS((const char *hname, int port)); | |
+int sock_connect PARAMS((int fd, const char *hname, int port)); | |
int main PARAMS((int argc, char *argv[])); | |
#define BUFSIZE 4096 | |
@@ -132,21 +138,17 @@ | |
} | |
#ifdef ANSI_FUNC | |
-int sock_connect (const char *hname, int port) | |
+int sock_connect (int fd, const char *hname, int port) | |
#else | |
-int sock_connect (hname, port) | |
+int sock_connect (fd, hname, port) | |
+int fd; | |
const char *hname; | |
int port; | |
#endif | |
{ | |
- int fd; | |
struct sockaddr_in addr; | |
struct hostent *hent; | |
- fd = socket(AF_INET, SOCK_STREAM, 0); | |
- if (fd == -1) | |
- return -1; | |
- | |
hent = gethostbyname(hname); | |
if (hent == NULL) | |
addr.sin_addr.s_addr = inet_addr(hname); | |
@@ -181,32 +183,52 @@ | |
struct timeval tv; | |
ssize_t len; | |
FILE *fp; | |
+ int use_ssl = 0; | |
+ char **av; | |
+ int ac; | |
+ int n; | |
+ char *p; | |
+ SSL_METHOD *ssl_meth; | |
+ SSL_CTX* ctx; | |
+ SSL* ssl; | |
port = 80; | |
- if ((argc == 5) || (argc == 6)) { | |
- if (argc == 5) { | |
- host = argv[1]; | |
- port = atoi(argv[2]); | |
- desthost = argv[3]; | |
- destport = argv[4]; | |
+ ac = argc - 1; | |
+ av = argv + 1; | |
+ if (ac >= 1 && strcmp(av[0], "-ssl") == 0) { | |
+ use_ssl = 1; | |
+ av++; | |
+ ac--; | |
+ port = 443; | |
+ } | |
+ if (ac >= 4) { | |
+ host = av[0]; | |
+ port = atoi(av[1]); | |
+ desthost = av[2]; | |
+ destport = av[3]; | |
+ av += 4; | |
+ ac -= 4; | |
+ if (ac > 1) { | |
+ usage(); | |
+ exit(-1); | |
} | |
- if ((argc == 6)) { | |
- host = argv[1]; | |
- port = atoi(argv[2]); | |
- desthost = argv[3]; | |
- destport = argv[4]; | |
- fp = fopen(argv[5], "r"); | |
+ if (ac == 1) { | |
+ fp = fopen(av[0], "r"); | |
if (fp == NULL) { | |
- fprintf(stderr, "Error opening %s: %s\n", argv[5], strerror(errno)); | |
+ fprintf(stderr, "Error opening %s: %s\n", av[0], strerror(errno)); | |
exit(-1); | |
- } else { | |
- char line[4096]; | |
- fscanf(fp, "%s", line); | |
- up = malloc(sizeof(line)); | |
- up = line; | |
- fclose(fp); | |
} | |
+ if (fgets(buffer, sizeof buffer - 1, fp)) { | |
+ len = strlen(buffer); | |
+ if (buffer[len - 1] == '\n') | |
+ buffer[len - 1] = '\0'; | |
+ up = malloc(len + 1); | |
+ strcpy(up, buffer); | |
+ } | |
+ fclose(fp); | |
+ av++; | |
+ ac--; | |
} | |
} else { | |
usage(); | |
@@ -218,18 +240,40 @@ | |
strncat(uri, ":", sizeof(uri) - strlen(uri) - 1); | |
strncat(uri, destport, sizeof(uri) - strlen(uri) - 1); | |
strncat(uri, " HTTP/1.0", sizeof(uri) - strlen(uri) - 1); | |
- if ((argc == 6) || (argc == 7)) { | |
- strncat(uri, "\nProxy-Authorization: Basic ", sizeof(uri) - strlen(uri) - 1); | |
+ if (up && *up) { | |
+ strncat(uri, "\r\nProxy-Authorization: Basic ", sizeof(uri) - strlen(uri) - 1); | |
strncat(uri, base64_encode(up), sizeof(uri) - strlen(uri) - 1); | |
} | |
strncat(uri, linefeed, sizeof(uri) - strlen(uri) - 1); | |
- csock = sock_connect(host, port); | |
- if(csock == -1) { | |
+ csock = socket(AF_INET, SOCK_STREAM, 0); | |
+ if (csock == -1) { | |
+ fprintf(stderr, "Couldn't create socket: %s\n", strerror(errno)); | |
+ exit(-1); | |
+ } | |
+ if (sock_connect(csock, host, port) < 0 && | |
+ errno && errno != EINPROGRESS) { | |
fprintf(stderr, "Couldn't establish connection to proxy: %s\n", strerror(errno)); | |
exit(-1); | |
} | |
+ if (use_ssl) { | |
+ SSLeay_add_ssl_algorithms(); | |
+ SSL_load_error_strings(); | |
+ SSL_library_init(); | |
+ ssl_meth = SSLv23_client_method(); | |
+ ctx = SSL_CTX_new(ssl_meth); | |
+ CHK_NULL(ctx); | |
+ SSL_CTX_set_options(ctx,SSL_OP_ALL); | |
+ ssl = SSL_new(ctx); | |
+ CHK_NULL(ssl); | |
+ SSL_set_fd(ssl, csock); | |
+ if (SSL_connect(ssl) < 0) { | |
+ fprintf(stderr, "Couldn't establish connection to proxy: %s\n", strerror(errno)); | |
+ exit(-1); | |
+ } | |
+ } | |
+ | |
sent = 0; | |
setup = 0; | |
for(;;) { | |
@@ -249,7 +293,11 @@ | |
/* there's probably a better way to do this */ | |
if (setup == 0) { | |
if (FD_ISSET(csock, &rfd)) { | |
- len = read(csock, buffer, sizeof(buffer)); | |
+ if (use_ssl) { | |
+ len = SSL_read(ssl, buffer, sizeof(buffer)); | |
+ } else { | |
+ len = read(csock, buffer, sizeof(buffer)); | |
+ } | |
if (len<=0) | |
break; | |
else { | |
@@ -265,7 +313,11 @@ | |
} | |
} | |
if (FD_ISSET(csock, &sfd) && (sent == 0)) { | |
- len = write(csock, uri, strlen(uri)); | |
+ if (use_ssl) { | |
+ len = SSL_write(ssl, uri, strlen(uri)); | |
+ } else { | |
+ len = write(csock, uri, strlen(uri)); | |
+ } | |
if (len<=0) | |
break; | |
else | |
@@ -273,7 +325,11 @@ | |
} | |
} else { | |
if (FD_ISSET(csock, &rfd)) { | |
- len = read(csock, buffer, sizeof(buffer)); | |
+ if (use_ssl) { | |
+ len = SSL_read(ssl, buffer, sizeof(buffer)); | |
+ } else { | |
+ len = read(csock, buffer, sizeof(buffer)); | |
+ } | |
if (len<=0) break; | |
len = write(1, buffer, len); | |
if (len<=0) break; | |
@@ -282,10 +338,23 @@ | |
if (FD_ISSET(0, &rfd)) { | |
len = read(0, buffer, sizeof(buffer)); | |
if (len<=0) break; | |
- len = write(csock, buffer, len); | |
+ if (use_ssl) { | |
+ len = SSL_write(ssl, buffer, len); | |
+ } else { | |
+ len = write(csock, buffer, len); | |
+ } | |
if (len<=0) break; | |
} | |
} | |
} | |
+ if (use_ssl) { | |
+ SSL_shutdown(ssl); | |
+ close(csock); | |
+ SSL_free(ssl); | |
+ SSL_CTX_free(ctx); | |
+ } else { | |
+ close(csock); | |
+ } | |
+ | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment