diff -cr stunnel-3.14/common.h pstunnel/common.h *** stunnel-3.14/common.h Wed Feb 21 23:08:31 2001 --- pstunnel/common.h Fri Mar 9 11:26:41 2001 *************** *** 18,31 **** * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #define OPT_CLIENT 0x01 ! #define OPT_CERT 0x02 ! #define OPT_DAEMON 0x04 ! #define OPT_FOREGROUND 0x08 ! #define OPT_PROGRAM 0x10 ! #define OPT_REMOTE 0x20 ! #define OPT_TRANSPARENT 0x40 ! #define OPT_PTY 0x80 /* Certificate defaults */ --- 18,32 ---- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ ! #define OPT_CLIENT 0x0001 ! #define OPT_CERT 0x0002 ! #define OPT_DAEMON 0x0004 ! #define OPT_FOREGROUND 0x0008 ! #define OPT_PROGRAM 0x0010 ! #define OPT_REMOTE 0x0020 ! #define OPT_TRANSPARENT 0x0040 ! #define OPT_PTY 0x0080 ! #define OPT_WEBPROXY 0x0100 /* Certificate defaults */ *************** *** 202,207 **** --- 203,209 ---- int random_bytes; /* how many random bytes to read */ char *pid_dir; int cert_defaults; + char *finaldest; } server_options; /* Prototypes for stunnel.c */ diff -cr stunnel-3.14/stunnel.c pstunnel/stunnel.c *** stunnel-3.14/stunnel.c Wed Feb 21 22:55:28 2001 --- pstunnel/stunnel.c Fri Mar 9 11:26:41 2001 *************** *** 102,107 **** --- 102,109 ---- /* Prototypes */ static void get_options(int, char *[]); static void daemon_loop(); + int connect_to_finaldest(int); + #ifndef USE_WIN32 static void daemonize(); static void create_pid(); *************** *** 242,249 **** options.rand_file=NULL; options.rand_write=1; options.random_bytes=RANDOM_BYTES; opterr=0; ! while ((c = getopt(argc, argv, "A:a:cp:v:d:fTl:L:r:s:g:t:u:n:N:hC:D:E:R:WB:VP:S:")) != EOF) switch (c) { case 'A': safecopy(options.cert_file,optarg); --- 244,252 ---- options.rand_file=NULL; options.rand_write=1; options.random_bytes=RANDOM_BYTES; + options.finaldest=NULL; opterr=0; ! while ((c = getopt(argc, argv, "A:a:cp:v:d:fTl:L:r:s:g:t:u:n:N:hC:D:E:R:WB:VP:S:Z:")) != EOF) switch (c) { case 'A': safecopy(options.cert_file,optarg); *************** *** 385,390 **** --- 388,402 ---- log(LOG_ERR, "Illegal option: '%c'", optopt); case 'h': print_help(); + case 'Z': + if(!(options.option & OPT_CLIENT)) { + log(LOG_ERR, "webproxy -Z option runs only in client mode"); + fprintf(stderr, "webproxy -Z option runs only in client mode"); + print_help(); + } + options.option |= OPT_WEBPROXY; + options.finaldest = optarg; + break; default: log(LOG_ERR, "INTERNAL ERROR: Illegal option: '%c'", c); print_help(); *************** *** 747,753 **** addr.sin_addr.s_addr=*list; log(LOG_DEBUG, "%s connecting %s:%d", options.servname, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); ! if(!connect(s, (struct sockaddr *) &addr, sizeof(addr))) return s; /* success */ } sockerror("remote connect"); --- 759,766 ---- addr.sin_addr.s_addr=*list; log(LOG_DEBUG, "%s connecting %s:%d", options.servname, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); ! if(!connect(s, (struct sockaddr *) &addr, sizeof(addr)) ! && !connect_to_finaldest(s)) return s; /* success */ } sockerror("remote connect"); *************** *** 1098,1103 **** --- 1111,1117 ---- "\n\t-d [host:]port -r [host:]port" #endif + "\n\t[-Z host:port ] " /* Argument notes */ *************** *** 1106,1111 **** --- 1120,1127 ---- "\n" "\n -d [host:]port daemon mode (host defaults to INADDR_ANY)" "\n -r [host:]port connect to remote service (host defaults to INADDR_LOOPBACK)" + "\n -Z host:port the remote SSL host, if in client mode and using a webproxy" + "\n eg. -c -d localhost:9999 -r proxy:3128 -Z remotehost:443" #ifndef USE_WIN32 "\n -l program\t execute local inetd-type program" "\n -L program\t open local pty and execute program" *************** *** 1159,1164 **** --- 1175,1224 ---- "\nSee stunnel -V output for default values\n" "\n"); exit(1); + } + + int connect_to_finaldest(int s) { + char buff[STRLEN]; + int len, code; + + if (!(options.option & OPT_WEBPROXY)) + return 0; + + #ifdef HAVE_SNPRINTF + len=snprintf(buff, STRLEN, + #else + len=sprintf(buff, + #endif + "CONNECT %s HTTP/1.0\r\n\r\n", options.finaldest); + len=writesocket(s, buff, len); + if(len<0) { + sockerror("writesocket (finaldest)"); + closesocket(s); + return -1; + } + log(LOG_DEBUG, "me ---> proxy: %s", buff); + + len=readsocket(s, buff, STRLEN-1); + if(len<0) { + sockerror("readsocket (finaldest)"); + closesocket(s); + return -1; + } + buff[len]='\0'; + log(LOG_DEBUG, "proxy ---> me: %s", buff); + + code = 0; + if(sscanf(buff, "HTTP/%*s %d %*s", &code) != 1) { + log(LOG_ERR, "error: %s", buff); + return -1; + } + + if(code != 200) { + log(LOG_WARNING, "return code not 200: %s", buff); + return -1; + } + + return 0; } /* End of stunnel.c */