openssl s_client を HTTP PROXY 対応にするパッチ for OpenSSL 0.9.8j

オリジナルはここ>http://marc.info/?l=openssl-dev&m=103106024113390&w=2
最近の OpenSSL に適用できなかったので手直し.
0.9.8k でも動作確認済.

--- s_client.c.orig	2008-12-21 02:04:08.000000000 +0900
+++ s_client.c	2009-02-16 19:33:16.031250000 +0900
@@ -195,6 +195,7 @@
 	BIO_printf(bio_err," -host host     - use -connect instead\n");
 	BIO_printf(bio_err," -port port     - use -connect instead\n");
 	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
+	BIO_printf(bio_err," -proxy host:port - use HTTP proxy\n");
 
 	BIO_printf(bio_err," -verify depth - turn on peer certificate verification\n");
 	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
@@ -295,8 +296,10 @@
 	int sbuf_len,sbuf_off;
 	fd_set readfds,writefds;
 	short port=PORT;
+	short pport=0;
 	int full_log=1;
 	char *host=SSL_HOST_NAME;
+	char *phost=NULL;
 	char *cert_file=NULL,*key_file=NULL;
 	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
 	char *passarg = NULL, *pass = NULL;
@@ -400,6 +403,12 @@
 			if (!extract_host_port(*(++argv),&host,NULL,&port))
 				goto bad;
 			}
+		else if (strcmp(*argv,"-proxy") == 0)
+			{
+			if (--argc < 1) goto bad;
+			if (!extract_host_port(*(++argv),&phost,NULL,&pport))
+				goto bad;
+			}
 		else if	(strcmp(*argv,"-verify") == 0)
 			{
 			verify=SSL_VERIFY_PEER;
@@ -795,12 +804,24 @@
 
 re_start:
 
-	if (init_client(&s,host,port,sock_type) == 0)
-		{
-		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
-		SHUTDOWN(s);
-		goto end;
-		}
+    if (phost && pport) {
+		/* in case we are using a http proxy we need to connect
+		to the proxy server */
+		if (init_client(&s,phost,pport,sock_type) == 0)
+			{
+			BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
+			SHUTDOWN(s);
+			goto end;
+			}
+	} else {
+		if (init_client(&s,host,port,sock_type) == 0)
+			{
+			BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
+			SHUTDOWN(s);
+			goto end;
+			}
+	}
+		
 	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
 
 #ifdef FIONBIO
@@ -920,6 +941,10 @@
 	sbuf_len=0;
 	sbuf_off=0;
 
+	unsigned int http_status;
+	unsigned int http_major_version;
+	unsigned int http_minor_version;
+
 	/* This is an ugly hack that does a lot of assumptions */
 	/* We do have to handle multi-line responses which may come
  	   in a single packet or not. We therefore have to use
@@ -1030,6 +1055,18 @@
 			goto shut;
 		mbuf[0] = 0;
 		}
+	else if (phost && pport)
+	    {
+		/* BIO_read(sbio,mbuf,BUFSIZZ); */
+		BIO_printf(sbio,"CONNECT %s:%d HTTP/1.0\r\nHost: %s\r\n\r\n", host, port, host);
+		BIO_read(sbio,sbuf,BUFSIZZ);
+		sscanf(sbuf, "HTTP/%u.%u %u", &http_major_version, &http_minor_version, &http_status);
+		if ( http_status != 200 ) {
+		    BIO_printf(bio_err,"connect:proxy returned status=%d\n", http_status);
+		    goto shut;
+		}
+
+	    }
 
 	for (;;)
 		{