Skip to content

Instantly share code, notes, and snippets.

@komeda-shinji
Created February 13, 2015 12:27
Show Gist options
  • Save komeda-shinji/c23a5f0d57886f36b53e to your computer and use it in GitHub Desktop.
Save komeda-shinji/c23a5f0d57886f36b53e to your computer and use it in GitHub Desktop.
corkscrewをSSLなプロキシに対応させた ref: http://qiita.com/komeda-shinji/items/8a78f07cc7d0d75d37c0
usage: corkscrew [-ssl] <proxyhost> <proxyport> <desthost> <destport> [authfile]
make LDADD="-lcrypto -lssl"
% 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