+++ /dev/null
-/***********************************************************************
- * connect.c -- Make socket connection using SOCKS4/5 and HTTP tunnel.
- *
- * Copyright (c) 2000-2004 Shun-ichi Goto
- * Copyright (c) 2002, J. Grant (English Corrections)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * ---------------------------------------------------------
- * PROJECT: My Test Program
- * AUTHOR: Shun-ichi GOTO <gotoh@taiyo.co.jp>
- * CREATE: Wed Jun 21, 2000
- * REVISION: $Revision$
- * ---------------------------------------------------------
- *
- * Getting Source
- * ==============
- *
- * Recent version of 'connect.c' is available from
- * http://www.taiyo.co.jp/~gotoh/ssh/connect.c
- *
- * Related tool, ssh-askpass.exe (alternative ssh-askpass on UNIX)
- * is available:
- * http://www.taiyo.co.jp/~gotoh/ssh/ssh-askpass.exe.gz
- *
- * See more detail:
- * http://www.taiyo.co.jp/~gotoh/ssh/connect.html
- *
- * How To Compile
- * ==============
- *
- * On UNIX environment:
- * $ gcc connect.c -o connect
- *
- * On SOLARIS:
- * $ gcc -o connect -lresolv -lsocket -lnsl connect.c
- *
- * on Win32 environment:
- * $ cl connect.c wsock32.lib advapi32.lib
- * or
- * $ bcc32 connect.c wsock32.lib advapi32.lib
- * or
- * $ gcc connect.c -o connect
- *
- * on Mac OS X environment:
- * $ gcc connect.c -o connect -lresolv
- * or
- * $ gcc connect.c -o connect -DBIND_8_COMPAT=1
- *
- * How To Use
- * ==========
- *
- * You can specify proxy method in an environment variable or in a
- * command line option.
- *
- * usage: connect [-dnhst45] [-R resolve] [-p local-port] [-w sec]
- * [-H [user@]proxy-server[:port]]
- * [-S [user@]socks-server[:port]]
- * [-T proxy-server[:port]]
- * [-c telnet proxy command]
- * host port
- *
- * "host" and "port" is for the target hostname and port-number to
- * connect to.
- *
- * The -H option specifys a hostname and port number of the http proxy
- * server to relay. If port is omitted, 80 is used. You can specify this
- * value in the environment variable HTTP_PROXY and pass the -h option
- * to use it.
- *
- * The -S option specifys the hostname and port number of the SOCKS
- * server to relay. Like -H, port number can be omitted and the default
- * is 1080. You can also specify this value pair in the environment
- * variable SOCKS5_SERVER and give the -s option to use it.
- *
- * The '-4' and the '-5' options are for specifying SOCKS relaying and
- * indicates protocol version to use. It is valid only when used with
- * '-s' or '-S'. Default is '-5' (protocol version 5)
- *
- * The '-R' option is for specifying method to resolve the
- * hostname. Three keywords ("local", "remote", "both") or dot-notation
- * IP address are acceptable. The keyword "both" means, "Try local
- * first, then remote". If a dot-notation IP address is specified, use
- * this host as nameserver. The default is "remote" for SOCKS5 or
- * "local" for others. On SOCKS4 protocol, remote resolving method
- * ("remote" and "both") requires protocol 4a supported server.
- *
- * The '-p' option will forward a local TCP port instead of using the
- * standard input and output.
- *
- * The '-P' option is same to '-p' except keep remote session. The
- * program repeats waiting the port with holding remote session without
- * disconnecting. To disconnect the remote session, send EOF to stdin or
- * kill the program.
- *
- * The '-w' option specifys timeout seconds for making connection with
- * TARGET host.
- *
- * The '-d' option is used for debug. If you fail to connect, use this
- * and check request to and response from server.
- *
- * You can omit the "port" argument when program name is special format
- * containing port number itself. For example,
- * $ ln -s connect connect-25
- * means this connect-25 command is spcifying port number 25 already
- * so you need not 2nd argument (and ignored if specified).
- *
- * To use proxy, this example is for SOCKS5 connection to connect to
- * 'host' at port 25 via SOCKS5 server on 'firewall' host.
- * $ connect -S firewall host 25
- * or
- * $ SOCKS5_SERVER=firewall; export SOCKS5_SERVER
- * $ connect -s host 25
- *
- * For a HTTP-PROXY connection:
- * $ connect -H proxy-server:8080 host 25
- * or
- * $ HTTP_PROXY=proxy-server:8080; export HTTP_PROXY
- * $ connect -h host 25
- * To forward a local port, for example to use ssh:
- * $ connect -p 5550 -H proxy-server:8080 host 22
- * ($ ssh -l user -p 5550 localhost )
- *
- * TIPS
- * ====
- *
- * Connect.c doesn't have any configuration to specify the SOCKS server.
- * If you are a mobile user, this limitation might bother you. However,
- * You can compile connect.c and link with other standard SOCKS library
- * like the NEC SOCKS5 library or Dante. This means connect.c is
- * socksified and uses a configration file like to other SOCKSified
- * network commands and you can switch configuration file any time
- * (ex. when ppp startup) that brings you switching of SOCKS server for
- * connect.c in same way with other commands. For this case, you can
- * write ~/.ssh/config like this:
- *
- * ProxyCommand connect -n %h %p
- *
- * SOCKS5 authentication
- * =====================
- *
- * Only USER/PASS authentication is supported.
- *
- * Proxy authentication
- * ====================
- *
- * Only BASIC scheme is supported.
- *
- * Authentication informations
- * ===========================
- *
- * User name for authentication is specifed by an environment variable
- * or system login name. And password is specified from environment
- * variable or external program (specified in $SSH_ASKPASS) or tty.
- *
- * Following environment variable is used for specifying user name.
- * SOCKS: $SOCKS5_USER, $LOGNAME, $USER
- * HTTP Proxy: $HTTP_PROXY_USER, $LOGNAME, $USER
- *
- * ssh-askpass support
- * ===================
- *
- * You can use ssh-askpass (came from OpenSSH or else) to specify
- * password on graphical environment (X-Window or MS Windows). To use
- * this, set program name to environment variable SSH_ASKPASS. On UNIX,
- * X-Window must be required, so $DISPLAY environment variable is also
- * needed. On Win32 environment, $DISPLAY is not mentioned.
- *
- * Related Informations
- * ====================
- *
- * SOCKS5 -- RFC 1928, RFC 1929, RFC 1961
- * NEC SOCKS Reference Implementation is available from:
- * http://www.socks.nec.com
- * DeleGate version 5 or earlier can be SOCKS4 server,
- * and version 6 can be SOCKS5 and SOCKS4 server.
- * and version 7.7.0 or later can be SOCKS5 and SOCKS4a server.
- * http://www.delegate.org/delegate/
- *
- * HTTP-Proxy --
- * Many http proxy servers supports this, but https should
- * be allowed as configuration on your host.
- * For example on DeleGate, you should add "https" to the
- * "REMITTABLE" parameter to allow HTTP-Proxy like this:
- * delegated -Pxxxx ...... REMITTABLE="+,https" ...
- *
- * Hypertext Transfer Protocol -- HTTP/1.1 -- RFC 2616
- * HTTP Authentication: Basic and Digest Access Authentication -- RFC 2617
- * For proxy authentication, refer these documents.
- *
- ***********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#ifdef __CYGWIN32__
-#undef _WIN32
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock.h>
-#include <sys/stat.h>
-#include <io.h>
-#include <conio.h>
-#else /* !_WIN32 */
-#include <unistd.h>
-#include <pwd.h>
-#include <termios.h>
-#include <sys/time.h>
-#ifndef __hpux
-#include <sys/select.h>
-#endif /* __hpux */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
-#define WITH_RESOLVER 1
-#include <arpa/nameser.h>
-#include <resolv.h>
-#else /* not ( not _WIN32 && not __CYGWIN32__) */
-#undef WITH_RESOLVER
-#endif /* not ( not _WIN32 && not __CYGWIN32__) */
-#endif /* !_WIN32 */
-
-#ifdef _WIN32
-#define ECONNRESET WSAECONNRESET
-#endif /* _WI32 */
-
-
-
-#ifndef LINT
-static char *vcid = "$Id$";
-#endif
-
-/* Microsoft Visual C/C++ has _snprintf() and _vsnprintf() */
-#ifdef _MSC_VER
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#endif
-
-/* consider Borland C */
-#ifdef __BORLANDC__
-#define _kbhit kbhit
-#define _setmode setmode
-#endif
-
-/* help message.
- Win32 environment does not support -R option (vc and cygwin)
- Win32 native compilers does not support -w option, yet (vc)
-*/
-static char *usage = "usage: %s [-dnhst45] [-p local-port]"
-#ifdef _WIN32
-#ifdef __CYGWIN32__
-"[-w timeout] \n" /* cygwin cannot -R */
-#else /* not __CYGWIN32__ */
-" \n" /* VC cannot -w nor -R */
-#endif /* not __CYGWIN32__ */
-#else /* not _WIN32 */
-/* help message for UNIX */
-"[-R resolve] [-w timeout] \n"
-#endif /* not _WIN32 */
-" [-H proxy-server[:port]] [-S [user@]socks-server[:port]] \n"
-" [-T proxy-server[:port]]\n"
-" [-c telnet-proxy-command]\n"
-" host port\n";
-
-/* name of this program */
-char *progname = NULL;
-char *progdesc = "connect --- simple relaying command via proxy.";
-char *rcs_revstr = "$Revision$";
-char *revstr = NULL;
-
-/* set of character for strspn() */
-const char *digits = "0123456789";
-const char *dotdigits = "0123456789.";
-
-/* options */
-int f_debug = 0;
-
-/* report flag to hide secure information */
-int f_report = 1;
-
-int connect_timeout = 0;
-
-/* local input type */
-#define LOCAL_STDIO 0
-#define LOCAL_SOCKET 1
-char *local_type_names[] = { "stdio", "socket" };
-int local_type = LOCAL_STDIO;
-u_short local_port = 0; /* option 'p' */
-int f_hold_session = 0; /* option 'P' */
-
-char *telnet_command = "telnet %h %p";
-
-/* utiity types, pair holder of number and string */
-typedef struct {
- int num;
- const char *str;
-} LOOKUP_ITEM;
-
-/* relay method, server and port */
-#define METHOD_UNDECIDED 0
-#define METHOD_DIRECT 1
-#define METHOD_SOCKS 2
-#define METHOD_HTTP 3
-#define METHOD_TELNET 4
-char *method_names[] = { "UNDECIDED", "DIRECT", "SOCKS", "HTTP", "TELNET" };
-
-int relay_method = METHOD_UNDECIDED; /* relaying method */
-char *relay_host = NULL; /* hostname of relay server */
-u_short relay_port = 0; /* port of relay server */
-char *relay_user = NULL; /* user name for auth */
-
-/* destination target host and port */
-char *dest_host = NULL;
-struct sockaddr_in dest_addr;
-u_short dest_port = 0;
-
-/* informations for SOCKS */
-#define SOCKS5_REP_SUCCEEDED 0x00 /* succeeded */
-#define SOCKS5_REP_FAIL 0x01 /* general SOCKS serer failure */
-#define SOCKS5_REP_NALLOWED 0x02 /* connection not allowed by ruleset */
-#define SOCKS5_REP_NUNREACH 0x03 /* Network unreachable */
-#define SOCKS5_REP_HUNREACH 0x04 /* Host unreachable */
-#define SOCKS5_REP_REFUSED 0x05 /* connection refused */
-#define SOCKS5_REP_EXPIRED 0x06 /* TTL expired */
-#define SOCKS5_REP_CNOTSUP 0x07 /* Command not supported */
-#define SOCKS5_REP_ANOTSUP 0x08 /* Address not supported */
-#define SOCKS5_REP_INVADDR 0x09 /* Inalid address */
-
-LOOKUP_ITEM socks5_rep_names[] = {
- { SOCKS5_REP_SUCCEEDED, "succeeded"},
- { SOCKS5_REP_FAIL, "general SOCKS server failure"},
- { SOCKS5_REP_NALLOWED, "connection not allowed by ruleset"},
- { SOCKS5_REP_NUNREACH, "Network unreachable"},
- { SOCKS5_REP_HUNREACH, "Host unreachable"},
- { SOCKS5_REP_REFUSED, "connection refused"},
- { SOCKS5_REP_EXPIRED, "TTL expired"},
- { SOCKS5_REP_CNOTSUP, "Command not supported"},
- { SOCKS5_REP_ANOTSUP, "Address not supported"},
- { SOCKS5_REP_INVADDR, "Invalid address"},
- { -1, NULL }
-};
-
-/* SOCKS5 authentication methods */
-#define SOCKS5_AUTH_REJECT 0xFF /* No acceptable auth method */
-#define SOCKS5_AUTH_NOAUTH 0x00 /* without authentication */
-#define SOCKS5_AUTH_GSSAPI 0x01 /* GSSAPI */
-#define SOCKS5_AUTH_USERPASS 0x02 /* User/Password */
-#define SOCKS5_AUTH_CHAP 0x03 /* Challenge-Handshake Auth Proto. */
-#define SOCKS5_AUTH_EAP 0x05 /* Extensible Authentication Proto. */
-#define SOCKS5_AUTH_MAF 0x08 /* Multi-Authentication Framework */
-
-#define SOCKS4_REP_SUCCEEDED 90 /* rquest granted (succeeded) */
-#define SOCKS4_REP_REJECTED 91 /* request rejected or failed */
-#define SOCKS4_REP_IDENT_FAIL 92 /* cannot connect identd */
-#define SOCKS4_REP_USERID 93 /* user id not matched */
-
-LOOKUP_ITEM socks4_rep_names[] = {
- { SOCKS4_REP_SUCCEEDED, "request granted (succeeded)"},
- { SOCKS4_REP_REJECTED, "request rejected or failed"},
- { SOCKS4_REP_IDENT_FAIL, "cannot connect identd"},
- { SOCKS4_REP_USERID, "user id not matched"},
- { -1, NULL }
-};
-
-#define RESOLVE_UNKNOWN 0
-#define RESOLVE_LOCAL 1
-#define RESOLVE_REMOTE 2
-#define RESOLVE_BOTH 3
-char *resolve_names[] = { "UNKNOWN", "LOCAL", "REMOTE", "BOTH" };
-
-int socks_version = 5; /* SOCKS protocol version */
-int socks_resolve = RESOLVE_UNKNOWN;
-struct sockaddr_in socks_ns;
-char *socks5_auth = NULL;
-
-/* Environment variable names */
-#define ENV_SOCKS_SERVER "SOCKS_SERVER" /* SOCKS server */
-#define ENV_SOCKS5_SERVER "SOCKS5_SERVER"
-#define ENV_SOCKS4_SERVER "SOCKS4_SERVER"
-
-#define ENV_SOCKS_RESOLVE "SOCKS_RESOLVE" /* resolve method */
-#define ENV_SOCKS5_RESOLVE "SOCKS5_RESOLVE"
-#define ENV_SOCKS4_RESOLVE "SOCKS4_RESOLVE"
-
-#define ENV_SOCKS5_USER "SOCKS5_USER" /* auth user for SOCKS5 */
-#define ENV_SOCKS4_USER "SOCKS4_USER" /* auth user for SOCKS4 */
-#define ENV_SOCKS_USER "SOCKS_USER" /* auth user for SOCKS */
-#define ENV_SOCKS5_PASSWD "SOCKS5_PASSWD" /* auth password for SOCKS5 */
-#define ENV_SOCKS5_PASSWORD "SOCKS5_PASSWORD" /* old style */
-
-#define ENV_HTTP_PROXY "HTTP_PROXY" /* common env var */
-#define ENV_HTTP_PROXY_USER "HTTP_PROXY_USER" /* auth user */
-#define ENV_HTTP_PROXY_PASSWORD "HTTP_PROXY_PASSWORD" /* auth password */
-
-#define ENV_TELNET_PROXY "TELNET_PROXY" /* common env var */
-
-#define ENV_CONNECT_USER "CONNECT_USER" /* default auth user name */
-#define ENV_CONNECT_PASSWORD "CONNECT_PASSWORD" /* default auth password */
-
-#define ENV_SOCKS_DIRECT "SOCKS_DIRECT" /* addr-list for non-proxy */
-#define ENV_SOCKS5_DIRECT "SOCKS5_DIRECT"
-#define ENV_SOCKS4_DIRECT "SOCKS4_DIRECT"
-#define ENV_HTTP_DIRECT "HTTP_DIRECT"
-#define ENV_CONNECT_DIRECT "CONNECT_DIRECT"
-
-#define ENV_SOCKS5_AUTH "SOCKS5_AUTH"
-#define ENV_SSH_ASKPASS "SSH_ASKPASS" /* askpass program */
-
-/* Prefix string of HTTP_PROXY */
-#define HTTP_PROXY_PREFIX "http://"
-#define PROXY_AUTH_NONE 0
-#define PROXY_AUTH_BASIC 1
-#define PROXY_AUTH_DIGEST 2
-int proxy_auth_type = PROXY_AUTH_NONE;
-
-/* reason of end repeating */
-#define REASON_UNK -2
-#define REASON_ERROR -1
-#define REASON_CLOSED_BY_LOCAL 0
-#define REASON_CLOSED_BY_REMOTE 1
-
-/* return value of relay start function. */
-#define START_ERROR -1
-#define START_OK 0
-#define START_RETRY 1
-
-/* socket related definitions */
-#ifndef _WIN32
-#define SOCKET int
-#endif
-#ifndef SOCKET_ERROR
-#define SOCKET_ERROR -1
-#endif
-
-#ifdef _WIN32
-#define socket_errno() WSAGetLastError()
-#else /* !_WIN32 */
-#define closesocket close
-#define socket_errno() (errno)
-#endif /* !_WIN32 */
-
-#ifdef _WIN32
-#define popen _popen
-#endif /* WIN32 */
-
-/* packet operation macro */
-#define PUT_BYTE(ptr,data) (*(unsigned char*)ptr = data)
-
-/* debug message output */
-void
-debug( const char *fmt, ... )
-{
- va_list args;
- if ( f_debug ) {
- va_start( args, fmt );
- fprintf(stderr, "DEBUG: ");
- vfprintf( stderr, fmt, args );
- va_end( args );
- }
-}
-
-void
-debug_( const char *fmt, ... ) /* without prefix */
-{
- va_list args;
- if ( f_debug ) {
- va_start( args, fmt );
- vfprintf( stderr, fmt, args );
- va_end( args );
- }
-}
-
-/* error message output */
-void
-error( const char *fmt, ... )
-{
- va_list args;
- va_start( args, fmt );
- fprintf(stderr, "ERROR: ");
- vfprintf( stderr, fmt, args );
- va_end( args );
-}
-
-void
-fatal( const char *fmt, ... )
-{
- va_list args;
- va_start( args, fmt );
- fprintf(stderr, "FATAL: ");
- vfprintf( stderr, fmt, args );
- va_end( args );
- exit (EXIT_FAILURE);
-}
-
-
-void *
-xmalloc (size_t size)
-{
- void *ret = malloc(size);
- if (ret == NULL)
- fatal("Cannot allocate memory: %d bytes.\n", size);
- return ret;
-}
-
-void
-downcase( char *buf )
-{
- while ( *buf ) {
- if ( isupper(*buf) )
- *buf += 'a'-'A';
- buf++;
- }
-}
-
-char *
-expand_host_and_port (const char *fmt, const char *host, int port)
-{
- const char *src;
- char *buf, *dst, *ptr;
- size_t len = strlen(fmt) + strlen(host) + 20;
- buf = xmalloc (len);
- dst = buf;
- src = fmt;
-
- while (*src) {
- if (*src == '%') {
- switch (src[1]) {
- case 'h':
- strcpy (dst, host);
- src += 2;
- break;
- case 'p':
- snprintf (dst, len, "%d", port);
- src += 2;
- break;
- default:
- src ++;
- break;
- }
- dst = buf + strlen (buf);
- } else if (*src == '\\') {
- switch (src[1]) {
- case 'r': /* CR */
- *dst++ = '\r';
- src += 2;
- break;
- case 'n': /* LF */
- *dst++ = '\n';
- src += 2;
- break;
- case 't': /* TAB */
- *dst++ = '\t';
- src += 2;
- break;
- default:
- src ++;
- break;
- }
- } else {
- /* usual */
- *dst++ = *src++;
- }
- *dst = '\0';
- }
- assert (strlen(buf) < len);
- return buf;
-}
-
-
-int
-lookup_resolve( const char *str )
-{
- char *buf = strdup( str );
- int ret;
-
- downcase( buf );
- if ( strcmp( buf, "both" ) == 0 )
- ret = RESOLVE_BOTH;
- else if ( strcmp( buf, "remote" ) == 0 )
- ret = RESOLVE_REMOTE;
- else if ( strcmp( buf, "local" ) == 0 )
- ret = RESOLVE_LOCAL;
- else if ( strspn(buf, dotdigits) == strlen(buf) ) {
-#ifndef WITH_RESOLVER
- fatal("Sorry, you can't specify to resolve the hostname with the -R option on Win32 environment.");
-#endif /* not WITH_RESOLVER */
- ret = RESOLVE_LOCAL; /* this case is also 'local' */
- socks_ns.sin_addr.s_addr = inet_addr(buf);
- socks_ns.sin_family = AF_INET;
- }
- else
- ret = RESOLVE_UNKNOWN;
- free(buf);
- return ret;
-}
-
-char *
-getusername(void)
-{
-#ifdef _WIN32
- static char buf[1024];
- DWORD size = sizeof(buf);
- buf[0] = '\0';
- GetUserName( buf, &size);
- return buf;
-#else /* not _WIN32 */
- struct passwd *pw = getpwuid(getuid());
- if ( pw == NULL )
- fatal("getpwuid() failed for uid: %d\n", getuid());
- return pw->pw_name;
-#endif /* not _WIN32 */
-}
-
-/* expect
- check STR is begin with substr with case-ignored comparison.
- Return 1 if matched, otherwise 0.
-*/
-int
-expect( char *str, char *substr)
-{
- int len = strlen(substr);
- while ( 0 < len-- ) {
- if ( toupper(*str) != toupper(*substr) )
- return 0; /* not matched */
- str++, substr++;
- }
- return 1; /* good, matched */
-}
-
-
-/** PARAMETER operation **/
-#define PARAMETER_FILE "/etc/connectrc"
-#define PARAMETER_DOTFILE ".connectrc"
-typedef struct {
- char* name;
- char* value;
-} PARAMETER_ITEM;
-PARAMETER_ITEM parameter_table[] = {
- { ENV_SOCKS_SERVER, NULL },
- { ENV_SOCKS5_SERVER, NULL },
- { ENV_SOCKS4_SERVER, NULL },
- { ENV_SOCKS_RESOLVE, NULL },
- { ENV_SOCKS5_RESOLVE, NULL },
- { ENV_SOCKS4_RESOLVE, NULL },
- { ENV_SOCKS5_USER, NULL },
- { ENV_SOCKS5_PASSWD, NULL },
- { ENV_SOCKS5_PASSWORD, NULL },
- { ENV_HTTP_PROXY, NULL },
- { ENV_HTTP_PROXY_USER, NULL },
- { ENV_HTTP_PROXY_PASSWORD, NULL },
- { ENV_CONNECT_USER, NULL },
- { ENV_CONNECT_PASSWORD, NULL },
- { ENV_SSH_ASKPASS, NULL },
- { ENV_SOCKS5_DIRECT, NULL },
- { ENV_SOCKS4_DIRECT, NULL },
- { ENV_SOCKS_DIRECT, NULL },
- { ENV_HTTP_DIRECT, NULL },
- { ENV_CONNECT_DIRECT, NULL },
- { ENV_SOCKS5_AUTH, NULL },
- { NULL, NULL }
-};
-
-PARAMETER_ITEM*
-find_parameter_item(const char* name)
-{
- int i;
- for( i = 0; parameter_table[i].name != NULL; i++ ){
- if ( strcmp(name, parameter_table[i].name) == 0 )
- return ¶meter_table[i];
- }
- return NULL;
-}
-
-void
-read_parameter_file_1(const char* name)
-{
- FILE* f;
- int line;
- char lbuf[1025];
- f = fopen(name, "r");
- if( f ){
- debug("Reading parameter file(%s)\n", name);
- for ( line = 1; fgets(lbuf, 1024, f); line++ ) {
- char *p, *q, *param, *value;
- p = strchr(lbuf, '\n');
- if ( p == NULL )
- fatal("%s:%d: buffer overflow\n", name, line);
- *p = '\0';
- p = strchr(lbuf, '#');
- if ( p )
- *p = '\0';
- for ( p = lbuf; *p; p++ )
- if( *p != ' ' && *p != '\t' ) break;
- if ( *p == '\0' ) continue;
- param = p;
- p = strchr(p, '=');
- if ( p == NULL ) {
- error("%s:%d: missing equal sign\n", name, line);
- continue;
- }
- for ( q = p - 1; q >= lbuf; q-- )
- if ( *q != ' ' && *q != '\t' ) break;
- *++q = '\0';
- for ( ++p; *p; p++ )
- if ( *p != ' ' && *p != '\t' ) break;
- value = p;
- for ( ; *p; p++ );
- for ( p--; p >= lbuf; p-- )
- if ( *p != ' ' && *p != '\t' ) break;
- *++p = '\0';
- if ( param && value ) {
- PARAMETER_ITEM *item;
- item = find_parameter_item(param);
- if ( item == NULL ) {
- error("%s:%d: unknown parameter `%s'\n", name, line, param);
- continue;
- }
- item->value = strdup(value);
- debug("Parameter `%s' is set to `%s'\n", param, value);
- }
- }
- }
-}
-
-void
-read_parameter_file(void)
-{
-#if !defined(_WIN32) || defined(cygwin)
- char *name;
- struct passwd *pw;
-#endif
-
- read_parameter_file_1(PARAMETER_FILE);
-#if !defined(_WIN32) || defined(cygwin)
- pw = getpwuid(getuid());
- if ( pw == NULL )
- fatal("getpwuid() failed for uid: %d\n", getuid());
- name = xmalloc(strlen(pw->pw_dir) + strlen(PARAMETER_DOTFILE) + 2);
- strcpy(name, pw->pw_dir);
- strcat(name, "/" PARAMETER_DOTFILE);
- read_parameter_file_1(name);
- free(name);
-#endif /* _WIN32 */
-}
-
-char*
-getparam(const char* name)
-{
- char *value = getenv(name);
- if ( value == NULL ){
- PARAMETER_ITEM *item = find_parameter_item(name);
- if ( item != NULL )
- value = item->value;
- }
- return value;
-}
-
-
-/** DIRECT connection **/
-#define MAX_DIRECT_ADDR_LIST 256
-
-struct ADDRPAIR {
- struct in_addr addr;
- struct in_addr mask;
- int negative;
-};
-
-struct ADDRPAIR direct_addr_list[MAX_DIRECT_ADDR_LIST];
-int n_direct_addr_list = 0;
-
-void
-mask_addr (void *addr, void *mask, int addrlen)
-{
- char *a, *m;
- a = addr;
- m = mask;
- while ( 0 < addrlen-- )
- *a++ &= *m++;
-}
-
-int
-add_direct_addr (struct in_addr *addr, struct in_addr *mask, int negative)
-{
- struct in_addr iaddr;
- char *s;
- if ( MAX_DIRECT_ADDR_LIST <= n_direct_addr_list ) {
- error("direct address table is full!\n");
- return -1;
- }
- iaddr = *addr;
- mask_addr(&iaddr, mask, sizeof(iaddr));
- s = strdup(inet_ntoa(iaddr));
- debug("adding direct address entry: %s/%s\n", s, inet_ntoa(*mask));
- free(s);
- memcpy( &direct_addr_list[n_direct_addr_list].addr,
- &iaddr, sizeof(iaddr));
- memcpy( &direct_addr_list[n_direct_addr_list].mask,
- mask, sizeof(*mask));
- direct_addr_list[n_direct_addr_list].negative = negative;
- n_direct_addr_list++;
- return 0;
-}
-
-int
-parse_addr_pair (const char *str, struct in_addr *addr, struct in_addr *mask)
-{
- /* NOTE: */
- /* Assume already be splitted by separator
- and formatted as folowing:
- 1) 12.34.56.789/255.255.255.0
- 2) 12.34.56.789/24
- 3) 12.34.56.
- All above generates same addr/mask pair 12.34.56.0 and 255.255.255.0
- */
- const char *ptr;
- u_char *dsta, *dstm;
- int i, n;
-
- assert( str != NULL );
- debug("parsing address pair: '%s'\n", str);
- addr->s_addr = 0;
- mask->s_addr = 0;
- ptr = str;
- dsta = (u_char*)&addr->s_addr;
- dstm = (u_char*)&mask->s_addr;
- for (i=0; i<4; i++ ) {
- if ( *ptr == '\0' )
- break; /* case of format #3 */
- if ( !isdigit(*ptr) )
- return -1; /* format error: */
- *dsta++ = atoi( ptr );
- *dstm++ = 255; /* automatic mask for format #3 */
- while ( isdigit(*ptr) ) /* skip digits */
- ptr++;
- if ( *ptr == '.' )
- ptr++;
- else
- break;
- }
- /* At this point, *ptr points '/' or EOS ('\0') */
- if ( *ptr == '\0' )
- return 0; /* complete as format #3 */
- if ( *ptr != '/' )
- return -1; /* format error */
- /* Now parse mask for format #1 or #2 */
- ptr++;
- mask->s_addr = 0; /* clear automatic mask */
-
- if ( strchr( ptr, '.') ) {
- /* case of format #1 */
- dstm = (u_char*)&mask->s_addr;
- for (i=0; i<4; i++) {
- if ( !isdigit(*ptr) )
- return -1; /* format error: */
- *dstm++ = atoi(ptr);
- while ( isdigit(*ptr) ) /* skip digits */
- ptr++;
- if ( *ptr == '.' )
- ptr++;
- else
- break; /* from for loop */
- }
- /* complete as format #1 */
- } else {
- /* case of format #2 */
- if ( !isdigit(*ptr) )
- return -1; /* format error: */
- n = atoi(ptr);
- if ( n<0 || 32<n)
- return -1; /* format error */
- mask->s_addr = (n==0)? 0: htonl(((u_long)0xFFFFFFFF)<<(32-n));
- /* complete as format #1 */
- }
- return 0;
-}
-
-void
-initialize_direct_addr (void)
-{
- int negative;
- int n_entries;
- char *env = NULL, *beg, *next, *envkey = NULL;
- struct in_addr addr, mask;
-
- if ( relay_method == METHOD_SOCKS ){
- if ( socks_version == 5 )
- envkey = ENV_SOCKS5_DIRECT;
- else
- envkey = ENV_SOCKS4_DIRECT;
- env = getparam(envkey);
- if ( env == NULL )
- env = getparam(ENV_SOCKS_DIRECT);
- } else if ( relay_method == METHOD_HTTP ){
- env = getparam(ENV_HTTP_DIRECT);
- }
-
- if ( env == NULL )
- env = getparam(ENV_CONNECT_DIRECT);
-
- if ( env == NULL )
- return; /* no entry */
- debug("making direct addr list from: '%s'\n", env);
- env = strdup( env ); /* reallocate to modify */
- beg = next = env;
- n_entries = 0;
- do {
- if ( MAX_DIRECT_ADDR_LIST <= n_entries ) {
- error("too many entries in %s", envkey);
- break; /* from do loop */
- }
- next = strchr( beg, ',');
- if ( next != NULL )
- *next++ = '\0';
- addr.s_addr = 0;
- mask.s_addr = 0;
- if (*beg == '!') {
- negative = 1;
- beg++;
- } else
- negative = 0;
- if ( !parse_addr_pair( beg, &addr, &mask ) ) {
- add_direct_addr( &addr, &mask, negative );
- } else {
- error("invalid addr format in %s: %s\n", envkey, beg);
- }
- if ( next != NULL )
- beg = next;
- } while ( next != NULL );
-
- free( env );
- return;
-}
-
-int
-cmp_addr (void *addr1, void *addr2, int addrlen)
-{
- return memcmp( addr1, addr2, addrlen );
-}
-
-int
-is_direct_address (const struct sockaddr_in *addr)
-{
- int i;
- struct in_addr saddr, iaddr;
-
- saddr = addr->sin_addr;
-
- /* Note: assume IPV4 address !! */
- for (i=0; i<n_direct_addr_list; i++ ) {
- iaddr = saddr;
- mask_addr( &iaddr, &direct_addr_list[i].mask,
- sizeof(struct in_addr));
- if (cmp_addr(&iaddr, &direct_addr_list[i].addr,
- sizeof(struct in_addr)) == 0) {
- if (direct_addr_list[i].negative) {
- debug("negative match, addr to be SOCKSify: %s\n",
- inet_ntoa(saddr));
- return 0; /* not direct */
- }
- if (!direct_addr_list[i].negative) {
- debug("positive match, addr to be direct: %s\n",
- inet_ntoa(saddr));
- return 1; /* direct*/
- }
- }
- }
- debug("not matched, addr to be SOCKSified: %s\n", inet_ntoa(saddr));
- return 0; /* not direct */
-}
-
-
-/** TTY operation **/
-
-int intr_flag = 0;
-
-#ifndef _WIN32
-void
-intr_handler(int sig)
-{
- intr_flag = 1;
-}
-
-void
-tty_change_echo(int fd, int enable)
-{
- static struct termios ntio, otio; /* new/old termios */
- static sigset_t nset, oset; /* new/old sigset */
- static struct sigaction nsa, osa; /* new/old sigaction */
- static int disabled = 0;
-
- if ( disabled && enable ) {
- /* enable echo */
- tcsetattr(fd, TCSANOW, &otio);
- disabled = 0;
- /* resotore sigaction */
- sigprocmask(SIG_SETMASK, &oset, NULL);
- sigaction(SIGINT, &osa, NULL);
- if ( intr_flag != 0 ) {
- /* re-generate signal */
- kill(getpid(), SIGINT);
- sigemptyset(&nset);
- sigsuspend(&nset);
- intr_flag = 0;
- }
- } else if (!disabled && !enable) {
- /* set SIGINTR handler and break syscall on singal */
- sigemptyset(&nset);
- sigaddset(&nset, SIGTSTP);
- sigprocmask(SIG_BLOCK, &nset, &oset);
- intr_flag = 0;
- memset(&nsa, 0, sizeof(nsa));
- nsa.sa_handler = intr_handler;
- sigaction(SIGINT, &nsa, &osa);
- /* disable echo */
- if (tcgetattr(fd, &otio) == 0 && (otio.c_lflag & ECHO)) {
- disabled = 1;
- ntio = otio;
- ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
- (void) tcsetattr(fd, TCSANOW, &ntio);
- }
- }
-
- return;
-}
-
-#define TTY_NAME "/dev/tty"
-int
-tty_readpass( const char *prompt, char *buf, size_t size )
-{
- int tty, ret = 0;
-
- tty = open(TTY_NAME, O_RDWR);
- if ( tty < 0 ) {
- error("Unable to open %s\n", TTY_NAME);
- return -1; /* can't open tty */
- }
- if ( size <= 0 )
- return -1; /* no room */
- write(tty, prompt, strlen(prompt));
- buf[0] = '\0';
- tty_change_echo(tty, 0); /* disable echo */
- ret = read(tty,buf, size-1);
- tty_change_echo(tty, 1); /* restore */
- write(tty, "\n", 1); /* new line */
- close(tty);
- if ( strchr(buf,'\n') == NULL )
- return -1;
- if ( 0 < ret )
- buf[ret] = '\0';
- return ret;
-}
-
-#else /* _WIN32 */
-
-BOOL __stdcall
-w32_intr_handler(DWORD dwCtrlType)
-{
- if ( dwCtrlType == CTRL_C_EVENT ) {
- intr_flag = 1;
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-#define tty_readpass w32_tty_readpass
-int
-w32_tty_readpass( const char *prompt, char *buf, size_t size )
-{
- HANDLE in = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE,
- 0, NULL, OPEN_EXISTING, 0, NULL);
- HANDLE out = CreateFile("CONOUT$", GENERIC_WRITE,
- 0, NULL, OPEN_EXISTING, 0, NULL);
- DWORD mode;
- DWORD ret, bytes;
-
- if (in == INVALID_HANDLE_VALUE || out == INVALID_HANDLE_VALUE)
- fatal("Cannot open console. (errno=%d)", GetLastError());
-
- WriteFile(out, prompt, strlen(prompt), &bytes, 0);
- SetConsoleCtrlHandler(w32_intr_handler, TRUE ); /* add handler */
- GetConsoleMode(in, &mode);
- SetConsoleMode(in, mode&~ENABLE_ECHO_INPUT); /* disable echo */
- ret = ReadFile(in, buf, size, &bytes, 0);
- SetConsoleMode(in, mode); /* enable echo */
- SetConsoleCtrlHandler( w32_intr_handler, FALSE ); /* remove handler */
- if ( intr_flag )
- GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); /* re-signal */
- WriteFile(out,"\n", 1, &bytes, 0);
- CloseHandle(in);
- CloseHandle(out);
- return ret;
-}
-
-#endif /* _WIN32 */
-
-/*** User / Password ***/
-
-/* SOCKS5 and HTTP Proxy authentication may requires username and
- password. We ll give it via environment variable or tty.
- Username and password for authentication are decided by
- following rules:
-
- Username is taken from
- 1) server location spec (i.e. user@host:port)
- 2) environment variables (see tables.1)
- 3) system account name currently logged in.
-
- Table.1 Order of environment variables for username
-
- | SOCKS v5 | SOCKS v4 | HTTP proxy |
- --+-------------+-------------+-----------------+
- 1 | SOCKS45_USER | SOCKS4_USER | HTTP_PROXY_USER |
- --+-------------+-------------+ |
- 2 | SOCKS_USER | |
- --+---------------------------+-----------------+
- 3 | CONNECT_USER |
- --+---------------------------------------------+
-
- Password is taken from
- 1) by environment variables (see table.2)
- 2) by entering from tty.
-
- Table.2 Order of environment variables for password
-
- | SOCKS v5 | HTTP proxy |
- --+-----------------+---------------------+
- 1 | SOCKS5_PASSWD | |
- --+-----------------+ HTTP_PROXY_PASSWORD |
- 2 | SOCKS5_PASSWORD | |
- --+-----------------+---------------------+
- 3 | CONNECT_PASSWORD |
- --+---------------------------------------+
-
- Note: SOCKS5_PASSWD which is added in rev. 1.79
- to share value with NEC SOCKS implementation.
- */
-
-char *
-determine_relay_user ()
-{
- char *user = NULL;
- /* get username from environment variable, or system. */
- if (relay_method == METHOD_SOCKS) {
- if (user == NULL && socks_version == 5)
- user = getparam (ENV_SOCKS5_USER);
- if (user == NULL && socks_version == 4)
- user = getparam (ENV_SOCKS4_USER);
- if (user == NULL)
- user = getparam (ENV_SOCKS_USER);
- } else if (relay_method == METHOD_HTTP) {
- if (user == NULL)
- user = getparam (ENV_HTTP_PROXY_USER);
- }
- if (user == NULL)
- user = getparam (ENV_CONNECT_USER);
- /* determine relay user by system call if not yet. */
- if (user == NULL)
- user = getusername();
- return user;
-}
-
-char *
-determine_relay_password ()
-{
- char *pass = NULL;
- if (pass == NULL && relay_method == METHOD_HTTP)
- pass = getparam(ENV_HTTP_PROXY_PASSWORD);
- if (pass == NULL && relay_method == METHOD_SOCKS)
- pass = getparam(ENV_SOCKS5_PASSWD);
- if (pass == NULL && relay_method == METHOD_SOCKS)
- pass = getparam(ENV_SOCKS5_PASSWORD);
- if (pass == NULL)
- pass = getparam(ENV_CONNECT_PASSWORD);
- return pass;
-}
-
-
-/*** network operations ***/
-
-
-/* set_relay()
- Determine relay informations:
- method, host, port, and username.
- 1st arg, METHOD should be METHOD_xxx.
- 2nd arg, SPEC is hostname or hostname:port or user@hostame:port.
- hostname is domain name or dot notation.
- If port is omitted, use 80 for METHOD_HTTP method,
- use 1080 for METHOD_SOCKS method.
- Username is also able to given by 3rd. format.
- 2nd argument SPEC can be NULL. if NULL, use environment variable.
- */
-int
-set_relay( int method, char *spec )
-{
- char *buf, *sep, *resolve;
-
- relay_method = method;
-
- read_parameter_file();
- initialize_direct_addr();
- if (n_direct_addr_list == 0) {
- debug ("No direct address are specified.\n");
- } else {
- int i;
- for ( i=0; i<n_direct_addr_list; i++ ) {
- char *s1, *s2;
- s1 = strdup(inet_ntoa(direct_addr_list[i].addr));
- s2 = strdup(inet_ntoa(direct_addr_list[i].mask));
- debug(" #%d: %c%s/%s\n", i,
- (direct_addr_list[i].negative)? '!': ' ',
- s1, s2);
- free(s1);
- free(s2);
- }
- }
-
- switch ( method ) {
- case METHOD_DIRECT:
- return -1; /* nothing to do */
-
- case METHOD_SOCKS:
- if ( spec == NULL ) {
- switch ( socks_version ) {
- case 5:
- spec = getparam(ENV_SOCKS5_SERVER);
- break;
- case 4:
- spec = getparam(ENV_SOCKS4_SERVER);
- break;
- }
- }
- if ( spec == NULL )
- spec = getparam(ENV_SOCKS_SERVER);
-
- if ( spec == NULL )
- fatal("Failed to determine SOCKS server.\n");
- relay_port = 1080; /* set default first */
-
- /* determine resolve method */
- if ( socks_resolve == RESOLVE_UNKNOWN ) {
- if ( ((socks_version == 5) &&
- ((resolve = getparam(ENV_SOCKS5_RESOLVE)) != NULL)) ||
- ((socks_version == 4) &&
- ((resolve = getparam(ENV_SOCKS4_RESOLVE)) != NULL)) ||
- ((resolve = getparam(ENV_SOCKS_RESOLVE)) != NULL) ) {
- socks_resolve = lookup_resolve( resolve );
- if ( socks_resolve == RESOLVE_UNKNOWN )
- fatal("Invalid resolve method: %s\n", resolve);
- } else {
- /* default */
- if ( socks_version == 5 )
- socks_resolve = RESOLVE_REMOTE;
- else
- socks_resolve = RESOLVE_LOCAL;
- }
- }
- break;
-
- case METHOD_HTTP:
- if ( spec == NULL )
- spec = getparam(ENV_HTTP_PROXY);
- if ( spec == NULL )
- fatal("You must specify http proxy server\n");
- relay_port = 80; /* set default first */
- break;
- case METHOD_TELNET:
- if ( spec == NULL )
- spec = getparam(ENV_TELNET_PROXY);
- if ( spec == NULL )
- fatal("You must specify telnet proxy server\n");
- relay_port = 23; /* set default first */
- }
-
- if (expect( spec, HTTP_PROXY_PREFIX)) {
- /* URL format like: "http://server:port/" */
- /* extract server:port part */
- buf = strdup( spec + strlen(HTTP_PROXY_PREFIX));
- buf[strcspn(buf, "/")] = '\0';
- } else {
- /* assume spec is aready "server:port" format */
- buf = strdup( spec );
- }
- spec = buf;
-
- /* check username in spec */
- sep = strchr( spec, '@' );
- if ( sep != NULL ) {
- *sep = '\0';
- relay_user = strdup( spec );
- spec = sep +1;
- }
- if (relay_user == NULL)
- relay_user = determine_relay_user();
-
- /* split out hostname and port number from spec */
- sep = strchr(spec,':');
- if ( sep == NULL ) {
- /* hostname only, port is already set as default */
- relay_host = strdup( spec );
- } else {
- /* hostname and port */
- relay_port = atoi(sep+1);
- *sep = '\0';
- relay_host = strdup( spec );
- }
- free(buf);
- return 0;
-}
-
-
-u_short
-resolve_port( const char *service )
-{
- int port;
- if ( service[strspn (service, digits)] == '\0' ) {
- /* all digits, port number */
- port = atoi(service);
- } else {
- /* treat as service name */
- struct servent *ent;
- ent = getservbyname( service, NULL );
- if ( ent == NULL ) {
- debug("Unknown service, '%s'\n", service);
- port = 0;
- } else {
- port = ntohs(ent->s_port);
- debug("service: %s => %d\n", service, port);
- }
- }
- return (u_short)port;
-}
-
-void
-make_revstr(void)
-{
- char *ptr;
- size_t len;
- ptr = strstr(rcs_revstr, ": ");
- if (!ptr) {
- revstr = strdup("unknown");
- return;
- }
- ptr += 2;
- len = strspn(ptr, dotdigits);
- if (0 < len) {
- revstr = xmalloc(len+1);
- memcpy(revstr, ptr, len);
- revstr[len] = '\0';
- }
-}
-
-int
-getarg( int argc, char **argv )
-{
- int err = 0;
- char *ptr, *server = (char*)NULL;
- int method = METHOD_DIRECT;
-
- progname = *argv;
- argc--, argv++;
-
- /* check optinos */
- while ( (0 < argc) && (**argv == '-') ) {
- ptr = *argv + 1;
- while ( *ptr ) {
- switch ( *ptr ) {
- case 's': /* use SOCKS */
- method = METHOD_SOCKS;
- break;
-
- case 'n': /* no proxy */
- method = METHOD_DIRECT;
- break;
-
- case 'h': /* use http-proxy */
- method = METHOD_HTTP;
- break;
- case 't':
- method = METHOD_TELNET;
- break;
-
- case 'S': /* specify SOCKS server */
- if ( 1 < argc ) {
- argv++, argc--;
- method = METHOD_SOCKS;
- server = *argv;
- } else {
- error("option '-%c' needs argument.\n", *ptr);
- err++;
- }
- break;
-
- case 'H': /* specify http-proxy server */
- if ( 1 < argc ) {
- argv++, argc--;
- method = METHOD_HTTP;
- server = *argv;
- } else {
- error("option '-%c' needs argument.\n", *ptr);
- err++;
- }
- break;
- case 'T': /* specify telnet proxy server */
- if ( 1 < argc ) {
- argv++, argc--;
- method = METHOD_TELNET;
- server = *argv;
- } else {
- error("option '-%c' needs argument.\n", *ptr);
- err++;
- }
- break;
-
- case 'c':
- if (1 < argc) {
- argv++, argc--;
- telnet_command = *argv;
- } else {
- error("option '%c' needs argument.\n", *ptr);
- err++;
- }
- break;
-
- case 'P':
- f_hold_session = 1;
- /* without break */
- case 'p': /* specify port to forward */
- if ( 1 < argc ) {
- argv++, argc--;
- local_type = LOCAL_SOCKET;
- local_port = resolve_port(*argv);
- } else {
- error("option '-%c' needs argument.\n", *ptr);
- err++;
- }
- break;
-
-#ifndef _WIN32
- case 'w':
- if ( 1 < argc ) {
- argv++, argc--;
- connect_timeout = atoi(*argv);
- } else {
- error("option '-%c' needs argument.\n", *ptr);
- err++;
- }
- break;
-#endif /* not _WIN32 */
-
- case '4':
- socks_version = 4;
- break;
-
- case '5':
- socks_version = 5;
- break;
-
- case 'a':
- if ( 1 < argc ) {
- argv++, argc--;
- socks5_auth = *argv;
- } else {
- error("option '-%c' needs argument.\n", *ptr);
- err++;
- }
- break;
-
- case 'R': /* specify resolve method */
- if ( 1 < argc ) {
- argv++, argc--;
- socks_resolve = lookup_resolve( *argv );
- } else {
- error("option '-%c' needs argument.\n", *ptr);
- err++;
- }
- break;
-
- case 'V': /* print version */
- fprintf(stderr, "%s\nVersion %s\n", progdesc, revstr);
- exit(0);
-
- case 'd': /* debug mode */
- f_debug++;
- break;
-
- default:
- error("unknown option '-%c'\n", *ptr);
- err++;
- }
- ptr++;
- }
- argc--, argv++;
- }
-
- /* check error */
- if ( 0 < err )
- goto quit;
-
- set_relay( method, server );
-
- /* check destination HOST (MUST) */
- if ( argc == 0 ) {
- fprintf(stderr, "%s\nVersion %s\n", progdesc, revstr);
- fprintf(stderr, usage, progname);
- exit(0);
- }
- dest_host = argv[0];
- /* decide port or service name from programname or argument */
- if ( ((ptr=strrchr( progname, '/' )) != NULL) ||
- ((ptr=strchr( progname, '\\')) != NULL) )
- ptr++;
- else
- ptr = progname;
- if ( dest_port == 0 ) {
- /* accept only if -P is not specified. */
- if ( 1 < argc ) {
- /* get port number from argument (prior to progname) */
- /* NOTE: This way is for cvs ext method. */
- dest_port = resolve_port(argv[1]);
- } else if ( strncmp( ptr, "connect-", 8) == 0 ) {
- /* decide port number from program name */
- char *str = strdup( ptr+8 );
- str[strcspn( str, "." )] = '\0';
- dest_port = resolve_port(str);
- free(str);
- }
- }
- /* check port number */
- if ( dest_port <= 0 ) {
- error( "You must specify the destination port correctly.\n");
- err++;
- goto quit;
- }
- if ( (relay_method != METHOD_DIRECT) && (relay_port <= 0) ) {
- error("Invalid relay port: %d\n", dest_port);
- err++;
- goto quit;
- }
-
-quit:
- /* report for debugging */
- debug("relay_method = %s (%d)\n",
- method_names[relay_method], relay_method);
- if ( relay_method != METHOD_DIRECT ) {
- debug("relay_host=%s\n", relay_host);
- debug("relay_port=%d\n", relay_port);
- debug("relay_user=%s\n", relay_user);
- }
- if ( relay_method == METHOD_SOCKS ) {
- debug("socks_version=%d\n", socks_version);
- debug("socks_resolve=%s (%d)\n",
- resolve_names[socks_resolve], socks_resolve);
- }
- debug("local_type=%s\n", local_type_names[local_type]);
- if ( local_type == LOCAL_SOCKET ) {
- debug("local_port=%d\n", local_port);
- if (f_hold_session)
- debug (" with holding remote session.\n");
- }
- debug("dest_host=%s\n", dest_host);
- debug("dest_port=%d\n", dest_port);
- if ( 0 < err ) {
- fprintf(stderr, usage, progname);
- exit(1);
- }
- return 0;
-}
-
-#ifndef _WIN32
-/* Time-out feature is not allowed for Win32 native compilers. */
-/* MSVC and Borland C cannot but Cygwin and UNIXes can. */
-
-/* timeout signal hander */
-void
-sig_timeout(void)
-{
- debug( "timed out\n" );
- signal( SIGALRM, SIG_IGN );
- alarm( 0 );
-}
-
-/* set timeout param = seconds, 0 clears */
-void
-set_timeout(int timeout)
-{
- /* This feature is allowed for UNIX or cygwin environments, currently */
- if ( timeout == 0 ) {
- debug( "clearing timeout\n" );
- signal( SIGALRM, SIG_IGN );
- alarm( 0 );
- } else {
- debug( "setting timeout: %d seconds\n", timeout );
- signal(SIGALRM, (void *)sig_timeout);
- alarm( timeout );
- }
-}
-#endif
-
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
-void
-switch_ns (struct sockaddr_in *ns)
-{
- res_init();
- memcpy (&_res.nsaddr_list[0], ns, sizeof(*ns));
- _res.nscount = 1;
- debug("Using nameserver at %s\n", inet_ntoa(ns->sin_addr));
-}
-#endif /* !_WIN32 && !__CYGWIN32__ */
-
-/* TODO: IPv6
- TODO: fallback if askpass execution failed.
- */
-
-int
-local_resolve (const char *host, struct sockaddr_in *addr)
-{
- struct hostent *ent;
- if ( strspn(host, dotdigits) == strlen(host) ) {
- /* given by IPv4 address */
- addr->sin_family = AF_INET;
- addr->sin_addr.s_addr = inet_addr(host);
- } else {
- debug("resolving host by name: %s\n", host);
- ent = gethostbyname (host);
- if ( ent ) {
- memcpy (&addr->sin_addr, ent->h_addr, ent->h_length);
- addr->sin_family = ent->h_addrtype;
- debug("resolved: %s (%s)\n",
- host, inet_ntoa(addr->sin_addr));
- } else {
- debug("failed to resolve locally.\n");
- return -1; /* failed */
- }
- }
- return 0; /* good */
-}
-
-int
-open_connection( const char *host, u_short port )
-{
- SOCKET s;
- struct sockaddr_in saddr;
-
- if ( relay_method == METHOD_DIRECT ) {
- host = dest_host;
- port = dest_port;
- } else if ((local_resolve (dest_host, &saddr) >= 0)&&
- (is_direct_address(&saddr))) {
- debug("%s is connected directly\n", dest_host);
- relay_method = METHOD_DIRECT;
- host = dest_host;
- port = dest_port;
- } else {
- host = relay_host;
- port = relay_port;
- }
-
- if (local_resolve (host, &saddr) < 0) {
- error("can't resolve hostname: %s\n", host);
- return SOCKET_ERROR;
- }
- saddr.sin_port = htons(port);
-
- debug("connecting to %s:%u\n", inet_ntoa(saddr.sin_addr), port);
- s = socket( AF_INET, SOCK_STREAM, 0 );
- if ( connect( s, (struct sockaddr *)&saddr, sizeof(saddr))
- == SOCKET_ERROR) {
- debug( "connect() failed.\n");
- return SOCKET_ERROR;
- }
- return s;
-}
-
-void
-report_text( char *prefix, char *buf )
-{
- static char work[1024];
- char *tmp;
-
- if ( !f_debug )
- return;
- if ( !f_report )
- return; /* don't report */
- debug("%s \"", prefix);
- while ( *buf ) {
- memset( work, 0, sizeof(work));
- tmp = work;
- while ( *buf && ((tmp-work) < (int)sizeof(work)-5) ) {
- switch ( *buf ) {
- case '\t': *tmp++ = '\\'; *tmp++ = 't'; break;
- case '\r': *tmp++ = '\\'; *tmp++ = 'r'; break;
- case '\n': *tmp++ = '\\'; *tmp++ = 'n'; break;
- case '\\': *tmp++ = '\\'; *tmp++ = '\\'; break;
- default:
- if ( isprint(*buf) ) {
- *tmp++ = *buf;
- } else {
- int consumed = tmp - work;
- snprintf( tmp, sizeof(work)-consumed,
- "\\x%02X", (unsigned char)*buf);
- tmp += strlen(tmp);
- }
- }
- buf++;
- *tmp = '\0';
- }
- debug_("%s", work);
- }
-
- debug_("\"\n");
-}
-
-
-void
-report_bytes( char *prefix, char *buf, int len )
-{
- if ( ! f_debug )
- return;
- debug( "%s", prefix );
- while ( 0 < len ) {
- fprintf( stderr, " %02x", *(unsigned char *)buf);
- buf++;
- len--;
- }
- fprintf(stderr, "\n");
- return;
-}
-
-int
-atomic_out( SOCKET s, char *buf, int size )
-{
- int ret, len;
-
- assert( buf != NULL );
- assert( 0<=size );
- /* do atomic out */
- ret = 0;
- while ( 0 < size ) {
- len = send( s, buf+ret, size, 0 );
- if ( len == -1 )
- fatal("atomic_out() failed to send(), %d\n", socket_errno());
- ret += len;
- size -= len;
- }
- if (!f_report) {
- debug("atomic_out() [some bytes]\n");
- debug(">>> xx xx xx xx ...\n");
- } else {
- debug("atomic_out() [%d bytes]\n", ret);
- report_bytes(">>>", buf, ret);
- }
- return ret;
-}
-
-int
-atomic_in( SOCKET s, char *buf, int size )
-{
- int ret, len;
-
- assert( buf != NULL );
- assert( 0<=size );
-
- /* do atomic in */
- ret = 0;
- while ( 0 < size ) {
- len = recv( s, buf+ret, size, 0 );
- if ( len == -1 ) {
- fatal("atomic_in() failed to recv(), %d\n", socket_errno());
- } else if ( len == 0 ) {
- fatal( "Connection closed by peer.\n");
- }
- ret += len;
- size -= len;
- }
- if (!f_report) {
- debug("atomic_in() [some bytes]\n");
- debug("<<< xx xx xx xx ...\n");
- } else {
- debug("atomic_in() [%d bytes]\n", ret);
- report_bytes("<<<", buf, ret);
- }
- return ret;
-}
-
-int
-line_input( SOCKET s, char *buf, int size )
-{
- char *dst = buf;
- if ( size == 0 )
- return 0; /* no error */
- size--;
- while ( 0 < size ) {
- switch ( recv( s, dst, 1, 0) ) { /* recv one-by-one */
- case SOCKET_ERROR:
- error("recv() error\n");
- return -1; /* error */
- case 0:
- size = 0; /* end of stream */
- break;
- default:
- /* continue reading until last 1 char is EOL? */
- if ( *dst == '\n' ) {
- /* finished */
- size = 0;
- } else {
- /* more... */
- size--;
- }
- dst++;
- }
- }
- *dst = '\0';
- report_text( "<<<", buf);
- return 0;
-}
-
-/* cut_token()
- Span token in given string STR until char in DELIM is appeared.
- Then replace contiguous DELIMS with '\0' for string termination
- and returns next pointer.
- If no next token, return NULL.
-*/
-char *
-cut_token( char *str, char *delim)
-{
- char *ptr = str + strcspn(str, delim);
- char *end = ptr + strspn(ptr, delim);
- if ( ptr == str )
- return NULL;
- while ( ptr < end )
- *ptr++ = '\0';
- return ptr;
-}
-
-const char *
-lookup(int num, LOOKUP_ITEM *items)
-{
- int i = 0;
- while (0 <= items[i].num) {
- if (items[i].num == num)
- return items[i].str;
- i++;
- }
- return "(unknown)";
-}
-
-/* readpass()
- password input routine
- Use ssh-askpass (same mechanism to OpenSSH)
-*/
-char *
-readpass( const char* prompt, ...)
-{
- static char buf[1000]; /* XXX, don't be fix length */
- va_list args;
- va_start(args, prompt);
- vsnprintf(buf, sizeof(buf), prompt, args);
- va_end(args);
-
- if ( getparam(ENV_SSH_ASKPASS)
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
- && getenv("DISPLAY")
-#endif /* not _WIN32 && not __CYGWIN32__ */
- ) {
- /* use ssh-askpass to get password */
- FILE *fp;
- char *askpass = getparam(ENV_SSH_ASKPASS), *cmd;
- int cmd_size = strlen(askpass) +1 +1 +strlen(buf) +1 +1;
- cmd = xmalloc(cmd_size);
- snprintf(cmd, cmd_size, "%s \"%s\"", askpass, buf);
- fp = popen(cmd, "r");
- free(cmd);
- if ( fp == NULL )
- return NULL; /* fail */
- buf[0] = '\0';
- if (fgets(buf, sizeof(buf), fp) == NULL)
- return NULL; /* fail */
- fclose(fp);
- } else {
- tty_readpass( buf, buf, sizeof(buf));
- }
- buf[strcspn(buf, "\r\n")] = '\0';
- return buf;
-}
-
-static int
-socks5_do_auth_userpass( int s )
-{
- unsigned char buf[1024], *ptr;
- char *pass = NULL;
- int len;
-
- /* do User/Password authentication. */
- /* This feature requires username and password from
- command line argument or environment variable,
- or terminal. */
- if (relay_user == NULL)
- fatal("cannot determine user name.\n");
-
- /* get password from environment variable if exists. */
- if ((pass=determine_relay_password()) == NULL &&
- (pass=readpass("Enter SOCKS5 password for %s@%s: ",
- relay_user, relay_host)) == NULL)
- fatal("Cannot get password for user: %s\n", relay_user);
-
- /* make authentication packet */
- ptr = buf;
- PUT_BYTE( ptr++, 1 ); /* subnegotiation ver.: 1 */
- len = strlen( relay_user ); /* ULEN and UNAME */
- PUT_BYTE( ptr++, len );
- strcpy( ptr, relay_user );
- ptr += len;
- len = strlen( pass ); /* PLEN and PASSWD */
- PUT_BYTE( ptr++, strlen(pass));
- strcpy( ptr, pass );
- ptr += len;
- memset (pass, 0, strlen(pass)); /* erase password */
-
- /* send it and get answer */
- f_report = 0;
- atomic_out( s, buf, ptr-buf );
- f_report = 1;
- atomic_in( s, buf, 2 );
-
- /* check status */
- if ( buf[1] == 0 )
- return 0; /* success */
- else
- return -1; /* fail */
-}
-
-static const char *
-socks5_getauthname( int auth )
-{
- switch ( auth ) {
- case SOCKS5_AUTH_REJECT: return "REJECTED";
- case SOCKS5_AUTH_NOAUTH: return "NO-AUTH";
- case SOCKS5_AUTH_GSSAPI: return "GSSAPI";
- case SOCKS5_AUTH_USERPASS: return "USERPASS";
- case SOCKS5_AUTH_CHAP: return "CHAP";
- case SOCKS5_AUTH_EAP: return "EAP";
- case SOCKS5_AUTH_MAF: return "MAF";
- default: return "(unknown)";
- }
-}
-
-typedef struct {
- char* name;
- unsigned char auth;
-} AUTH_METHOD_ITEM;
-
-AUTH_METHOD_ITEM socks5_auth_table[] = {
- { "none", SOCKS5_AUTH_NOAUTH },
- { "gssapi", SOCKS5_AUTH_GSSAPI },
- { "userpass", SOCKS5_AUTH_USERPASS },
- { "chap", SOCKS5_AUTH_CHAP },
- { NULL, -1 },
-};
-
-int
-socks5_auth_parse_1(char *start, char *end){
- int i, len;
- for ( ; *start; start++ )
- if ( *start != ' ' && *start != '\t') break;
- for ( end--; end >= start; end-- ) {
- if ( *end != ' ' && *end != '\t'){
- end++;
- break;
- }
- }
- len = end - start;
- for ( i = 0; socks5_auth_table[i].name != NULL; i++ ){
- if ( strncmp(start, socks5_auth_table[i].name, len) == 0) {
- return socks5_auth_table[i].auth;
- }
- }
- fatal("Unknown auth method: %s\n", start);
- return -1;
-}
-
-int
-socks5_auth_parse(char *start, unsigned char *auth_list, int max_auth){
- char *end;
- int i = 0;
- while ( i < max_auth ) {
- end = strchr(start, ',');
- if (*start && end) {
- auth_list[i++] = socks5_auth_parse_1(start, end);
- start = ++end;
- } else {
- break;
- }
- }
- if ( *start && ( i < max_auth ) ){
- for( end = start; *end; end++ );
- auth_list[i++] = socks5_auth_parse_1(start, end);
- } else {
- fatal("Too much auth method.\n");
- }
- return i;
-}
-
-/* begin SOCKS5 relaying
- And no authentication is supported.
- */
-int
-begin_socks5_relay( SOCKET s )
-{
- unsigned char buf[256], *ptr, *env = socks5_auth;
- unsigned char n_auth = 0; unsigned char auth_list[10], auth_method;
- int len, auth_result, i;
-
- debug( "begin_socks_relay()\n");
-
- /* request authentication */
- ptr = buf;
- PUT_BYTE( ptr++, 5); /* SOCKS version (5) */
-
- if ( env == NULL )
- env = getparam(ENV_SOCKS5_AUTH);
- if ( env == NULL ) {
- /* add no-auth authentication */
- auth_list[n_auth++] = SOCKS5_AUTH_NOAUTH;
- /* add user/pass authentication */
- auth_list[n_auth++] = SOCKS5_AUTH_USERPASS;
- } else {
- n_auth = socks5_auth_parse(env, auth_list, 10);
- }
- PUT_BYTE( ptr++, n_auth); /* num auth */
- for (i=0; i<n_auth; i++) {
- debug("available auth method[%d] = %s (0x%02x)\n",
- i, socks5_getauthname(auth_list[i]), auth_list[i]);
- PUT_BYTE( ptr++, auth_list[i]); /* authentications */
- }
- atomic_out( s, buf, ptr-buf ); /* send requst */
- atomic_in( s, buf, 2 ); /* recv response */
- if ( (buf[0] != 5) || /* ver5 response */
- (buf[1] == 0xFF) ) { /* check auth method */
- error("No auth method accepted.\n");
- return -1;
- }
- auth_method = buf[1];
-
- debug("auth method: %s\n", socks5_getauthname(auth_method));
-
- switch ( auth_method ) {
- case SOCKS5_AUTH_REJECT:
- error("No acceptable authentication method\n");
- return -1; /* fail */
-
- case SOCKS5_AUTH_NOAUTH:
- /* nothing to do */
- auth_result = 0;
- break;
-
- case SOCKS5_AUTH_USERPASS:
- auth_result = socks5_do_auth_userpass(s);
- break;
-
- default:
- error("Unsupported authentication method: %s\n",
- socks5_getauthname( auth_method ));
- return -1; /* fail */
- }
- if ( auth_result != 0 ) {
- error("Authentication failed.\n");
- return -1;
- }
- /* request to connect */
- ptr = buf;
- PUT_BYTE( ptr++, 5); /* SOCKS version (5) */
- PUT_BYTE( ptr++, 1); /* CMD: CONNECT */
- PUT_BYTE( ptr++, 0); /* FLG: 0 */
- if ( dest_addr.sin_addr.s_addr == 0 ) {
- /* resolved by SOCKS server */
- PUT_BYTE( ptr++, 3); /* ATYP: DOMAINNAME */
- len = strlen(dest_host);
- PUT_BYTE( ptr++, len); /* DST.ADDR (len) */
- memcpy( ptr, dest_host, len ); /* (hostname) */
- ptr += len;
- } else {
- /* resolved localy */
- PUT_BYTE( ptr++, 1 ); /* ATYP: IPv4 */
- memcpy( ptr, &dest_addr.sin_addr.s_addr, sizeof(dest_addr.sin_addr));
- ptr += sizeof(dest_addr.sin_addr);
- }
- PUT_BYTE( ptr++, dest_port>>8); /* DST.PORT */
- PUT_BYTE( ptr++, dest_port&0xFF);
- atomic_out( s, buf, ptr-buf); /* send request */
- atomic_in( s, buf, 4 ); /* recv response */
- if ( (buf[1] != SOCKS5_REP_SUCCEEDED) ) { /* check reply code */
- error("Got error response from SOCKS server: %d (%s).\n",
- buf[1], lookup(buf[1], socks5_rep_names));
- return -1;
- }
- ptr = buf + 4;
- switch ( buf[3] ) { /* case by ATYP */
- case 1: /* IP v4 ADDR*/
- atomic_in( s, ptr, 4+2 ); /* recv IPv4 addr and port */
- break;
- case 3: /* DOMAINNAME */
- atomic_in( s, ptr, 1 ); /* recv name and port */
- atomic_in( s, ptr+1, *(unsigned char*)ptr + 2);
- break;
- case 4: /* IP v6 ADDR */
- atomic_in( s, ptr, 16+2 ); /* recv IPv6 addr and port */
- break;
- }
-
- /* Conguraturation, connected via SOCKS5 server! */
- return 0;
-}
-
-/* begin SOCKS protocol 4 relaying
- And no authentication is supported.
-
- There's SOCKS protocol version 4 and 4a. Protocol version
- 4a has capability to resolve hostname by SOCKS server, so
- we don't need resolving IP address of destination host on
- local machine.
-
- Environment variable SOCKS_RESOLVE directs how to resolve
- IP addess. There's 3 keywords allowed; "local", "remote"
- and "both" (case insensitive). Keyword "local" means taht
- target host name is resolved by localhost resolver
- (usualy with gethostbyname()), "remote" means by remote
- SOCKS server, "both" means to try resolving by localhost
- then remote.
-
- SOCKS4 protocol and authentication of SOCKS5 protocol
- requires user name on connect request.
- User name is determined by following method.
-
- 1. If server spec has user@hostname:port format then
- user part is used for this SOCKS server.
-
- 2. Get user name from environment variable LOGNAME, USER
- (in this order).
-
-*/
-int
-begin_socks4_relay( SOCKET s )
-{
- unsigned char buf[256], *ptr;
-
- debug( "begin_socks_relay()\n");
-
- /* make connect request packet
- protocol v4:
- VN:1, CD:1, PORT:2, ADDR:4, USER:n, NULL:1
- protocol v4a:
- VN:1, CD:1, PORT:2, DUMMY:4, USER:n, NULL:1, HOSTNAME:n, NULL:1
- */
- ptr = buf;
- PUT_BYTE( ptr++, 4); /* protocol version (4) */
- PUT_BYTE( ptr++, 1); /* CONNECT command */
- PUT_BYTE( ptr++, dest_port>>8); /* destination Port */
- PUT_BYTE( ptr++, dest_port&0xFF);
- /* destination IP */
- memcpy(ptr, &dest_addr.sin_addr, sizeof(dest_addr.sin_addr));
- ptr += sizeof(dest_addr.sin_addr);
- if ( dest_addr.sin_addr.s_addr == 0 )
- *(ptr-1) = 1; /* fake, protocol 4a */
- /* username */
- if (relay_user == NULL)
- fatal( "Cannot determine user name.\n");
- strcpy( ptr, relay_user );
- ptr += strlen( relay_user ) +1;
- /* destination host name (for protocol 4a) */
- if ( (socks_version == 4) && (dest_addr.sin_addr.s_addr == 0)) {
- strcpy( ptr, dest_host );
- ptr += strlen( dest_host ) +1;
- }
- /* send command and get response
- response is: VN:1, CD:1, PORT:2, ADDR:4 */
- atomic_out( s, buf, ptr-buf); /* send request */
- atomic_in( s, buf, 8 ); /* recv response */
- if ( (buf[1] != SOCKS4_REP_SUCCEEDED) ) { /* check reply code */
- error("Got error response: %d: '%s'.\n",
- buf[1], lookup(buf[1], socks4_rep_names));
- return -1; /* failed */
- }
-
- /* Conguraturation, connected via SOCKS4 server! */
- return 0;
-}
-
-int
-sendf(SOCKET s, const char *fmt,...)
-{
- static char buf[10240]; /* xxx, enough? */
-
- va_list args;
- va_start( args, fmt );
- vsnprintf( buf, sizeof(buf), fmt, args );
- va_end( args );
-
- report_text(">>>", buf);
- if ( send(s, buf, strlen(buf), 0) == SOCKET_ERROR ) {
- debug("failed to send http request. errno=%d\n", socket_errno());
- return -1;
- }
- return 0;
-}
-
-const char *base64_table =
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-char *
-make_base64_string(const char *str)
-{
- static char *buf;
- unsigned char *src;
- char *dst;
- int bits, data, src_len, dst_len;
- /* make base64 string */
- src_len = strlen(str);
- dst_len = (src_len+2)/3*4;
- buf = xmalloc(dst_len+1);
- bits = data = 0;
- src = (unsigned char *)str;
- dst = (unsigned char *)buf;
- while ( dst_len-- ) {
- if ( bits < 6 ) {
- data = (data << 8) | *src;
- bits += 8;
- if ( *src != 0 )
- src++;
- }
- *dst++ = base64_table[0x3F & (data >> (bits-6))];
- bits -= 6;
- }
- *dst = '\0';
- /* fix-up tail padding */
- switch ( src_len%3 ) {
- case 1:
- *--dst = '=';
- case 2:
- *--dst = '=';
- }
- return buf;
-}
-
-
-int
-basic_auth (SOCKET s)
-{
- char *userpass;
- char *cred;
- const char *user = relay_user;
- char *pass = NULL;
- int len, ret;
-
- /* Get username/password for authentication */
- if (user == NULL)
- fatal("Cannot decide username for proxy authentication.");
- if ((pass = determine_relay_password ()) == NULL &&
- (pass = readpass("Enter proxy authentication password for %s@%s: ",
- relay_user, relay_host)) == NULL)
- fatal("Cannot decide password for proxy authentication.");
-
- len = strlen(user)+strlen(pass)+1;
- userpass = xmalloc(len+1);
- snprintf(userpass, len+1, "%s:%s", user, pass);
- memset (pass, 0, strlen(pass));
- cred = make_base64_string(userpass);
- memset (userpass, 0, len);
-
- f_report = 0; /* don't report for security */
- ret = sendf(s, "Proxy-Authorization: Basic %s\r\n", cred);
- f_report = 1;
- report_text(">>>", "Proxy-Authorization: Basic xxxxx\r\n");
-
- memset(cred, 0, strlen(cred));
- free(cred);
-
- return ret;
-}
-
-/* begin relaying via HTTP proxy
- Directs CONNECT method to proxy server to connect to
- destination host (and port). It may not be allowed on your
- proxy server.
- */
-int
-begin_http_relay( SOCKET s )
-{
- char buf[1024];
- int result;
- char *auth_what;
-
- debug("begin_http_relay()\n");
-
- if (sendf(s,"CONNECT %s:%d HTTP/1.0\r\n", dest_host, dest_port) < 0)
- return START_ERROR;
- if (proxy_auth_type == PROXY_AUTH_BASIC && basic_auth (s) < 0)
- return START_ERROR;
- if (sendf(s,"\r\n") < 0)
- return START_ERROR;
-
- /* get response */
- if ( line_input(s, buf, sizeof(buf)) < 0 ) {
- debug("failed to read http response.\n");
- return START_ERROR;
- }
-
- /* check status */
- if (!strchr(buf, ' ')) {
- error ("Unexpected http response: '%s'.\n", buf);
- return START_ERROR;
- }
- result = atoi(strchr(buf,' '));
-
- switch ( result ) {
- case 200:
- /* Conguraturation, connected via http proxy server! */
- debug("connected, start user session.\n");
- break;
- case 302: /* redirect */
- do {
- if (line_input(s, buf, sizeof(buf)))
- break;
- downcase(buf);
- if (expect(buf, "Location: ")) {
- relay_host = cut_token(buf, "//");
- cut_token(buf, "/");
- relay_port = atoi(cut_token(buf, ":"));
- }
- } while (strcmp(buf,"\r\n") != 0);
- return START_RETRY;
-
- /* We handle both 401 and 407 codes here: 401 is WWW-Authenticate, which
- * not strictly the correct response, but some proxies do send this (e.g.
- * Symantec's Raptor firewall) */
- case 401: /* WWW-Auth required */
- case 407: /* Proxy-Auth required */
- /** NOTE: As easy implementation, we support only BASIC scheme
- and ignore realm. */
- /* If proxy_auth_type is PROXY_AUTH_BASIC and get
- this result code, authentication was failed. */
- if (proxy_auth_type != PROXY_AUTH_NONE) {
- error("Authentication failed.\n");
- return START_ERROR;
- }
- auth_what = (result == 401) ? "WWW-Authenticate:" : "Proxy-Authenticate:";
- do {
- if ( line_input(s, buf, sizeof(buf)) ) {
- break;
- }
- downcase(buf);
- if (expect(buf, auth_what)) {
- /* parse type and realm */
- char *scheme, *realm;
- scheme = cut_token(buf, " ");
- realm = cut_token(scheme, " ");
- if ( scheme == NULL || realm == NULL ) {
- debug("Invalid format of %s field.", auth_what);
- return START_ERROR; /* fail */
- }
- /* check supported auth type */
- if (expect(scheme, "basic")) {
- proxy_auth_type = PROXY_AUTH_BASIC;
- } else {
- debug("Unsupported authentication type: %s", scheme);
- }
- }
- } while (strcmp(buf,"\r\n") != 0);
- if ( proxy_auth_type == PROXY_AUTH_NONE ) {
- debug("Can't find %s in response header.", auth_what);
- return START_ERROR;
- } else {
- return START_RETRY;
- }
-
- default:
- /* Not allowed */
- debug("http proxy is not allowed.\n");
- return START_ERROR;
- }
- /* skip to end of response header */
- do {
- if ( line_input(s, buf, sizeof(buf) ) ) {
- debug("Can't skip response headers\n");
- return START_ERROR;
- }
- } while ( strcmp(buf,"\r\n") != 0 );
-
- return START_OK;
-}
-
-/* begin relaying via TELNET proxy.
- Sends string specified by telnet_command (-c option) with
- replacing host name and port number to the socket. */
-int
-begin_telnet_relay( SOCKET s )
-{
- char buf[1024];
- char *cmd;
- char *good_phrase = "connected to";
- char *bad_phrase_list[] = {
- " failed", " refused", " rejected", " closed"
- };
- char sep = ' ';
- int i;
-
- debug("begin_telnet_relay()\n");
-
- /* report phrase */
- debug("good phrase: '%s'\n", good_phrase);
- debug("bad phrases");
- sep = ':';
- for (i=0; i< (sizeof(bad_phrase_list) / sizeof(char*)); i++) {
- debug_("%c '%s'", sep, bad_phrase_list[i]);
- sep = ',';
- }
- debug_("\n");
-
- /* make request string with replacing %h by destination hostname
- and %p by port number, etc. */
- cmd = expand_host_and_port(telnet_command, dest_host, dest_port);
-
- /* Sorry, we send request string now without waiting a prompt. */
- if (sendf(s, "%s\r\n", cmd) < 0) {
- free(cmd);
- return START_ERROR;
- }
- free(cmd);
-
- /* Process answer from proxy until good or bad phrase is detected. We
- assume that the good phrase should be appeared only in the final
- line of proxy responses. Bad keywods in the line causes operation
- fail. First checks a good phrase, then checks bad phrases.
- If no match, continue reading line from proxy. */
- while (!line_input(s, buf, sizeof(buf)) && buf[0] != '\0') {
- downcase(buf);
- /* first, check good phrase */
- if (strstr(buf, good_phrase)) {
- debug("good phrase is detected: '%s'\n", good_phrase);
- return START_OK;
- }
- /* then, check bad phrase */
- for (i=0; i<(sizeof(bad_phrase_list)/sizeof(char*)); i++) {
- if (strstr(buf, bad_phrase_list[i]) != NULL) {
- debug("bad phrase is detected: '%s'\n", bad_phrase_list[i]);
- return START_ERROR;
- }
- }
- }
- debug("error reading from telnet proxy\n");
-
- return START_ERROR;
-}
-
-
-#ifdef _WIN32
-/* ddatalen()
- Returns 1 if data is available, otherwise return 0
- */
-int
-stdindatalen (void)
-{
- DWORD len = 0;
- struct stat st;
- fstat( 0, &st );
- if ( st.st_mode & _S_IFIFO ) {
- /* in case of PIPE */
- if ( !PeekNamedPipe( GetStdHandle(STD_INPUT_HANDLE),
- NULL, 0, NULL, &len, NULL) ) {
- if ( GetLastError() == ERROR_BROKEN_PIPE ) {
- /* PIPE source is closed */
- /* read() will detects EOF */
- len = 1;
- } else {
- fatal("PeekNamedPipe() failed, errno=%d\n",
- GetLastError());
- }
- }
- } else if ( st.st_mode & _S_IFREG ) {
- /* in case of regular file (redirected) */
- len = 1; /* always data ready */
- } else if ( _kbhit() ) {
- /* in case of console */
- len = 1;
- }
- return len;
-}
-#endif /* _WIN32 */
-
-/* relay byte from stdin to socket and fro socket to stdout.
- returns reason of termination */
-int
-do_repeater( SOCKET local_in, SOCKET local_out, SOCKET remote )
-{
- /** vars for local input data **/
- char lbuf[1024]; /* local input buffer */
- int lbuf_len; /* available data in lbuf */
- int f_local; /* read local input more? */
- /** vars for remote input data **/
- char rbuf[1024]; /* remote input buffer */
- int rbuf_len; /* available data in rbuf */
- int f_remote; /* read remote input more? */
- int close_reason = REASON_UNK; /* reason of end repeating */
- /** other variables **/
- int nfds, len;
- fd_set ifds, ofds;
- struct timeval *tmo;
-#ifdef _WIN32
- struct timeval win32_tmo;
-#endif /* _WIN32 */
-
- /* repeater between stdin/out and socket */
- nfds = ((local_in<remote)? remote: local_in) +1;
- f_local = 1; /* yes, read from local */
- f_remote = 1; /* yes, read from remote */
- lbuf_len = 0;
- rbuf_len = 0;
-
- while ( f_local || f_remote ) {
- FD_ZERO(&ifds );
- FD_ZERO(&ofds );
- tmo = NULL;
-
- /** prepare for reading local input **/
- if ( f_local && (lbuf_len < (int)sizeof(lbuf)) ) {
-#ifdef _WIN32
- if ( local_type != LOCAL_SOCKET ) {
- /* select() on Winsock is not accept standard handle.
- So use select() with short timeout and checking data
- in stdin by another method. */
- win32_tmo.tv_sec = 0;
- win32_tmo.tv_usec = 10*1000; /* 10 ms */
- tmo = &win32_tmo;
- } else
-#endif /* !_WIN32 */
- FD_SET( local_in, &ifds );
- }
-
- /** prepare for reading remote input **/
- if ( f_remote && (rbuf_len < (int)sizeof(rbuf)) ) {
- FD_SET( remote, &ifds );
- }
-
- /* FD_SET( local_out, ofds ); */
- /* FD_SET( remote, ofds ); */
-
- if ( select( nfds, &ifds, &ofds, (fd_set*)NULL, tmo ) == -1 ) {
- /* some error */
- error( "select() failed, %d\n", socket_errno());
- return REASON_ERROR;
- }
-#ifdef _WIN32
- /* fake ifds if local is stdio handle because
- select() of Winsock does not accept stdio
- handle. */
- if (f_local && (local_type!=LOCAL_SOCKET) && (0<stdindatalen()))
- FD_SET(0,&ifds); /* data ready */
-#endif
-
- /* remote => local */
- if ( FD_ISSET(remote, &ifds) && (rbuf_len < (int)sizeof(rbuf)) ) {
- len = recv( remote, rbuf + rbuf_len, sizeof(rbuf)-rbuf_len, 0);
- if ( len == 0 ) {
- debug("connection closed by peer\n");
- close_reason = REASON_CLOSED_BY_REMOTE;
- f_remote = 0; /* no more read from socket */
- f_local = 0;
- } else if ( len == -1 ) {
- if (socket_errno() != ECONNRESET) {
- /* error */
- fatal("recv() faield, %d\n", socket_errno());
- } else {
- debug("ECONNRESET detected\n");
- }
- } else {
- debug("recv %d bytes\n", len);
- if ( 1 < f_debug ) /* more verbose */
- report_bytes( "<<<", rbuf, rbuf_len);
- rbuf_len += len;
- }
- }
-
- /* local => remote */
- if ( FD_ISSET(local_in, &ifds) && (lbuf_len < (int)sizeof(lbuf)) ) {
- if (local_type == LOCAL_SOCKET)
- len = recv(local_in, lbuf + lbuf_len,
- sizeof(lbuf)-lbuf_len, 0);
- else
- len = read(local_in, lbuf + lbuf_len, sizeof(lbuf)-lbuf_len);
- if ( len == 0 ) {
- /* stdin is EOF */
- debug("local input is EOF\n");
- if (!f_hold_session)
- shutdown(remote, 1); /* no-more writing */
- f_local = 0;
- close_reason = REASON_CLOSED_BY_LOCAL;
- } else if ( len == -1 ) {
- /* error on reading from stdin */
- if (f_hold_session) {
- debug ("failed to read from local\n");
- f_local = 0;
- close_reason = REASON_CLOSED_BY_LOCAL;
- } else
- fatal("recv() failed, errno = %d\n", errno);
- } else {
- /* repeat */
- lbuf_len += len;
- }
- }
-
- /* flush data in buffer to socket */
- if ( 0 < lbuf_len ) {
- len = send(remote, lbuf, lbuf_len, 0);
- if ( 1 < f_debug ) /* more verbose */
- report_bytes( ">>>", lbuf, lbuf_len);
- if ( len == -1 ) {
- fatal("send() failed, %d\n", socket_errno());
- } else if ( 0 < len ) {
- /* move data on to top of buffer */
- debug("send %d bytes\n", len);
- lbuf_len -= len;
- if ( 0 < lbuf_len )
- memcpy( lbuf, lbuf+len, lbuf_len );
- assert( 0 <= lbuf_len );
- }
- }
-
- /* flush data in buffer to local output */
- if ( 0 < rbuf_len ) {
- if (local_type == LOCAL_SOCKET)
- len = send( local_out, rbuf, rbuf_len, 0);
- else
- len = write( local_out, rbuf, rbuf_len);
- if ( len == -1 ) {
- fatal("output (local) failed, errno=%d\n", errno);
- }
- rbuf_len -= len;
- if ( len < rbuf_len )
- memcpy( rbuf, rbuf+len, rbuf_len );
- assert( 0 <= rbuf_len );
- }
- if (f_local == 0 && f_hold_session) {
- debug ("closing local port without disconnecting from remote\n");
- f_remote = 0;
- shutdown (local_out, 2);
- close (local_out);
- break;
- }
- }
-
- return close_reason;
-}
-
-int
-accept_connection (u_short port)
-{
- static int sock = -1;
- int connection;
- struct sockaddr_in name;
- struct sockaddr client;
- int socklen;
- fd_set ifds;
- int nfds;
- int sockopt;
-
- /* Create the socket. */
- debug("Creating source port to forward.\n");
- sock = socket (PF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- fatal("socket() failed, errno=%d\n", socket_errno());
- sockopt = 1;
- setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
- (void*)&sockopt, sizeof(sockopt));
-
- /* Give the socket a name. */
- name.sin_family = AF_INET;
- name.sin_port = htons (port);
- name.sin_addr.s_addr = htonl (INADDR_ANY);
- if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
- fatal ("bind() failed, errno=%d\n", socket_errno());
-
- if (listen( sock, 1) < 0)
- fatal ("listen() failed, errno=%d\n", socket_errno());
-
- /* wait for new connection with watching EOF of stdin. */
- debug ("waiting new connection at port %d (socket=%d)\n", port, sock);
- nfds = sock + 1;
- do {
- int n;
- struct timeval *ptmo = NULL;
-#ifdef _WIN32
- struct timeval tmo;
- tmo.tv_sec = 0;
- tmo.tv_usec = 100*1000; /* On Windows, 100ms timeout */
- ptmo = &tmo;
-#endif /* _WIN32 */
- FD_ZERO (&ifds);
- FD_SET ((SOCKET)sock, &ifds);
-#ifndef _WIN32
- FD_SET (0, &ifds); /* watch stdin */
-#endif
- n = select (nfds, &ifds, NULL, NULL, ptmo);
- if (n == -1) {
- fatal ("select() failed, %d\n", socket_errno());
- exit (1);
- }
-#ifdef _WIN32
- if (0 < stdindatalen()) {
- FD_SET (0, &ifds); /* fake */
- n++;
- }
-#endif
- if (0 < n) {
- if (FD_ISSET(0, &ifds) && (getchar() <= 0)) {
- /* EOF */
- debug ("Give-up waiting port because stdin is closed.");
- exit(0);
- }
- if (FD_ISSET(sock, &ifds))
- break; /* socket is stimulated */
- }
- } while (1);
- socklen = sizeof(client);
- connection = accept( sock, &client, &socklen);
- if ( connection < 0 )
- fatal ("accept() failed, errno=%d\n", socket_errno());
- return connection;
-}
-
-
-
-/** Main of program **/
-int
-main( int argc, char **argv )
-{
- int ret;
- int remote; /* socket */
- int local_in; /* Local input */
- int local_out; /* Local output */
- int reason;
-#ifdef _WIN32
- WSADATA wsadata;
- WSAStartup( 0x101, &wsadata);
-#endif /* _WIN32 */
-
- /* initialization */
- make_revstr();
- getarg( argc, argv );
- debug("Program is $Revision$\n");
-
- /* Open local_in and local_out if forwarding a port */
- if ( local_type == LOCAL_SOCKET ) {
- /* Relay between local port and destination */
- local_in = local_out = accept_connection( local_port );
- } else {
- /* Relay between stdin/stdout and desteination */
- local_in = 0;
- local_out = 1;
-#ifdef _WIN32
- _setmode(local_in, O_BINARY);
- _setmode(local_out, O_BINARY);
-#endif
- }
-
-retry:
-#ifndef _WIN32
- if (0 < connect_timeout)
- set_timeout (connect_timeout);
-#endif /* not _WIN32 */
-
- /* make connection */
- if ( relay_method == METHOD_DIRECT ) {
- remote = open_connection (dest_host, dest_port);
- if ( remote == SOCKET_ERROR )
- fatal( "Unable to connect to destination host, errno=%d\n",
- socket_errno());
- } else {
- remote = open_connection (relay_host, relay_port);
- if ( remote == SOCKET_ERROR )
- fatal( "Unable to connect to relay host, errno=%d\n",
- socket_errno());
- }
-
- /** resolve destination host (SOCKS) **/
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
- if (socks_ns.sin_addr.s_addr != 0)
- switch_ns (&socks_ns);
-#endif /* not _WIN32 && not __CYGWIN32__ */
- if (relay_method == METHOD_SOCKS &&
- socks_resolve == RESOLVE_LOCAL &&
- local_resolve (dest_host, &dest_addr) < 0) {
- fatal("Unknown host: %s", dest_host);
- }
-
- /** relay negociation **/
- switch ( relay_method ) {
- case METHOD_SOCKS:
- if ( ((socks_version == 5) && (begin_socks5_relay(remote) < 0)) ||
- ((socks_version == 4) && (begin_socks4_relay(remote) < 0)) )
- fatal( "failed to begin relaying via SOCKS.\n");
- break;
-
- case METHOD_HTTP:
- ret = begin_http_relay(remote);
- switch (ret) {
- case START_ERROR:
- close (remote);
- fatal("failed to begin relaying via HTTP.\n");
- case START_OK:
- break;
- case START_RETRY:
- /* retry with authentication */
- close (remote);
- goto retry;
- }
- break;
- case METHOD_TELNET:
- if (begin_telnet_relay(remote) < 0)
- fatal("failed to begin relaying via telnet.\n");
- break;
- }
- debug("connected\n");
-
-#ifndef _WIN32
- if (0 < connect_timeout)
- set_timeout (0);
-#endif /* not _WIN32 */
-
- /* main loop */
- debug ("start relaying.\n");
-do_repeater:
- reason = do_repeater(local_in, local_out, remote);
- debug ("relaying done.\n");
- if (local_type == LOCAL_SOCKET &&
- reason == REASON_CLOSED_BY_LOCAL &&
- f_hold_session) {
- /* re-wait at local port without closing remote session */
- debug ("re-waiting at local port %d\n", local_port);
- local_in = local_out = accept_connection( local_port );
- debug ("re-start relaying\n");
- goto do_repeater;
- }
- closesocket(remote);
- if ( local_type == LOCAL_SOCKET)
- closesocket(local_in);
-#ifdef _WIN32
- WSACleanup();
-#endif /* _WIN32 */
- debug ("that's all, bye.\n");
-
- return 0;
-}
-
-/* ------------------------------------------------------------
- Local Variables:
- compile-command: "cc connect.c -o connect"
- tab-width: 8
- fill-column: 74
- comment-column: 48
- End:
- ------------------------------------------------------------ */
-
-/*** end of connect.c ***/
+++ /dev/null
-<?xml version="1.0" encoding="us-ascii"?>\r
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\r
- "http://www.w3.org/TR/xhtml1/DTD/strict.dtd">\r
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\r
- <head>\r
- <title>SSH Proxy Command -- connect.c</title>\r
- <meta name="generator" content="emacs-wiki.el" />\r
- <meta http-equiv="Content-Type"\r
- content="us-ascii" />\r
- <link rev="made" href="mailto:gotoh@taiyo.co.jp" />\r
- <link rel="home" href="http://www.taiyo.co.jp/~gotoh/" />\r
- <link rel="index" href="http://www.taiyo.co.jp/~gotoh/SiteIndex.html" />\r
- <link rel="stylesheet" type="text/css" href="emacs-wiki.css" />\r
- </head>\r
- <body>\r
- <h1>SSH Proxy Command -- connect.c</h1>\r
- <!-- Page published by Emacs Wiki begins here -->\r
-<p>\r
-<strong>connect.c</strong> is the simple relaying command to make network\r
-connection via SOCKS and https proxy. It is mainly intended to\r
-be used as <strong>proxy command</strong> of OpenSSH. You can make SSH session\r
-beyond the firewall with this command,\r
-\r
-</p>\r
-\r
-<p>\r
-Features of <strong>connect.c</strong> are:\r
-\r
-</p>\r
-\r
-<ul>\r
-<li>Supports SOCKS (version 4/4a/5) and https CONNECT method.\r
-</li>\r
-<li>Supports NO-AUTH and USERPASS authentication of SOCKS\r
-</li>\r
-<li>Partially supports telnet proxy (experimental).\r
-</li>\r
-<li>You can input password from tty, ssh-askpass or\r
- environment variable.\r
-</li>\r
-<li>Run on UNIX or Windows platform.\r
-</li>\r
-<li>You can compile with various C compiler (cc, gcc, Visual C, Borland C. etc.)\r
-</li>\r
-<li>Simple and general program independent from OpenSSH.\r
-</li>\r
-<li>You can also relay local socket stream instead of standard I/O.\r
-</li>\r
-</ul>\r
-\r
-<p>\r
-Download source code from:\r
-<a href="http://www.taiyo.co.jp/~gotoh/ssh/connect.c">http://www.taiyo.co.jp/~gotoh/ssh/connect.c</a>\r
-<br/>\r
-For windows user, pre-compiled binary is also available:\r
-<a href="http://www.taiyo.co.jp/~gotoh/ssh/connect.exe">http://www.taiyo.co.jp/~gotoh/ssh/connect.exe</a> (compiled with MSVC)\r
-\r
-</p>\r
-\r
-<h2>Contents</h2>\r
-<dl class="contents">\r
-<dt class="contents">\r
-<a href="#sec1">News</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec2">What is 'proxy command'</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec3">How to Use</a>\r
-</dt>\r
-<dd>\r
-<dl class="contents">\r
-<dt class="contents">\r
-<a href="#sec4">Get Source</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec5">Compile and Install</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec6">Modify your ~/.ssh/config</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec7">Use SSH</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec8">Have trouble?</a>\r
-</dt>\r
-</dl>\r
-</dd>\r
-<dt class="contents">\r
-<a href="#sec9">More Detail</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec10">Specifying user name via environment variables</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec11">Specifying password via environment variables</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec12">Limitations</a>\r
-</dt>\r
-<dd>\r
-<dl class="contents">\r
-<dt class="contents">\r
-<a href="#sec13">SOCKS5 authentication</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec14">HTTP authentication</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec15">Switching proxy server</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec16">Telnet Proxy</a>\r
-</dt>\r
-</dl>\r
-</dd>\r
-<dt class="contents">\r
-<a href="#sec17">Tips</a>\r
-</dt>\r
-<dd>\r
-<dl class="contents">\r
-<dt class="contents">\r
-<a href="#sec18">Proxying socket connection</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec19">Use with ssh-askpass command</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec20">Use for Network Stream of Emacs</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec21">Remote resolver</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec22">Hopping Connection via SSH</a>\r
-</dt>\r
-</dl>\r
-</dd>\r
-<dt class="contents">\r
-<a href="#sec23">Break The More Restricted Wall</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec24">F.Y.I.</a>\r
-</dt>\r
-<dd>\r
-<dl class="contents">\r
-<dt class="contents">\r
-<a href="#sec25">Difference between SOCKS versions.</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec26">Configuration to use HTTPS</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec27">SOCKS5 Servers</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec28">Specifications</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec29">Related Links</a>\r
-</dt>\r
-<dt class="contents">\r
-<a href="#sec30">Similars</a>\r
-</dt>\r
-</dl>\r
-</dd>\r
-<dt class="contents">\r
-<a href="#sec31">hisotry</a>\r
-</dt>\r
-</dl>\r
-\r
-\r
-<h2><a name="sec1" id="sec1"></a>News</h2>\r
-<dl>\r
-<dt>2005-07-08</dt>\r
-<dd>\r
-Rev. 1.95. Buf fix for previous change. The bug causes the fail of\r
- basic authentication. And also fixed bug of parameter file handling.\r
- Thanks reporting, Johannes Schindelin <Johannes.Schindelin at gmx.de>.\r
-</dd>\r
-<dt>2005-07-07</dt>\r
-<dd>\r
-Rev. 1.94. Changed to use snprintf()/vsnprintf() for security issue\r
- that gcc complained them on OpenBSD 3.7/x86. The features are not\r
- changed.\r
-</dd>\r
-<dt>2005-03-04</dt>\r
-<dd>\r
-Updated compile option for Mac OS X.\r
-</dd>\r
-<dt>2005-02-21</dt>\r
-<dd>\r
-Rev.1.92. Removed assertions which has no mean and worse for windows\r
- suggested by OZAWA Takahiro.\r
-</dd>\r
-<dt>2005-01-12</dt>\r
-<dd>\r
-Rev.1.90. Fixed not to cause seg-fault on accessing to non HTTP\r
- port. This problem is reported by Jason Armstrong <ja at riverdrums.com>.\r
-</dd>\r
-<dt>2004-10-30</dt>\r
-<dd>\r
-Rev.1.89. Partial support for telnet proxy.\r
- Thanks to Gregory Shimansky <gshimansky at mail dot ru>. \r
- (Note: This is ad-hoc implementation, so it is not enough for\r
- various type of telnet proxies.\r
- And password interaction is not supported.)\r
-</dd>\r
-</dl>\r
-\r
-<h2><a name="sec2" id="sec2"></a>What is 'proxy command'</h2>\r
-\r
-<p>\r
-OpenSSH development team decides to stop supporting SOCKS and any\r
-other tunneling mechanism. It was aimed to separate complexity to\r
-support various mechanism of proxying from core code. And they\r
-recommends more flexible mechanism: <strong>ProxyCommand</strong> option\r
-instead.\r
-\r
-</p>\r
-\r
-<p>\r
-Proxy command mechanism is delegation of network stream\r
-communication. If <strong>ProxyCommand</strong> options is specified, SSH\r
-invoke specified external command and talk with standard I/O of thid\r
-command. Invoked command undertakes network communication with\r
-relaying to/from standard input/output including iniitial\r
-communication or negotiation for proxying. Thus, ssh can split out\r
-proxying code into external command.\r
-\r
-</p>\r
-\r
-<p>\r
-The <strong>connect.c</strong> program was made for this purpose.\r
-\r
-</p>\r
-\r
-<h2><a name="sec3" id="sec3"></a>How to Use</h2>\r
-\r
-<h3><a name="sec4" id="sec4"></a>Get Source</h3>\r
-\r
-<p>\r
-Download source code from <a href="http://www.taiyo.co.jp/~gotoh/ssh/connect.c">here</a>.\r
-<br/>\r
-If you are MS Windows user, you can get pre-compiled binary from\r
-<a href="http://www.taiyo.co.jp/~gotoh/ssh/connect.exe">here</a>.\r
-\r
-</p>\r
-\r
-<h3><a name="sec5" id="sec5"></a>Compile and Install</h3>\r
-\r
-<p>\r
-In most environment, you can compile <strong>connect.c</strong> simply.\r
-On UNIX environment, you can use cc or gcc.\r
-On Windows environment, you can use Microsoft Visual C, Borland C or Cygwin gcc.\r
-\r
-</p>\r
-\r
-<table border="2" cellpadding="5">\r
-<thead>\r
-<tr>\r
-<th>Compiler</th><th>command line to compile</th>\r
-</tr>\r
-</thead>\r
-<tbody>\r
-<tr>\r
-<td>UNIX cc</td><td>cc connect.c -o connect</td>\r
-</tr>\r
-<tr>\r
-<td>UNIX gcc</td><td>gcc connect.c -o connect</td>\r
-</tr>\r
-<tr>\r
-<td>Solaris</td><td>gcc connect.c -o connect -lnsl -lsocket -lresolv</td>\r
-</tr>\r
-<tr>\r
-<td>Microsoft Visual C/C++</td><td>cl connect.c wsock32.lib advapi32.lib</td>\r
-</tr>\r
-<tr>\r
-<td>Borland C</td><td>bcc32 connect.c wsock32.lib advapi32.lib</td>\r
-</tr>\r
-<tr>\r
-<td>Cygwin gcc</td><td>gcc connect.c -o connect</td>\r
-</tr>\r
-<tr>\r
-<td>Mac OS X</td><td>gcc connect.c -o connect -lresolv<br/>or<br/>gcc connect.c -o connect -DBIND_8_COMPAT=1</td>\r
-</tr>\r
-</tbody>\r
-</table>\r
-\r
-<p>\r
-To install <strong>connect</strong> command, simply copy compiled binary to directory\r
-in your PATH (ex. /usr/local/bin). Like this:\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-$ cp connect /usr/local/bin\r
-</pre>\r
-\r
-<h3><a name="sec6" id="sec6"></a>Modify your ~/.ssh/config</h3>\r
-\r
-<p>\r
-Modify your <code>~/.ssh/config</code> file to use <strong>connect</strong> command as\r
-<strong>proxy command</strong>. For the case of SOCKS server is running on\r
-firewall host <code>socks.local.net</code> with port 1080, you can add\r
-<strong>ProxyCommand</strong> option in <code>~/.ssh/config</code>, like this:\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-Host remote.outside.net\r
- ProxyCommand connect -S socks.local.net %h %p\r
-</pre>\r
-\r
-<p>\r
-<code>%h</code> and <code>%p</code> will be replaced on invoking proxy command with\r
-target hostname and port specified to SSH command.\r
-\r
-</p>\r
-\r
-<p>\r
-If you hate writing many entries of remote hosts, following example\r
-may help you.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-## Inside of the firewall, use connect command with direct connection.\r
-Host *.local.net\r
- ProxyCommand connect %h %p\r
-\r
-## Outside of the firewall, use connect command with SOCKS conenction.\r
-Host *\r
- ProxyCommand connect -S socks.local.net %h %p\r
-</pre>\r
-\r
-<p>\r
-If you want to use http proxy, use <strong>-H</strong> option instead of <strong>-S</strong>\r
-option in examle above, like this:\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-## Inside of the firewall, direct\r
-Host *.local.net\r
- ProxyCommand connect %h %p\r
-\r
-## Outside of the firewall, with HTTP proxy\r
-Host *\r
- ProxyCommand connect -H proxy.local.net:8080 %h %p\r
-</pre>\r
-\r
-<h3><a name="sec7" id="sec7"></a>Use SSH</h3>\r
-\r
-<p>\r
-After editing your <code>~/.ssh/config</code> file, you are ready to use ssh.\r
-You can execute ssh without any special options as if remote host is\r
-IP reachable host. Following is an example to execute <code>hostname</code>\r
-command on host <code>remote.outside.net</code>.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-$ ssh remote.outside.net hostname\r
-remote.outside.net\r
-$\r
-</pre>\r
-\r
-<h3><a name="sec8" id="sec8"></a>Have trouble?</h3>\r
-\r
-<p>\r
-If you have trouble, execute <strong>connect</strong> command from command line\r
-with <code>-d</code> option to see what is happened. Some debug message may\r
-appear and reports progress. This information may tell you what is\r
-wrong. In this example, error has occurred on authentication stage of\r
-SOCKS5 protocol.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-$ connect -d -S socks.local.net unknown.remote.outside.net 110\r
-DEBUG: relay_method = SOCKS (2)\r
-DEBUG: relay_host=socks.local.net\r
-DEBUG: relay_port=1080\r
-DEBUG: relay_user=gotoh\r
-DEBUG: socks_version=5\r
-DEBUG: socks_resolve=REMOTE (2)\r
-DEBUG: local_type=stdio\r
-DEBUG: dest_host=unknown.remote.outside.net\r
-DEBUG: dest_port=110\r
-DEBUG: Program is $Revision$\r
-DEBUG: connecting to xxx.xxx.xxx.xxx:1080\r
-DEBUG: begin_socks_relay()\r
-DEBUG: atomic_out() [4 bytes]\r
-DEBUG: >>> 05 02 00 02\r
-DEBUG: atomic_in() [2 bytes]\r
-DEBUG: <<< 05 02\r
-DEBUG: auth method: USERPASS\r
-DEBUG: atomic_out() [some bytes]\r
-DEBUG: >>> xx xx xx xx ...\r
-DEBUG: atomic_in() [2 bytes]\r
-DEBUG: <<< 01 01\r
-ERROR: Authentication faield.\r
-FATAL: failed to begin relaying via SOCKS.\r
-</pre>\r
-\r
-<h2><a name="sec9" id="sec9"></a>More Detail</h2>\r
-\r
-<p>\r
-Command line usage is here:\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-usage: connect [-dnhst45] [-R resolve] [-p local-port] [-w sec]\r
- [-H [user@]proxy-server[:port]]\r
- [-S [user@]socks-server[:port]]\r
- [-T socks-server:[port]]\r
- [-c telnet-proxy-command]\r
- host port\r
-</pre>\r
-\r
-<p>\r
-<strong><em>host</em></strong> and <strong><em>port</em></strong> is target hostname and port-number to connect.\r
-\r
-</p>\r
-\r
-<p>\r
-<strong>-H</strong> option specify hostname and port number of http proxy server to\r
-relay. If port is omitted, 80 is used. You can specify this value by\r
-environment variable <code>HTTP_PROXY</code> and give <strong>-h</strong> option to use it.\r
-\r
-</p>\r
-\r
-<p>\r
-<strong>-S</strong> option specify hostname and port number of SOCKS server to\r
-relay. Like <strong>-H</strong> option, port number can be omit and default is 1080. \r
-You can also specify this value pair by environment variable\r
-<code>SOCKS5_SERVER</code> and give <strong>-s</strong> option to use it.\r
-\r
-</p>\r
-\r
-<p>\r
-<strong>-T</strong> option specify hostname and port number of telnet proxy to\r
-relay. The port number can be omit and default is 23.\r
-You can also specify this value pair by environment variable\r
-<code>TELNET_PROXY</code> and give <strong>-t</strong> option to use it.\r
-\r
-</p>\r
-\r
-<p>\r
-<strong>-4</strong> and <strong>-5</strong> is for specifying SOCKS protocol version. It is\r
-valid only using with <strong>-s</strong> or <strong>-S</strong>. Default is <strong>-5</strong>\r
-(protocol version 5)\r
-\r
-</p>\r
-\r
-<p>\r
-<strong>-R</strong> is for specifying method to resolve hostname. 3 keywords\r
-(<code>local</code>, <code>remote</code>, <code>both</code>) or dot-notation IP address is\r
-allowed. Keyword <code>both</code> means; "Try local first, then\r
-remote". If dot-notation IP address is specified, use this host as\r
-nameserver (UNIX only). Default is <code>remote</code> for SOCKS5 or <code>local</code>\r
-for others. On SOCKS4 protocol, remote resolving method (<code>remote</code>\r
-and <code>both</code>) use protocol version 4a.\r
-\r
-</p>\r
-\r
-<p>\r
-The <strong>-p</strong> option specifys to wait a local TCP port and make relaying\r
-with it instead of standard input and output.\r
-\r
-</p>\r
-\r
-<p>\r
-The <strong>-w</strong> option specifys timeout seconds on making connection with\r
-target host.\r
-\r
-</p>\r
-\r
-<p>\r
-The <strong>-c</strong> option specifys request string against telnet\r
-proxy server. The special word '%h' and '%p' in this string are replaced\r
-as hostname and port number before sending. \r
-For telnet proxy by <a class="nonexistent" href="mailto:gotoh@taiyo.co.jp">DeleGate</a>, both "telnet %h %p" and "%h:%p"\r
-are acceptable.\r
-Default is "telnet %h %p".\r
-\r
-</p>\r
-\r
-<p>\r
-The <strong>-a</strong> option specifiys user intended authentication methods\r
-separated by comma. Currently <code>userpass</code> and <code>none</code> are\r
-supported. Default is <code>userpass</code>. You can also specifying this\r
-parameter by the environment variable <code>SOCKS5_AUTH</code>.\r
-\r
-</p>\r
-\r
-<p>\r
-The <strong>-d</strong> option is used for debug. If you fail to connect, use this\r
-and check request to and response from server.\r
-\r
-</p>\r
-\r
-<p>\r
-You can omit <strong><em>port</em></strong> argument when program name is special format\r
-containing port number itself. For example, \r
-\r
-</p>\r
-\r
-<pre class="example">\r
-$ ln -s connect connect-25\r
-$ ./connect-25 smtphost.outside.net\r
-220 smtphost.outside.net ESMTP Sendmail\r
-QUIT\r
-221 2.0.0 smtphost.remote.net closing connection\r
-$\r
-</pre>\r
-\r
-<p>\r
-This example means that the command name "<code>connect-25</code>" contains port number\r
-25 so you can omit 2nd argument (and used if specified explicitly).\r
-\r
-</p>\r
-\r
-<h2><a name="sec10" id="sec10"></a>Specifying user name via environment variables</h2>\r
-\r
-<p>\r
-There are 5 environemnt variables to specify\r
-user name without command line option. This mechanism is usefull\r
-for the user who using another user name different from system account.\r
-\r
-</p>\r
-\r
-<dl>\r
-<dt>SOCKS5_USER</dt>\r
-<dd>\r
-Used for SOCKS v5 access.\r
-</dd>\r
-<dt>SOCKS4_USER</dt>\r
-<dd>\r
-Used for SOCKS v4 access.\r
-</dd>\r
-<dt>SOCKS_USER</dt>\r
-<dd>\r
-Used for SOCKS v5 or v4 access and varaibles above are not defined.\r
-</dd>\r
-<dt>HTTP_PROXY_USER</dt>\r
-<dd>\r
-Used for HTTP proxy access.\r
-</dd>\r
-<dt>CONNECT_USER</dt>\r
-<dd>\r
-Used for all type of access if all above are not defined.\r
-</dd>\r
-</dl>\r
-\r
-<p>\r
-Following table describes how user name is determined.\r
-Left most number is order to check. If variable is not defined,\r
-check next variable, and so on.\r
-\r
-</p>\r
-\r
-<table border=1>\r
-<tr align=center><th></th><th>SOCKS v5</th><th>SOCKS v4</th><th>HTTP proxy</th></tr>\r
-<tr align=center><td>1</td><td>SOCKS5_USER</td><td>SOCKS4_USER</td><td rowspan=2>HTTP_PROXY_USER</td></tr>\r
-<tr align=center><td>2</td><td colspan=2>SOCKS_USER</td></tr>\r
-<tr align=center><td>3</td><td colspan=3>CONNECT_USER</td></tr>\r
-<tr align=center><td>4</td><td colspan=3><i>(query user name to system)</i></td></tr>\r
-</table>\r
-\r
-<h2><a name="sec11" id="sec11"></a>Specifying password via environment variables</h2>\r
-\r
-<p>\r
-There are 5 environemnt variables to specify\r
-password. If you use this feature, please note that it is\r
-not secure way.\r
-\r
-</p>\r
-\r
-<dl>\r
-<dt>SOCKS5_PASSWD</dt>\r
-<dd>\r
-Used for SOCKS v5 access. This variables is compatible\r
- with NEC SOCKS implementation.\r
-</dd>\r
-<dt>SOCKS5_PASSWORD</dt>\r
-<dd>\r
-Used for SOCKS v5 access if SOCKS5_PASSWD is not defined.\r
-</dd>\r
-<dt>SOCKS_PASSWORD</dt>\r
-<dd>\r
-Used for SOCKS v5 (or v4) access all above is not defined.\r
-</dd>\r
-<dt>HTTP_PROXY_PASSWORD</dt>\r
-<dd>\r
-Used for HTTP proxy access.\r
-</dd>\r
-<dt>CONNECT_PASSWORD</dt>\r
-<dd>\r
-Used for all type of access if all above are not defined.\r
-</dd>\r
-</dl>\r
-\r
-<p>\r
-Following table describes how password is determined.\r
-Left most number is order to check. If variable is not defined,\r
-check next variable, and so on. Finally ask to user interactively\r
-using external program or tty input.\r
-\r
-</p>\r
-\r
-<table border=1>\r
-<tr align=center><th></th><th>SOCKS v5</th><th>HTTP proxy</th></tr>\r
-<tr align=center><td>1</td><td>SOCKS5_PASSWD</td><td rowspan=2>HTTP_PROXY_PASSWORD</td></tr>\r
-<tr align=center><td>2</td><td>SOCKS_PASSWORD</td></tr>\r
-<tr align=center><td>3</td><td colspan=2>CONNECT_PASSWORD</td></tr>\r
-<tr align=center><td>4</td><td colspan=2><i>(ask to user interactively)</i></td></tr>\r
-</table>\r
-\r
-<h2><a name="sec12" id="sec12"></a>Limitations</h2>\r
-\r
-<h3><a name="sec13" id="sec13"></a>SOCKS5 authentication</h3>\r
-\r
-<p>\r
-Only NO-AUTH and USER/PASSWORD authentications are supported.\r
-GSSAPI authentication (RFC 1961) and other draft authentications (CHAP,\r
-EAP, MAF, etc.) is not supported.\r
-\r
-</p>\r
-\r
-<h3><a name="sec14" id="sec14"></a>HTTP authentication</h3>\r
-\r
-<p>\r
-BASIC authentication is supported but DIGEST authentication is not.\r
-\r
-</p>\r
-\r
-<h3><a name="sec15" id="sec15"></a>Switching proxy server</h3>\r
-\r
-<p>\r
-There is no mechanism to switch proxy server regarding to PC environment.\r
-This limitation might be bad news for mobile user.\r
-Since I do not want to make this program complex, I do not want to\r
-support although this feature is already requested. Please advice me\r
-if there is good idea of detecting environment to swich and simple way\r
-to specify conditioned directive of servers.\r
-\r
-</p>\r
-\r
-<p>\r
-One tricky workaround exists. It is replacing ~/.ssh/config file\r
-by script on ppp up/down.\r
-\r
-</p>\r
-\r
-<p>\r
-There's another example of wrapper script (contributed by Darren Tucker).\r
-This script costs executing ifconfig and grep to detect\r
-current environment, but it works. (NOTE: you should modify addresses\r
-if you use it.)\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-#!/bin/sh\r
-## ~/bin/myconnect --- Proxy server switching wrapper\r
-\r
-if ifconfig eth0 |grep "inet addr:192\.168\.1" >/dev/null; then\r
- opts="-S 192.168.1.1:1080" \r
-elif ifconfig eth0 |grep "inet addr:10\." >/dev/null; then\r
- opts="-H 10.1.1.1:80"\r
-else\r
- opts="-s"\r
-fi\r
-exec /usr/local/bin/connect $opts $@\r
-</pre>\r
-\r
-<h3><a name="sec16" id="sec16"></a>Telnet Proxy</h3>\r
-\r
-<p>\r
-At first, note that the telnet proxy support is an partial feature.\r
-In this implementation, <strong>connect</strong> single requestinting and proxy\r
-returns some success/error detective in talked back lines including\r
-greeting, prompt and connected messages.\r
-\r
-</p>\r
-\r
-<p>\r
-The <strong>connect</strong> simply send request after connection to proxy is\r
-established before any response reading, then repeat reading response\r
-strings from proxy to decide remote connection request is succeeded or\r
-not by checking pre-defined phrase in each lines. There are\r
-pre-defined phrases which are good-phrase and bad-phrases. First\r
-good-phrase is checked and change state as relaying if exist.\r
-<strong>connect</strong> treat this line as final response from proxy before\r
-starting acutal communication with remote host. Or if good-phrase is\r
-not matched, bad-phrases will be checked. If one of bad-phrase\r
-matched, it cause connection error immediately.\r
-\r
-</p>\r
-\r
-<p>\r
-The pre-defined phrases are currently fixed string so you cannot\r
-change without modifying and compiling. The good-phrase is:\r
-"connected to". The bad-phrases are: " failed", " refused", "\r
-rejected", " closed".\r
-\r
-</p>\r
-\r
-<h2><a name="sec17" id="sec17"></a>Tips</h2>\r
-\r
-<h3><a name="sec18" id="sec18"></a>Proxying socket connection</h3>\r
-\r
-<p>\r
-In usual, <strong>connect.c</strong> relays network connection to/from standard\r
-input/output. By specifying <strong>-p</strong> option, however, <strong>connect.c</strong>\r
-relays local network stream instead of standard input/output.\r
-With this option, <strong>connect</strong> command waits connection\r
-from other program, then start relaying between both network stream.\r
-\r
-</p>\r
-\r
-<p>\r
-This feature may be useful for the program which is hard to SOCKSify.\r
-\r
-</p>\r
-\r
-<h3><a name="sec19" id="sec19"></a>Use with ssh-askpass command</h3>\r
-\r
-<p>\r
-<strong>connect.c</strong> ask you password when authentication is required. If\r
-you are using on tty/pty terminal, connect can input from terminal\r
-with prompt. But you can also use <code>ssh-askpass</code> program to input\r
-password. If you are graphical environment like X Window or MS\r
-Windows, and program does not have tty/pty, and environment variable\r
-SSH_ASKPASS is specified, then <strong>connect.c</strong> invoke command\r
-specified by environment variable <code>SSH_ASKPASS</code> to input password.\r
-<code>ssh-askpass</code> program might be installed if you are using OpenSSH on\r
-UNIX environment. On Windows environment, pre-compiled binary is\r
-available from\r
-<a href="http://www.taiyo.co.jp/~gotoh/ssh/ssh-askpass.exe">here</a>.\r
-\r
-</p>\r
-\r
-<p>\r
-This feature is limited on window system environment.\r
-\r
-</p>\r
-\r
-<p>\r
-And also useful on Emacs on MS Windows (NT Emacs or Meadow). It is\r
-hard to send passphrase to <strong>connect</strong> command (and also ssh)\r
-because external command is invoked on hidden terminal and do I/O with\r
-this terminal. Using ssh-askpass avoids this problem.\r
-\r
-</p>\r
-\r
-<h3><a name="sec20" id="sec20"></a>Use for Network Stream of Emacs</h3>\r
-\r
-<p>\r
-Although <strong>connect.c</strong> is made for OpenSSH, it is generic and\r
-independent from OpenSSH. So we can use this for other purpose. For\r
-example, you can use this command in Emacs to open network connection\r
-with remote host over the firewall via SOCKS or HTTP proxy without\r
-SOCKSifying Emacs itself.\r
-\r
-</p>\r
-\r
-<p>\r
-There is sample code: \r
-<a href="http://www.taiyo.co.jp/~gotoh/lisp/relay.el">http://www.taiyo.co.jp/~gotoh/lisp/relay.el</a>\r
-\r
-</p>\r
-\r
-<p>\r
-With this code, you can use <code>relay-open-network-stream</code> function\r
-instead of <code>open-network-stream</code> to make network connection. See top\r
-comments of source for more detail.\r
-\r
-</p>\r
-\r
-<h3><a name="sec21" id="sec21"></a>Remote resolver</h3>\r
-\r
-<p>\r
-If you are SOCKS4 user on UNIX environment, you might want specify\r
-nameserver to resolve remote hostname. You can do it specifying\r
-<strong>-R</strong> option followed by IP address of resolver.\r
-\r
-</p>\r
-\r
-<h3><a name="sec22" id="sec22"></a>Hopping Connection via SSH</h3>\r
-\r
-<p>\r
-Conbination of ssh and <strong>connect</strong> command have more interesting usage.\r
-Following command makes indirect connection to host2:port from your\r
-current host via host1.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-ssh host1 connect host2 port\r
-</pre>\r
-\r
-<p>\r
-This method is useful for the situations like:\r
-\r
-</p>\r
-\r
-<ul>\r
-<li>You are outside of organizasion now, but you want to access an\r
- internal host barriered by firewall.\r
-</li>\r
-<li>You want to use some service which is allowed only from some\r
- limited hosts.\r
-</li>\r
-</ul>\r
-\r
-<p>\r
-For example, I want to use local NetNews service in my office\r
-from home. I cannot make NNTP session directly because NNTP host is\r
-barriered by firewall. Fortunately, I have ssh account on internal\r
-host and allowed using SOCKS5 on firewall from outside. So I use\r
-following command to connect to NNTP service.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-$ ssh host1 connect news 119\r
-200 news.my-office.com InterNetNews NNRP server INN 2.3.2 ready (posting ok).\r
-quit\r
-205 .\r
-$\r
-</pre>\r
-\r
-<p>\r
-By combinating hopping connection and relay.el, I can read NetNews\r
-using <a href="http://www.gohome.org/wl/">Wanderlust</a> on Emacs at home.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
- |\r
- External (internet) | Internal (office)\r
- |\r
-+------+ +----------+ +-------+ +-----------+\r
-| HOME | | firewall | | host1 | | NNTP host |\r
-+------+ +----------+ +-------+ +-----------+\r
- emacs <-------------- ssh ---------------> sshd <-- connect --> nntpd\r
- <-- connect --> socksd <-- SOCKS -->\r
-</pre>\r
-\r
-<p>\r
-As an advanced example, you can use SSH hopping as fetchmail's plug-in\r
-program to access via secure tunnel. This method requires that\r
-<strong>connect</strong> program is insatalled on remote host. There's example\r
-of .fetchmailrc bellow. When fetchmail access to mail-server, you will\r
-login to remote host using SSH then execute <strong>connect</strong> program on\r
-remote host to relay conversation with pop server. Thus fetchmail can\r
-retrieve mails in secure.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-poll mail-server\r
- protocol pop3\r
- plugin "ssh %h connect localhost %p"\r
- username "username"\r
- password "password"\r
-</exmaple>\r
-\r
-* <a name="sec23" id="sec23"></a>Break The More Restricted Wall\r
-\r
-If firewall does not provide SOCKS nor HTTPS other than port 443, you\r
-cannot break the wall in usual way. But if you have you own host\r
-which is accessible from internet, you can make ssh connection to your\r
-own host by configuring sshd as waiting at port 443 instead of\r
-standard 22. By this, you can login to your own host via port 443.\r
-Once you have logged-in to extenal home machine, you can execute\r
-**connect** as second hop to make connection from your own host to\r
-final target host, like this:\r
-\r
-<example>\r
-$ cat ~/.ssh/config\r
-Host home\r
- ProxyCommand connect -H firewall:8080 %h 443\r
-\r
-Host server\r
- ProxyCommand ssh home connect %h %p\r
-...\r
-internal$ ssh home\r
-You are logged in to home!\r
-home# exit\r
-internal$ ssh server\r
-You are logged in to server!\r
-server# exit\r
-internal$\r
-</pre>\r
-\r
-<p>\r
-This way is similar to "Hopping connection via SSH" except configuring\r
-outer sshd as waiting at port 443 (https). This means that you have a\r
-capability to break the strongly restricted wall if you have own host\r
-out side of the wall.\r
-\r
-</p>\r
-\r
-<pre class="example">\r
- |\r
- Internal (office) | External (internet)\r
- |\r
-+--------+ +----------+ +------+ +--------+\r
-| office | | firewall | | home | | server |\r
-+--------+ +----------+ +------+ +--------+\r
- <------------------ ssh --------------------->sshd:443\r
- <-- connect --> http-proxy <-- https:443 --> any\r
- connect <-- tcp --> port\r
-</pre>\r
-\r
-<p>\r
-NOTE: If you wanna use this, you should give up hosting https service\r
-at port 443 on you external host 'home'.\r
-\r
-</p>\r
-\r
-<h2><a name="sec24" id="sec24"></a>F.Y.I.</h2>\r
-\r
-<h3><a name="sec25" id="sec25"></a>Difference between SOCKS versions.</h3>\r
-\r
-<p>\r
-SOCKS version 4 is first popular implementation which is documented\r
-<a href="http://www.socks.nec.com/protocol/socks4.protocol">here</a>. Since\r
-this protocol provide IP address based requesting, client program\r
-should resolve name of outer host by itself. Version 4a (documented\r
-<a href="http://www.socks.nec.com/protocol/socks4a.protocol">here</a>) is\r
-enhanced to allow request by hostname instead of IP address.\r
-\r
-</p>\r
-\r
-<p>\r
-SOCKS version 5 is re-designed protocol stands on experience of\r
-version 4 and 4a. There is no compativility with previous\r
-versions. Instead, there's some improvement: IPv6 support, request by\r
-hostname, UDP proxying, etc.\r
-\r
-</p>\r
-\r
-<h3><a name="sec26" id="sec26"></a>Configuration to use HTTPS</h3>\r
-\r
-<p>\r
-Many http proxy servers implementation supports https <code>CONNECT</code> method\r
-(SLL). You might add configuration to allow using https. For the\r
-example of <a href="http://www.delegate.org/delegate/">DeleGate</a> (\r
-DeleGate is a multi-purpose application level gateway, or a proxy\r
-server) , you should add <code>https</code> to <code>REMITTABLE</code> parameter to\r
-allow HTTP-Proxy like this:\r
-\r
-</p>\r
-\r
-<pre class="example">\r
-delegated -Pxxxx ...... REMITTABLE='+,https' ...\r
-</pre>\r
-\r
-<p>\r
-For the case of Squid, you should allow target ports via https by ACL,\r
-and so on.\r
-\r
-</p>\r
-\r
-<h3><a name="sec27" id="sec27"></a>SOCKS5 Servers</h3>\r
-\r
-<dl>\r
-<dt><a href="http://www.socks.nec.com/refsoftware.html">NEC SOCKS Reference Implementation</a></dt>\r
-<dd>\r
-Reference implementation of SOKCS server and library.\r
-</dd>\r
-<dt><a href="http://www.inet.no/dante/index.html">Dante</a></dt>\r
-<dd>\r
-Dante is free implementation of SOKCS server and library.\r
- Many enhancements and modulalized.\r
-</dd>\r
-<dt><a href="http://www.delegate.org/delegate/">DeleGate</a></dt>\r
-<dd>\r
-DeleGate is multi function proxy service provider.\r
- DeleGate 5.x.x or earlier can be SOCKS4 server,\r
- and 6.x.x can be SOCKS5 and SOCKS4 server.\r
- and 7.7.0 or later can be SOCKS5 and SOCKS4a server.\r
-</dd>\r
-</dl>\r
-\r
-<h3><a name="sec28" id="sec28"></a>Specifications</h3>\r
-\r
-<dl>\r
-<dt><a href="http://www.socks.nec.com/protocol/socks4.protocol">socks4.protocol.txt</a></dt>\r
-<dd>\r
-SOCKS: A protocol for TCP proxy across firewalls\r
-</dd>\r
-<dt><a href="http://www.socks.nec.com/protocol/socks4a.protocol">socks4a.protocol.txt</a></dt>\r
-<dd>\r
-SOCKS 4A: A Simple Extension to SOCKS 4 Protocol\r
-</dd>\r
-<dt><a href="http://www.socks.nec.com/rfc/rfc1928.txt">RFC 1928</a></dt>\r
-<dd>\r
-SOCKS Protocol Version 5\r
-</dd>\r
-<dt><a href="http://www.socks.nec.com/rfc/rfc1929.txt">RFC 1929</a></dt>\r
-<dd>\r
-Username/Password Authentication for SOCKS V5\r
-</dd>\r
-<dt><a href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</a></dt>\r
-<dd>\r
-Hypertext Transfer Protocol -- HTTP/1.1\r
-</dd>\r
-<dt><a href="http://www.ietf.org/rfc/rfc2617.txt">RFC 2617</a></dt>\r
-<dd>\r
-HTTP Authentication: Basic and Digest Access Authentication\r
-</dd>\r
-</dl>\r
-\r
-<h3><a name="sec29" id="sec29"></a>Related Links</h3>\r
-\r
-<ul>\r
-<li><a href="http://www.openssh.org">OpenSSH Home</a>\r
-</li>\r
-<li><a href="http://www.ssh.com/">Proprietary SSH</a>\r
-</li>\r
-<li><a href="http://www.taiyo.co.jp/~gotoh/ssh/openssh-socks.html">Using OpenSSH through a SOCKS compatible PROXY on your LAN</a> (J. Grant)\r
-</li>\r
-</ul>\r
-\r
-<h3><a name="sec30" id="sec30"></a>Similars</h3>\r
-\r
-<ul>\r
-<li><a href="http://proxytunnel.sourceforge.net/">Proxy Tunnel</a> -- Proxying command using https CONNECT.\r
-</li>\r
-<li><a href="http://www.snurgle.org/~griffon/ssh-https-tunnel">stunnel</a> -- Proxy through an https tunnel (Perl script)\r
-</li>\r
-</ul>\r
-\r
-<h2><a name="sec31" id="sec31"></a>hisotry</h2>\r
-\r
-<dl>\r
-<dt>2004-07-21</dt>\r
-<dd>\r
-Rev.1.84. Fixed some typo.\r
-</dd>\r
-<dt>2004-05-18</dt>\r
-<dd>\r
-Rev.1.83. Fixed problem not work on Solaris.\r
-</dd>\r
-<dt>2004-04-27</dt>\r
-<dd>\r
-Rev.1.82. Bug fix of memory clear on http proxying.\r
-</dd>\r
-<dt>2004-04-22</dt>\r
-<dd>\r
-Rev. 1.81. Fixed memory violation and memory leak bug. New environment\r
- variable SOCKS5_PASSWD for sharing value with NEC SOCKS implementation.\r
- And document (this page) is updated.\r
-</dd>\r
-<dt>2004-03-30</dt>\r
-<dd>\r
-Rev. 1.76. Fixed to accept multiple 'Proxy-Authorization' response.\r
-</dd>\r
-<dt>2003-01-07</dt>\r
-<dd>\r
-Rev. 1.68. Fixed a trouble around timeout support.\r
-</dd>\r
-<dt>2002-11-21</dt>\r
-<dd>\r
-Rev. 1.64 supports reading parameters from file /etc/connectrc or\r
- ~/.connectrc instead of specifying via environment variables. For\r
- examle, you can use this feature to switch setting by replacing file\r
- when network environment is changed. And added SOCKS_DIRECT,\r
- SOCKS5_DIRECT, SOCKS4_DIRECT, HTTP_DIRECT, SOCKS5_AUTH, environment\r
- parameters. (Thanks Masatoshi TSUCHIYA)\r
-</dd>\r
-<dt>2002-11-20</dt>\r
-<dd>\r
-Rev. 1.63 supports some old proxies which make response 401 with\r
- WWW-Authenticate: header. And fixed to use username specified in\r
- proxy host by -H option correctly. (contributed from Des Herriott, thanks)\r
-</dd>\r
-<dt>2002-10-14</dt>\r
-<dd>\r
-Rev. 1.61 with New option -w for specifying connection timeout.\r
- Currently, it works on UNIX only. (contributed from Darren Tucker, thanks)\r
-</dd>\r
-<dt>2002-09-29</dt>\r
-<dd>\r
-Add sample script for switching proxy server\r
- advised from Darren Tucker, thanks.\r
-</dd>\r
-<dt>2002-08-27</dt>\r
-<dd>\r
-connect.c is updataed to rev. 1.60.\r
-</dd>\r
-<dt>2002-04-08</dt>\r
-<dd>\r
-Updated <a href="http://www.taiyo.co.jp/~gotoh/ssh/openssh-socks.html">"Using OpenSSH through a SOCKS compatible PROXY on your LAN"</a> written by J. Grant. (version 0.8)\r
-</dd>\r
-<dt>2002-02-20</dt>\r
-<dd>\r
-Add link of new document "Using OpenSSH through a SOCKS compatible PROXY on your LAN"\r
- written by J. Grant.\r
-</dd>\r
-<dt>2002-01-31</dt>\r
-<dd>\r
-Rev. 1.53 -- On Win32 and with MSVC, handle password\r
- input from console correctly.\r
-</dd>\r
-<dt>2002-01-30</dt>\r
-<dd>\r
-Rev. 1.50 -- [Security Fix] Do not print secure info in debug mode.\r
-</dd>\r
-<dt>2002-01-09</dt>\r
-<dd>\r
-Web page was made.\r
- connect.c is rev. 1.48.\r
-</dd>\r
-</dl>\r
-<br>\r
-\r
- <!-- Page published by Emacs Wiki ends here -->\r
- <div class="navfoot">\r
- <hr/>\r
- <table width="100%" border="0" summary="Footer navigation">\r
- <tbody><tr>\r
- <td width="50%" align="left">\r
- <span class="footdate">Last Updated: 2005-07-18</span><br/>\r
- </td>\r
- <td width="50%" align="right">\r
- This page is authored by <a href="mailto:gotoh@taiyo.co.jp">Shun-ichi GOTO</a>\r
- using <a href="http://repose.cx/emacs/wiki">emacs-wiki.el</a><br/>\r
- </td>\r
- </tr></tbody>\r
- </table>\r
- </div>\r
- </body>\r
-</html>\r
+++ /dev/null
-diff -r -u -p1 openssh-4.3p1/buffer.c none-openssh-4.3p1/buffer.c
---- openssh-4.3p1/buffer.c 2005-03-14 07:22:26.000000000 -0500
-+++ none-openssh-4.3p1/buffer.c 2006-02-01 11:08:29.000000000 -0500
-@@ -109,3 +109,3 @@ restart:
- newlen = buffer->alloc + len + 32768;
-- if (newlen > BUFFER_MAX_LEN)
-+ if (newlen > BUFFER_MAX_HPN_LEN)
- fatal("buffer_append_space: alloc %u not supported",
-diff -r -u -p1 openssh-4.3p1/buffer.h none-openssh-4.3p1/buffer.h
---- openssh-4.3p1/buffer.h 2005-03-14 07:22:26.000000000 -0500
-+++ none-openssh-4.3p1/buffer.h 2006-02-01 11:08:29.000000000 -0500
-@@ -27,2 +27,3 @@ typedef struct {
- #define BUFFER_MAX_LEN 0xa00000
-+#define BUFFER_MAX_HPN_LEN (2<<29)-1
-
-diff -r -u -p1 openssh-4.3p1/channels.c none-openssh-4.3p1/channels.c
---- openssh-4.3p1/channels.c 2006-01-31 05:47:15.000000000 -0500
-+++ none-openssh-4.3p1/channels.c 2006-02-01 11:08:29.000000000 -0500
-@@ -290,2 +290,3 @@ channel_new(char *ctype, int type, int r
- c->local_maxpacket = maxpack;
-+ c->dynamic_window = 0;
- c->remote_id = -1;
-@@ -750,5 +751,5 @@ channel_pre_open(Channel *c, fd_set * re
- u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
--
-+
- /* check buffer limits */
-- limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
-+ limit = MIN(limit, (BUFFER_MAX_HPN_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
-
-@@ -1617,5 +1618,20 @@ channel_check_window(Channel *c)
- c->local_consumed > 0) {
-+ u_int32_t tcpwinsz = 0;
-+ socklen_t optsz = sizeof(tcpwinsz);
-+ int ret = -1;
-+ u_int32_t addition = 0;
-+ if (c->dynamic_window) {
-+ ret = getsockopt(packet_get_connection_in(),
-+ SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
-+ if ((ret == 0) && tcpwinsz > BUFFER_MAX_HPN_LEN)
-+ tcpwinsz = BUFFER_MAX_HPN_LEN;
-+ }
-+ if (c->dynamic_window && (ret == 0) &&
-+ (tcpwinsz > c->local_window_max)) {
-+ addition = tcpwinsz - c->local_window_max;
-+ c->local_window_max += addition;
-+ }
- packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
- packet_put_int(c->remote_id);
-- packet_put_int(c->local_consumed);
-+ packet_put_int(c->local_consumed + addition);
- packet_send();
-@@ -1624,3 +1640,3 @@ channel_check_window(Channel *c)
- c->local_consumed);
-- c->local_window += c->local_consumed;
-+ c->local_window += c->local_consumed + addition;
- c->local_consumed = 0;
-diff -r -u -p1 openssh-4.3p1/channels.h none-openssh-4.3p1/channels.h
---- openssh-4.3p1/channels.h 2005-12-31 00:22:32.000000000 -0500
-+++ none-openssh-4.3p1/channels.h 2006-02-01 11:08:29.000000000 -0500
-@@ -102,2 +102,3 @@ struct Channel {
- u_int local_maxpacket;
-+ int dynamic_window;
- int extended_usage;
-@@ -126,7 +127,7 @@ struct Channel {
- #define CHAN_SES_PACKET_DEFAULT (32*1024)
--#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT)
-+#define CHAN_SES_WINDOW_DEFAULT (0xa00000/2)
- #define CHAN_TCP_PACKET_DEFAULT (32*1024)
--#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
-+#define CHAN_TCP_WINDOW_DEFAULT (0xa00000/2)
- #define CHAN_X11_PACKET_DEFAULT (16*1024)
--#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
-+#define CHAN_X11_WINDOW_DEFAULT (0xa00000/2)
-
-diff -r -u -p1 openssh-4.3p1/cipher.c none-openssh-4.3p1/cipher.c
---- openssh-4.3p1/cipher.c 2005-12-19 01:40:40.000000000 -0500
-+++ none-openssh-4.3p1/cipher.c 2006-02-01 11:08:29.000000000 -0500
-@@ -153,3 +153,4 @@ ciphers_valid(const char *names)
- c = cipher_by_name(p);
-- if (c == NULL || c->number != SSH_CIPHER_SSH2) {
-+ if (c == NULL || (c->number != SSH_CIPHER_SSH2 &&
-+c->number != SSH_CIPHER_NONE)) {
- debug("bad cipher %s [%s]", p, names);
-@@ -327,2 +328,3 @@ cipher_get_keyiv(CipherContext *cc, u_ch
- switch (c->number) {
-+ case SSH_CIPHER_NONE:
- case SSH_CIPHER_SSH2:
-@@ -361,2 +363,3 @@ cipher_set_keyiv(CipherContext *cc, u_ch
- switch (c->number) {
-+ case SSH_CIPHER_NONE:
- case SSH_CIPHER_SSH2:
-diff -r -u -p1 openssh-4.3p1/compat.c none-openssh-4.3p1/compat.c
---- openssh-4.3p1/compat.c 2005-03-01 05:24:33.000000000 -0500
-+++ none-openssh-4.3p1/compat.c 2006-02-01 11:08:29.000000000 -0500
-@@ -164,2 +164,10 @@ compat_datafellows(const char *version)
- datafellows = check[i].bugs;
-+ /* Check to see if the remote side is OpenSSH and not HPN */
-+ if(strstr(version,"OpenSSH") != NULL)
-+ {
-+ if (strstr(version,"hpn") == NULL)
-+ {
-+ datafellows |= SSH_BUG_LARGEWINDOW;
-+ }
-+ }
- return;
-diff -r -u -p1 openssh-4.3p1/compat.h none-openssh-4.3p1/compat.h
---- openssh-4.3p1/compat.h 2005-03-01 05:24:33.000000000 -0500
-+++ none-openssh-4.3p1/compat.h 2006-02-01 11:08:29.000000000 -0500
-@@ -58,2 +58,3 @@
- #define SSH_OLD_FORWARD_ADDR 0x01000000
-+#define SSH_BUG_LARGEWINDOW 0x02000000
-
-diff -r -u -p1 openssh-4.3p1/kex.c none-openssh-4.3p1/kex.c
---- openssh-4.3p1/kex.c 2005-11-04 23:19:36.000000000 -0500
-+++ none-openssh-4.3p1/kex.c 2006-02-01 11:08:29.000000000 -0500
-@@ -51,3 +51,3 @@ static void kex_choose_conf(Kex *);
- /* put algorithm proposal into buffer */
--static void
-+void
- kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
-diff -r -u -p1 openssh-4.3p1/kex.h none-openssh-4.3p1/kex.h
---- openssh-4.3p1/kex.h 2005-11-04 23:19:36.000000000 -0500
-+++ none-openssh-4.3p1/kex.h 2006-02-01 11:08:29.000000000 -0500
-@@ -125,2 +125,4 @@ struct Kex {
-
-+void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
-+
- Kex *kex_setup(char *[PROPOSAL_MAX]);
-diff -r -u -p1 openssh-4.3p1/myproposal.h none-openssh-4.3p1/myproposal.h
---- openssh-4.3p1/myproposal.h 2005-07-26 07:54:56.000000000 -0400
-+++ none-openssh-4.3p1/myproposal.h 2006-02-01 11:08:29.000000000 -0500
-@@ -33,3 +33,3 @@
- "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
-- "aes128-ctr,aes192-ctr,aes256-ctr"
-+ "aes128-ctr,aes192-ctr,aes256-ctr,none"
- #define KEX_DEFAULT_MAC \
-diff -r -u -p1 openssh-4.3p1/packet.c none-openssh-4.3p1/packet.c
---- openssh-4.3p1/packet.c 2005-11-04 23:15:00.000000000 -0500
-+++ none-openssh-4.3p1/packet.c 2006-02-01 11:08:29.000000000 -0500
-@@ -1548,2 +1548,9 @@ packet_send_ignore(int nbytes)
- }
-+int rekey_requested = 0;
-+
-+void
-+packet_request_rekeying(void)
-+{
-+ rekey_requested = 1;
-+}
-
-@@ -1555,2 +1562,7 @@ packet_need_rekeying(void)
- return 0;
-+ if (rekey_requested == 1)
-+ {
-+ rekey_requested = 0;
-+ return 1;
-+ }
- return
-diff -r -u -p1 openssh-4.3p1/packet.h none-openssh-4.3p1/packet.h
---- openssh-4.3p1/packet.h 2005-07-26 07:54:56.000000000 -0400
-+++ none-openssh-4.3p1/packet.h 2006-02-01 11:08:29.000000000 -0500
-@@ -20,2 +20,5 @@
-
-+void
-+packet_request_rekeying(void);
-+
- void packet_set_connection(int, int);
-diff -r -u -p1 openssh-4.3p1/readconf.c none-openssh-4.3p1/readconf.c
---- openssh-4.3p1/readconf.c 2005-12-13 03:33:20.000000000 -0500
-+++ none-openssh-4.3p1/readconf.c 2006-02-01 11:08:29.000000000 -0500
-@@ -1018,2 +1018,3 @@ initialize_options(Options * options)
- options->server_alive_count_max = -1;
-+ options->none_switch = -1;
- options->num_send_env = 0;
-@@ -1147,2 +1148,4 @@ fill_default_options(Options * options)
- options->server_alive_count_max = 3;
-+ if (options->none_switch == -1)
-+ options->none_switch = 0;
- if (options->control_master == -1)
-diff -r -u -p1 openssh-4.3p1/readconf.h none-openssh-4.3p1/readconf.h
---- openssh-4.3p1/readconf.h 2005-12-13 03:29:02.000000000 -0500
-+++ none-openssh-4.3p1/readconf.h 2006-02-01 11:08:29.000000000 -0500
-@@ -59,2 +59,3 @@ typedef struct {
- int tcp_keep_alive; /* Set SO_KEEPALIVE. */
-+ int tcp_rcv_buf; /* user switch to set tcp recv buffer */
- LogLevel log_level; /* Level for logging. */
-@@ -104,2 +105,3 @@ typedef struct {
- int rekey_limit;
-+ int none_switch;
- int no_host_authentication_for_localhost;
-diff -r -u -p1 openssh-4.3p1/scp.c none-openssh-4.3p1/scp.c
---- openssh-4.3p1/scp.c 2006-01-31 06:11:38.000000000 -0500
-+++ none-openssh-4.3p1/scp.c 2006-02-01 12:20:31.000000000 -0500
-@@ -280,3 +280,3 @@ main(int argc, char **argv)
- fflag = tflag = 0;
-- while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
-+ while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246zS:o:F:R:")) != -1)
- switch (ch) {
-@@ -288,2 +288,3 @@ main(int argc, char **argv)
- case 'C':
-+ case 'z':
- addargs(&args, "-%c", ch);
-@@ -341,2 +342,5 @@ main(int argc, char **argv)
- break;
-+ case 'R':
-+ addargs(&args, "-r%s", optarg);
-+ break;
- default:
-@@ -555,3 +559,3 @@ source(int argc, char **argv)
- int fd = -1, haderr, indx;
-- char *last, *name, buf[2048];
-+ char *last, *name, buf[16384];
- int len;
-@@ -782,3 +786,3 @@ sink(int argc, char **argv)
- int setimes, targisdir, wrerrno = 0;
-- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
-+ char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
- struct timeval tv[2];
-@@ -943,3 +947,3 @@ bad: run_err("%s: %s", np, strerror(er
- (void) atomicio(vwrite, remout, "", 1);
-- if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) {
-+ if ((bp = allocbuf(&buffer, ofd, sizeof(buf))) == NULL) {
- (void) close(ofd);
-@@ -953,4 +957,4 @@ bad: run_err("%s: %s", np, strerror(er
- start_progress_meter(curfile, size, &statbytes);
-- for (count = i = 0; i < size; i += 4096) {
-- amt = 4096;
-+ for (count = i = 0; i < size; i += sizeof(buf)) {
-+ amt = sizeof(buf);
- if (i + amt > size)
-@@ -971,3 +975,3 @@ bad: run_err("%s: %s", np, strerror(er
- if (limit_rate)
-- bwlimit(4096);
-+ bwlimit(sizeof(buf));
-
-@@ -1087,3 +1091,3 @@ usage(void)
- "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
-- " [-l limit] [-o ssh_option] [-P port] [-S program]\n"
-+ " [-l limit] [-o ssh_option] [-P port] [-R Receive buffer size (Kb)] [-S program]\n"
- " [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
-Only in none-openssh-4.3p1/: scp.c.rej
-diff -r -u -p1 openssh-4.3p1/serverloop.c none-openssh-4.3p1/serverloop.c
---- openssh-4.3p1/serverloop.c 2005-12-31 00:33:37.000000000 -0500
-+++ none-openssh-4.3p1/serverloop.c 2006-02-01 11:08:29.000000000 -0500
-@@ -977,2 +977,4 @@ server_request_session(void)
- 0, "server-session", 1);
-+ if (!(datafellows & SSH_BUG_LARGEWINDOW))
-+ c->dynamic_window = 1;
- if (session_open(the_authctxt, c->self) != 1) {
-diff -r -u -p1 openssh-4.3p1/sftp.c none-openssh-4.3p1/sftp.c
---- openssh-4.3p1/sftp.c 2006-01-31 05:49:28.000000000 -0500
-+++ none-openssh-4.3p1/sftp.c 2006-02-01 08:28:26.000000000 -0500
-@@ -1466,3 +1466,3 @@ main(int argc, char **argv)
-
-- while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) {
-+ while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:z")) != -1) {
- switch (ch) {
-@@ -1521,2 +1521,5 @@ main(int argc, char **argv)
- case 'h':
-+ case 'z':
-+ addargs(&args, "-%c", ch);
-+ break;
- default:
-diff -r -u -p1 openssh-4.3p1/ssh.c none-openssh-4.3p1/ssh.c
---- openssh-4.3p1/ssh.c 2005-12-31 00:33:37.000000000 -0500
-+++ none-openssh-4.3p1/ssh.c 2006-02-01 08:30:30.000000000 -0500
-@@ -160,7 +160,7 @@
- usage(void)
- {
- fprintf(stderr,
--"usage: ssh [-1246AaBCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
-+"usage: ssh [-1246AaBCfgkMNnqRrsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
- " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
- " [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
- " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
-@@ -165,2 +165,3 @@ usage(void)
- " [-w tunnel:tunnel] [user@]hostname [command]\n"
-+" [-r Receive Buffer Size in K]\n"
- );
-@@ -246,9 +246,12 @@
- /* Parse command-line arguments. */
- host = NULL;
-
-+ /* need to set options.tcp_rcv_buf to 0 */
-+ options.tcp_rcv_buf = 0;
-+
- again:
- while ((opt = getopt(ac, av,
-- "1246ab:c:e:fgi:kl:m:no:p:qstvxABCD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
-+ "1246ab:c:e:fgi:kl:m:no:p:qr:stvxABCD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
- switch (opt) {
- case '1':
- options.protocol = SSH_PROTO_1;
-@@ -474,2 +477,3 @@ again:
- no_tty_flag = 1;
-+ options.none_switch = 0;
- break;
-@@ -497,2 +501,13 @@ again:
- break;
-+ case 'r':
-+ options.tcp_rcv_buf = atoi(optarg) * 1024;
-+ break;
-+ case 'z':
-+ /* make sure we can't turn on the none_switch */
-+ /* if they try to force a no tty flag on a tty session */
-+ if (!no_tty_flag) {
-+ options.none_switch = 1;
-+ }
-+ break;
-+
- default:
-@@ -1132,2 +1147,3 @@ ssh_session2_open(void)
- if (tty_flag) {
-+ window = 4*CHAN_SES_PACKET_DEFAULT;
- window >>= 1;
-@@ -1139,3 +1155,5 @@ ssh_session2_open(void)
- "client-session", /*nonblock*/0);
--
-+ if (!tty_flag && (!(datafellows & SSH_BUG_LARGEWINDOW))) {
-+ c->dynamic_window = 1;
-+ }
- debug3("ssh_session2_open: channel_new: %d", c->self);
-Only in none-openssh-4.3p1/: ssh.c.rej
-diff -r -u -p1 openssh-4.3p1/sshconnect.c none-openssh-4.3p1/sshconnect.c
---- openssh-4.3p1/sshconnect.c 2005-12-13 03:29:03.000000000 -0500
-+++ none-openssh-4.3p1/sshconnect.c 2006-02-01 11:08:29.000000000 -0500
-@@ -168,2 +168,25 @@ ssh_create_socket(int privileged, struct
- debug("Allocated local port %d.", p);
-+
-+
-+ /* tuning needs to happen after the socket is */
-+ /* created but before the connection happens */
-+ /* so winscale is negotiated properly -cjr */
-+
-+ /* Set tcp receive buffer if requested */
-+ if (options.tcp_rcv_buf)
-+ {
-+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-+ (void *)&options.tcp_rcv_buf,
-+ sizeof(options.tcp_rcv_buf)) >= 0)
-+ {
-+ debug("setsockopt SO_RCVBUF: %.100s", strerror(errno));
-+ }
-+ else
-+ {
-+ /* coudln't set the socket size to use spec. */
-+ /* should default to system param and continue */
-+ /* warn the user though - cjr */
-+ error("Couldn't set socket receive buffer as requested. Continuing anyway.");
-+ }
-+ }
- return sock;
-@@ -173,4 +196,26 @@ ssh_create_socket(int privileged, struct
- error("socket: %.100s", strerror(errno));
--
-- /* Bind the socket to an alternative local IP address */
-+
-+ /* tuning needs to happen after the socket is */
-+ /* created but before the connection happens */
-+ /* so winscale is negotiated properly -cjr */
-+
-+ /* Set tcp receive buffer if requested */
-+ if (options.tcp_rcv_buf)
-+ {
-+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-+ (void *)&options.tcp_rcv_buf,
-+ sizeof(options.tcp_rcv_buf)) >= 0)
-+ {
-+ debug("setsockopt SO_RCVBUF: %.100s", strerror(errno));
-+ }
-+ else
-+ {
-+ /* coudln't set the socket size to use spec. */
-+ /* should default to system param and continue */
-+ /* warn the user though - cjr */
-+ error("Couldn't set socket receive buffer as requested. Continuing anyway.");
-+ }
-+ }
-+
-+ /* Bind the socket to an alternative local IP address */
- if (options.bind_address == NULL)
-@@ -481,3 +526,3 @@ ssh_exchange_identification(void)
- compat20 ? PROTOCOL_MINOR_2 : minor1,
-- SSH_VERSION);
-+ SSH_RELEASE);
- if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
-diff -r -u -p1 openssh-4.3p1/sshconnect2.c none-openssh-4.3p1/sshconnect2.c
---- openssh-4.3p1/sshconnect2.c 2005-11-04 23:07:33.000000000 -0500
-+++ none-openssh-4.3p1/sshconnect2.c 2006-02-01 11:08:29.000000000 -0500
-@@ -60,2 +60,8 @@ extern char *server_version_string;
- extern Options options;
-+extern Kex *xxx_kex;
-+
-+/* tty_flag is set in ssh.c. use this in ssh_userauth2 */
-+/* if it is set then prevent the switch to the null cipher */
-+
-+extern int tty_flag;
-
-@@ -311,3 +317,11 @@ ssh_userauth2(const char *local_user, co
- dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
--
-+ if ((options.none_switch == 1) && !tty_flag) /* no null on tty sessions */
-+ {
-+ debug("Requesting none rekeying...");
-+ myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
-+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
-+ kex_prop2buf(&xxx_kex->my,myproposal);
-+ packet_request_rekeying();
-+ fprintf(stderr, "WARNING: ENABLED NULL CIPHER\n");
-+ }
- debug("Authentication succeeded (%s).", authctxt.method->name);
-diff -r -u -p1 openssh-4.3p1/sshd.c none-openssh-4.3p1/sshd.c
---- openssh-4.3p1/sshd.c 2005-12-23 22:59:12.000000000 -0500
-+++ none-openssh-4.3p1/sshd.c 2006-02-01 11:08:30.000000000 -0500
-@@ -379,3 +379,3 @@ sshd_exchange_identification(int sock_in
- }
-- snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
-+ snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE);
- server_version_string = xstrdup(buf);
-diff -r -u -p1 openssh-4.3p1/version.h none-openssh-4.3p1/version.h
---- openssh-4.3p1/version.h 2006-02-01 06:27:31.000000000 -0500
-+++ none-openssh-4.3p1/version.h 2006-02-01 11:08:30.000000000 -0500
-@@ -5,2 +5,3 @@
- #define SSH_PORTABLE "p1"
--#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
-+#define SSH_HPN "-hpn"
-+#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN
+++ /dev/null
-diff -r -u -p1 openssh-4.3p1/buffer.c patch/buffer.c
---- openssh-4.3p1/buffer.c 2005-03-14 07:22:26.000000000 -0500
-+++ patch/buffer.c 2006-02-01 10:26:10.000000000 -0500
-@@ -109,3 +109,3 @@ restart:
- newlen = buffer->alloc + len + 32768;
-- if (newlen > BUFFER_MAX_LEN)
-+ if (newlen > BUFFER_MAX_HPN_LEN)
- fatal("buffer_append_space: alloc %u not supported",
-diff -r -u -p1 openssh-4.3p1/buffer.h patch/buffer.h
---- openssh-4.3p1/buffer.h 2005-03-14 07:22:26.000000000 -0500
-+++ patch/buffer.h 2006-02-01 10:26:10.000000000 -0500
-@@ -27,2 +27,3 @@ typedef struct {
- #define BUFFER_MAX_LEN 0xa00000
-+#define BUFFER_MAX_HPN_LEN (2<<29)-1
-
-diff -r -u -p1 openssh-4.3p1/channels.c patch/channels.c
---- openssh-4.3p1/channels.c 2006-01-31 05:47:15.000000000 -0500
-+++ patch/channels.c 2006-02-01 10:26:10.000000000 -0500
-@@ -290,2 +290,3 @@ channel_new(char *ctype, int type, int r
- c->local_maxpacket = maxpack;
-+ c->dynamic_window = 0;
- c->remote_id = -1;
-@@ -750,5 +751,5 @@ channel_pre_open(Channel *c, fd_set * re
- u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
--
-+
- /* check buffer limits */
-- limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
-+ limit = MIN(limit, (BUFFER_MAX_HPN_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
-
-@@ -1617,5 +1618,20 @@ channel_check_window(Channel *c)
- c->local_consumed > 0) {
-+ u_int32_t tcpwinsz = 0;
-+ socklen_t optsz = sizeof(tcpwinsz);
-+ int ret = -1;
-+ u_int32_t addition = 0;
-+ if (c->dynamic_window) {
-+ ret = getsockopt(packet_get_connection_in(),
-+ SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
-+ if ((ret == 0) && tcpwinsz > BUFFER_MAX_HPN_LEN)
-+ tcpwinsz = BUFFER_MAX_HPN_LEN;
-+ }
-+ if (c->dynamic_window && (ret == 0) &&
-+ (tcpwinsz > c->local_window_max)) {
-+ addition = tcpwinsz - c->local_window_max;
-+ c->local_window_max += addition;
-+ }
- packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
- packet_put_int(c->remote_id);
-- packet_put_int(c->local_consumed);
-+ packet_put_int(c->local_consumed + addition);
- packet_send();
-@@ -1624,3 +1640,3 @@ channel_check_window(Channel *c)
- c->local_consumed);
-- c->local_window += c->local_consumed;
-+ c->local_window += c->local_consumed + addition;
- c->local_consumed = 0;
-diff -r -u -p1 openssh-4.3p1/channels.h patch/channels.h
---- openssh-4.3p1/channels.h 2005-12-31 00:22:32.000000000 -0500
-+++ patch/channels.h 2006-02-01 10:26:10.000000000 -0500
-@@ -102,2 +102,3 @@ struct Channel {
- u_int local_maxpacket;
-+ int dynamic_window;
- int extended_usage;
-@@ -126,7 +127,7 @@ struct Channel {
- #define CHAN_SES_PACKET_DEFAULT (32*1024)
--#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT)
-+#define CHAN_SES_WINDOW_DEFAULT (0xa00000/2)
- #define CHAN_TCP_PACKET_DEFAULT (32*1024)
--#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
-+#define CHAN_TCP_WINDOW_DEFAULT (0xa00000/2)
- #define CHAN_X11_PACKET_DEFAULT (16*1024)
--#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
-+#define CHAN_X11_WINDOW_DEFAULT (0xa00000/2)
-
-diff -r -u -p1 openssh-4.3p1/compat.c patch/compat.c
---- openssh-4.3p1/compat.c 2005-03-01 05:24:33.000000000 -0500
-+++ patch/compat.c 2006-02-01 10:26:10.000000000 -0500
-@@ -164,2 +164,10 @@ compat_datafellows(const char *version)
- datafellows = check[i].bugs;
-+ /* Check to see if the remote side is OpenSSH and not HPN */
-+ if(strstr(version,"OpenSSH") != NULL)
-+ {
-+ if (strstr(version,"hpn") == NULL)
-+ {
-+ datafellows |= SSH_BUG_LARGEWINDOW;
-+ }
-+ }
- return;
-diff -r -u -p1 openssh-4.3p1/compat.h patch/compat.h
---- openssh-4.3p1/compat.h 2005-03-01 05:24:33.000000000 -0500
-+++ patch/compat.h 2006-02-01 10:26:10.000000000 -0500
-@@ -58,2 +58,3 @@
- #define SSH_OLD_FORWARD_ADDR 0x01000000
-+#define SSH_BUG_LARGEWINDOW 0x02000000
-
-diff -r -u -p1 openssh-4.3p1/readconf.h patch/readconf.h
---- openssh-4.3p1/readconf.h 2005-12-13 03:29:02.000000000 -0500
-+++ patch/readconf.h 2006-02-01 10:26:11.000000000 -0500
-@@ -59,2 +59,3 @@ typedef struct {
- int tcp_keep_alive; /* Set SO_KEEPALIVE. */
-+ int tcp_rcv_buf; /* user switch to set tcp recv buffer */
- LogLevel log_level; /* Level for logging. */
-diff -r -u -p1 openssh-4.3p1/scp.c patch/scp.c
---- openssh-4.3p1/scp.c 2006-01-31 06:11:38.000000000 -0500
-+++ patch/scp.c 2006-02-01 07:04:50.000000000 -0500
-@@ -280,3 +280,3 @@ main(int argc, char **argv)
- fflag = tflag = 0;
-- while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
-+ while ((ch = getopt(argc, argv, "dfl:pR:rtvBCc:i:P:q1246S:o:F:w:")) != -1)
- switch (ch) {
-@@ -341,2 +341,5 @@ main(int argc, char **argv)
- break;
-+ case 'R':
-+ addargs(&args, "-r%s", optarg);
-+ break;
- default:
-@@ -555,3 +558,3 @@ source(int argc, char **argv)
- int fd = -1, haderr, indx;
-- char *last, *name, buf[2048];
-+ char *last, *name, buf[16384];
- int len;
-@@ -782,3 +785,3 @@ sink(int argc, char **argv)
- int setimes, targisdir, wrerrno = 0;
-- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
-+ char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
- struct timeval tv[2];
-@@ -943,3 +946,3 @@ bad: run_err("%s: %s", np, strerror(er
- (void) atomicio(vwrite, remout, "", 1);
-- if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) {
-+ if ((bp = allocbuf(&buffer, ofd, sizeof(buf))) == NULL) {
- (void) close(ofd);
-@@ -953,4 +956,4 @@ bad: run_err("%s: %s", np, strerror(er
- start_progress_meter(curfile, size, &statbytes);
-- for (count = i = 0; i < size; i += 4096) {
-- amt = 4096;
-+ for (count = i = 0; i < size; i += sizeof(buf)) {
-+ amt = sizeof(buf);
- if (i + amt > size)
-@@ -971,3 +974,3 @@ bad: run_err("%s: %s", np, strerror(er
- if (limit_rate)
-- bwlimit(4096);
-+ bwlimit(sizeof(buf));
-
-@@ -1086,4 +1089,4 @@ usage(void)
- (void) fprintf(stderr,
-- "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
-- " [-l limit] [-o ssh_option] [-P port] [-S program]\n"
-+ "usage: scp [-1246BCpqrRv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
-+ " [-l limit] [-o ssh_option] [-P port] [-R buffer size] [-S program]\n"
- " [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
-diff -r -u -p1 openssh-4.3p1/serverloop.c patch/serverloop.c
---- openssh-4.3p1/serverloop.c 2005-12-31 00:33:37.000000000 -0500
-+++ patch/serverloop.c 2006-02-01 10:26:11.000000000 -0500
-@@ -977,2 +977,4 @@ server_request_session(void)
- 0, "server-session", 1);
-+ if (!(datafellows & SSH_BUG_LARGEWINDOW))
-+ c->dynamic_window = 1;
- if (session_open(the_authctxt, c->self) != 1) {
-diff -r -u -p1 openssh-4.3p1/ssh.c patch/ssh.c
---- openssh-4.3p1/ssh.c 2005-12-31 00:33:37.000000000 -0500
-+++ patch/ssh.c 2006-02-01 07:02:41.000000000 -0500
-@@ -160,7 +160,7 @@
- usage(void)
- {
- fprintf(stderr,
--"usage: ssh [-1246AaBCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
-+"usage: ssh [-1246AaBCfgkMNnqRrsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
- " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
- " [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
- " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
-@@ -165,2 +165,3 @@ usage(void)
- " [-w tunnel:tunnel] [user@]hostname [command]\n"
-+" [-r receive buffer size]\n"
- );
-@@ -246,9 +246,12 @@
- /* Parse command-line arguments. */
- host = NULL;
-
-+ /* need to set options.tcp_rcv_buf to 0 */
-+ options.tcp_rcv_buf = 0;
-+
- again:
- while ((opt = getopt(ac, av,
-- "1246ab:c:e:fgi:kl:m:no:p:qstvxABCD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
-+ "1246ab:c:e:fgi:kl:m:no:p:qr:stvxABCD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
- switch (opt) {
- case '1':
- options.protocol = SSH_PROTO_1;
-@@ -497,2 +501,5 @@ again:
- break;
-+ case 'r':
-+ options.tcp_rcv_buf = atoi(optarg) * 1024;
-+ break;
- default:
-@@ -1132,2 +1139,3 @@ ssh_session2_open(void)
- if (tty_flag) {
-+ window = 4*CHAN_SES_PACKET_DEFAULT;
- window >>= 1;
-@@ -1139,3 +1147,5 @@ ssh_session2_open(void)
- "client-session", /*nonblock*/0);
--
-+ if (!tty_flag && (!(datafellows & SSH_BUG_LARGEWINDOW))) {
-+ c->dynamic_window = 1;
-+ }
- debug3("ssh_session2_open: channel_new: %d", c->self);
-Only in patch: ssh.c.rej
-diff -r -u -p1 openssh-4.3p1/sshconnect.c patch/sshconnect.c
---- openssh-4.3p1/sshconnect.c 2005-12-13 03:29:03.000000000 -0500
-+++ patch/sshconnect.c 2006-02-01 10:26:11.000000000 -0500
-@@ -168,2 +168,25 @@ ssh_create_socket(int privileged, struct
- debug("Allocated local port %d.", p);
-+
-+
-+ /* tuning needs to happen after the socket is */
-+ /* created but before the connection happens */
-+ /* so winscale is negotiated properly -cjr */
-+
-+ /* Set tcp receive buffer if requested */
-+ if (options.tcp_rcv_buf)
-+ {
-+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-+ (void *)&options.tcp_rcv_buf,
-+ sizeof(options.tcp_rcv_buf)) >= 0)
-+ {
-+ debug("setsockopt SO_RCVBUF: %.100s", strerror(errno));
-+ }
-+ else
-+ {
-+ /* coudln't set the socket size to use spec. */
-+ /* should default to system param and continue */
-+ /* warn the user though - cjr */
-+ error("Couldn't set socket receive buffer as requested. Continuing anyway.");
-+ }
-+ }
- return sock;
-@@ -173,4 +196,26 @@ ssh_create_socket(int privileged, struct
- error("socket: %.100s", strerror(errno));
--
-- /* Bind the socket to an alternative local IP address */
-+
-+ /* tuning needs to happen after the socket is */
-+ /* created but before the connection happens */
-+ /* so winscale is negotiated properly -cjr */
-+
-+ /* Set tcp receive buffer if requested */
-+ if (options.tcp_rcv_buf)
-+ {
-+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-+ (void *)&options.tcp_rcv_buf,
-+ sizeof(options.tcp_rcv_buf)) >= 0)
-+ {
-+ debug("setsockopt SO_RCVBUF: %.100s", strerror(errno));
-+ }
-+ else
-+ {
-+ /* coudln't set the socket size to use spec. */
-+ /* should default to system param and continue */
-+ /* warn the user though - cjr */
-+ error("Couldn't set socket receive buffer as requested. Continuing anyway.");
-+ }
-+ }
-+
-+ /* Bind the socket to an alternative local IP address */
- if (options.bind_address == NULL)
-@@ -481,3 +526,3 @@ ssh_exchange_identification(void)
- compat20 ? PROTOCOL_MINOR_2 : minor1,
-- SSH_VERSION);
-+ SSH_RELEASE);
- if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
-diff -r -u -p1 openssh-4.3p1/sshd.c patch/sshd.c
---- openssh-4.3p1/sshd.c 2005-12-23 22:59:12.000000000 -0500
-+++ patch/sshd.c 2006-02-01 10:26:11.000000000 -0500
-@@ -379,3 +379,3 @@ sshd_exchange_identification(int sock_in
- }
-- snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
-+ snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE);
- server_version_string = xstrdup(buf);
-diff -r -u -p1 openssh-4.3p1/version.h patch/version.h
---- openssh-4.3p1/version.h 2006-02-01 06:27:31.000000000 -0500
-+++ patch/version.h 2006-02-01 10:26:11.000000000 -0500
-@@ -5,2 +5,3 @@
- #define SSH_PORTABLE "p1"
--#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
-+#define SSH_HPN "-hpn"
-+#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN
+++ /dev/null
-diff -NupwB ../4.7/openssh-4.7p1/atomicio.c openssh-4.7p1/atomicio.c
---- ../4.7/openssh-4.7p1/atomicio.c 2007-06-25 08:15:12.000000000 -0400
-+++ openssh-4.7p1/atomicio.c 2008-02-06 13:28:54.000000000 -0500
-@@ -57,13 +57,13 @@ atomicio(ssize_t (*f) (int, void *, size
- res = (f) (fd, s + pos, n - pos);
- switch (res) {
- case -1:
--#ifdef EWOULDBLOCK
-- if (errno == EINTR || errno == EWOULDBLOCK)
--#else
- if (errno == EINTR)
--#endif
- continue;
-+#ifdef EWOULDBLOCK
-+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
-+#else
- if (errno == EAGAIN) {
-+#endif
- (void)poll(&pfd, 1, -1);
- continue;
- }
-@@ -103,13 +103,13 @@ atomiciov(ssize_t (*f) (int, const struc
- res = (f) (fd, iov, iovcnt);
- switch (res) {
- case -1:
--#ifdef EWOULDBLOCK
-- if (errno == EINTR || errno == EWOULDBLOCK)
--#else
- if (errno == EINTR)
--#endif
- continue;
-+#ifdef EWOULDBLOCK
-+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
-+#else
- if (errno == EAGAIN) {
-+#endif
- (void)poll(&pfd, 1, -1);
- continue;
- }
-diff -NupwB ../4.7/openssh-4.7p1/auth2.c openssh-4.7p1/auth2.c
---- ../4.7/openssh-4.7p1/auth2.c 2007-05-20 00:58:41.000000000 -0400
-+++ openssh-4.7p1/auth2.c 2008-02-06 13:29:19.000000000 -0500
-@@ -44,6 +44,7 @@
- #include "dispatch.h"
- #include "pathnames.h"
- #include "buffer.h"
-+#include "canohost.h"
-
- #ifdef GSSAPI
- #include "ssh-gss.h"
-@@ -67,6 +68,9 @@ extern Authmethod method_hostbased;
- extern Authmethod method_gssapi;
- #endif
-
-+static int log_flag = 0;
-+
-+
- Authmethod *authmethods[] = {
- &method_none,
- &method_pubkey,
-@@ -151,6 +155,11 @@ input_userauth_request(int type, u_int32
- service = packet_get_string(NULL);
- method = packet_get_string(NULL);
- debug("userauth-request for user %s service %s method %s", user, service, method);
-+ if (!log_flag) {
-+ logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s",
-+ get_remote_ipaddr(), get_remote_port(), user);
-+ log_flag = 1;
-+ }
- debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
-
- if ((style = strchr(user, ':')) != NULL)
-diff -NupwB ../4.7/openssh-4.7p1/buffer.c openssh-4.7p1/buffer.c
---- ../4.7/openssh-4.7p1/buffer.c 2006-08-04 22:39:39.000000000 -0400
-+++ openssh-4.7p1/buffer.c 2008-02-06 17:02:07.000000000 -0500
-@@ -127,7 +127,9 @@ restart:
-
- /* Increase the size of the buffer and retry. */
- newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
-- if (newlen > BUFFER_MAX_LEN)
-+ /* need it to be slightly larger than the MAX LEN for this */
-+ /* still investigating *why* but this works for now -cjr */
-+ if (newlen > (BUFFER_MAX_LEN_HPN + BUFFER_MAX_LEN))
- fatal("buffer_append_space: alloc %u not supported",
- newlen);
- buffer->buf = xrealloc(buffer->buf, 1, newlen);
-diff -NupwB ../4.7/openssh-4.7p1/buffer.h openssh-4.7p1/buffer.h
---- ../4.7/openssh-4.7p1/buffer.h 2006-08-04 22:39:39.000000000 -0400
-+++ openssh-4.7p1/buffer.h 2008-02-06 13:28:23.000000000 -0500
-@@ -16,6 +16,9 @@
- #ifndef BUFFER_H
- #define BUFFER_H
-
-+/* move the following to a more appropriate place and name */
-+#define BUFFER_MAX_LEN_HPN 0x4000000 /* 64MB */
-+
- typedef struct {
- u_char *buf; /* Buffer for data. */
- u_int alloc; /* Number of bytes allocated for data. */
-diff -NupwB ../4.7/openssh-4.7p1/channels.c openssh-4.7p1/channels.c
---- ../4.7/openssh-4.7p1/channels.c 2007-06-25 05:04:47.000000000 -0400
-+++ openssh-4.7p1/channels.c 2008-02-06 13:29:19.000000000 -0500
-@@ -311,6 +311,7 @@ channel_new(char *ctype, int type, int r
- c->local_window_max = window;
- c->local_consumed = 0;
- c->local_maxpacket = maxpack;
-+ c->dynamic_window = 0;
- c->remote_id = -1;
- c->remote_name = xstrdup(remote_name);
- c->remote_window = 0;
-@@ -765,11 +766,35 @@ channel_pre_open_13(Channel *c, fd_set *
- FD_SET(c->sock, writeset);
- }
-
-+int channel_tcpwinsz () {
-+ u_int32_t tcpwinsz = 0;
-+ socklen_t optsz = sizeof(tcpwinsz);
-+ int ret = -1;
-+
-+ /* if we aren't on a socket return 128KB*/
-+ if(!packet_connection_is_on_socket())
-+ return(128*1024);
-+ ret = getsockopt(packet_get_connection_in(),
-+ SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
-+ /* return no more than 64MB */
-+ if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN)
-+ tcpwinsz = BUFFER_MAX_LEN_HPN;
-+ debug2("tcpwinsz: %d for connection: %d", tcpwinsz,
-+ packet_get_connection_in());
-+ return(tcpwinsz);
-+}
-+
- static void
- channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
- {
- u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
-
-+ /* check buffer limits */
-+ if ((!c->tcpwinsz) || (c->dynamic_window > 0))
-+ c->tcpwinsz = channel_tcpwinsz();
-+
-+ limit = MIN(limit, 2 * c->tcpwinsz);
-+
- if (c->istate == CHAN_INPUT_OPEN &&
- limit > 0 &&
- buffer_len(&c->input) < limit &&
-@@ -1661,14 +1686,21 @@ channel_check_window(Channel *c)
- c->local_maxpacket*3) ||
- c->local_window < c->local_window_max/2) &&
- c->local_consumed > 0) {
-+ u_int addition = 0;
-+ /* adjust max window size if we are in a dynamic environment */
-+ if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
-+ /* grow the window somewhat aggressively to maintain pressure */
-+ addition = 1.5*(c->tcpwinsz - c->local_window_max);
-+ c->local_window_max += addition;
-+ }
- packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
- packet_put_int(c->remote_id);
-- packet_put_int(c->local_consumed);
-+ packet_put_int(c->local_consumed + addition);
- packet_send();
- debug2("channel %d: window %d sent adjust %d",
- c->self, c->local_window,
- c->local_consumed);
-- c->local_window += c->local_consumed;
-+ c->local_window += c->local_consumed + addition;
- c->local_consumed = 0;
- }
- return 1;
-@@ -1871,11 +1903,12 @@ channel_after_select(fd_set *readset, fd
-
-
- /* If there is data to send to the connection, enqueue some of it now. */
--void
-+int
- channel_output_poll(void)
- {
- Channel *c;
- u_int i, len;
-+ int packet_length = 0;
-
- for (i = 0; i < channels_alloc; i++) {
- c = channels[i];
-@@ -1915,7 +1948,7 @@ channel_output_poll(void)
- packet_start(SSH2_MSG_CHANNEL_DATA);
- packet_put_int(c->remote_id);
- packet_put_string(data, dlen);
-- packet_send();
-+ packet_length = packet_send();
- c->remote_window -= dlen + 4;
- xfree(data);
- }
-@@ -1945,7 +1978,7 @@ channel_output_poll(void)
- SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
- packet_put_int(c->remote_id);
- packet_put_string(buffer_ptr(&c->input), len);
-- packet_send();
-+ packet_length = packet_send();
- buffer_consume(&c->input, len);
- c->remote_window -= len;
- }
-@@ -1980,12 +2013,13 @@ channel_output_poll(void)
- packet_put_int(c->remote_id);
- packet_put_int(SSH2_EXTENDED_DATA_STDERR);
- packet_put_string(buffer_ptr(&c->extended), len);
-- packet_send();
-+ packet_length = packet_send();
- buffer_consume(&c->extended, len);
- c->remote_window -= len;
- debug2("channel %d: sent ext data %d", c->self, len);
- }
- }
-+ return (packet_length);
- }
-
-
-@@ -2342,7 +2376,8 @@ channel_set_af(int af)
-
- static int
- channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
-- const char *host_to_connect, u_short port_to_connect, int gateway_ports)
-+ const char *host_to_connect, u_short port_to_connect, int gateway_ports,
-+ int hpn_disabled, int hpn_buffer_size)
- {
- Channel *c;
- int sock, r, success = 0, wildcard = 0, is_client;
-@@ -2455,9 +2490,15 @@ channel_setup_fwd_listener(int type, con
- continue;
- }
- /* Allocate a channel number for the socket. */
-+ /* explicitly test for hpn disabled option. if true use smaller window size */
-+ if (hpn_disabled)
- c = channel_new("port listener", type, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
- 0, "port listener", 1);
-+ else
-+ c = channel_new("port listener", type, sock, sock, -1,
-+ hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
-+ 0, "port listener", 1);
- strlcpy(c->path, host, sizeof(c->path));
- c->host_port = port_to_connect;
- c->listening_port = listen_port;
-@@ -2494,20 +2535,22 @@ channel_cancel_rport_listener(const char
- /* protocol local port fwd, used by ssh (and sshd in v1) */
- int
- channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
-- const char *host_to_connect, u_short port_to_connect, int gateway_ports)
-+ const char *host_to_connect, u_short port_to_connect, int gateway_ports,
-+ int hpn_disabled, int hpn_buffer_size)
- {
- return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
- listen_host, listen_port, host_to_connect, port_to_connect,
-- gateway_ports);
-+ gateway_ports, hpn_disabled, hpn_buffer_size);
- }
-
- /* protocol v2 remote port fwd, used by sshd */
- int
- channel_setup_remote_fwd_listener(const char *listen_address,
-- u_short listen_port, int gateway_ports)
-+ u_short listen_port, int gateway_ports, int hpn_disabled, int hpn_buffer_size)
- {
- return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
-- listen_address, listen_port, NULL, 0, gateway_ports);
-+ listen_address, listen_port, NULL, 0, gateway_ports,
-+ hpn_disabled, hpn_buffer_size);
- }
-
- /*
-@@ -2622,7 +2665,8 @@ channel_request_rforward_cancel(const ch
- * message if there was an error).
- */
- int
--channel_input_port_forward_request(int is_root, int gateway_ports)
-+channel_input_port_forward_request(int is_root, int gateway_ports,
-+ int hpn_disabled, int hpn_buffer_size)
- {
- u_short port, host_port;
- int success = 0;
-@@ -2648,7 +2692,7 @@ channel_input_port_forward_request(int i
-
- /* Initiate forwarding */
- success = channel_setup_local_fwd_listener(NULL, port, hostname,
-- host_port, gateway_ports);
-+ host_port, gateway_ports, hpn_disabled, hpn_buffer_size);
-
- /* Free the argument string. */
- xfree(hostname);
-@@ -2852,7 +2896,8 @@ channel_send_window_changes(void)
- */
- int
- x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
-- int single_connection, u_int *display_numberp, int **chanids)
-+ int single_connection, u_int *display_numberp, int **chanids,
-+ int hpn_disabled, int hpn_buffer_size)
- {
- Channel *nc = NULL;
- int display_number, sock;
-@@ -2949,10 +2994,17 @@ x11_create_display_inet(int x11_display_
- *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
- for (n = 0; n < num_socks; n++) {
- sock = socks[n];
-+ /* Is this really necassary? */
-+ if (hpn_disabled)
- nc = channel_new("x11 listener",
- SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
- CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
- 0, "X11 inet listener", 1);
-+ else
-+ nc = channel_new("x11 listener",
-+ SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
-+ hpn_buffer_size, CHAN_X11_PACKET_DEFAULT,
-+ 0, "X11 inet listener", 1);
- nc->single_connection = single_connection;
- (*chanids)[n] = nc->self;
- }
-diff -NupwB ../4.7/openssh-4.7p1/channels.h openssh-4.7p1/channels.h
---- ../4.7/openssh-4.7p1/channels.h 2007-06-12 09:38:54.000000000 -0400
-+++ openssh-4.7p1/channels.h 2008-02-06 13:29:19.000000000 -0500
-@@ -98,8 +98,10 @@ struct Channel {
- u_int local_window_max;
- u_int local_consumed;
- u_int local_maxpacket;
-+ int dynamic_window;
- int extended_usage;
- int single_connection;
-+ u_int tcpwinsz;
-
- char *ctype; /* type */
-
-@@ -122,9 +124,11 @@ struct Channel {
-
- /* default window/packet sizes for tcp/x11-fwd-channel */
- #define CHAN_SES_PACKET_DEFAULT (32*1024)
--#define CHAN_SES_WINDOW_DEFAULT (64*CHAN_SES_PACKET_DEFAULT)
-+#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT)
-+
- #define CHAN_TCP_PACKET_DEFAULT (32*1024)
--#define CHAN_TCP_WINDOW_DEFAULT (64*CHAN_TCP_PACKET_DEFAULT)
-+#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
-+
- #define CHAN_X11_PACKET_DEFAULT (16*1024)
- #define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
-
-@@ -193,7 +197,7 @@ void channel_input_window_adjust(int, u
-
- void channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
- void channel_after_select(fd_set *, fd_set *);
--void channel_output_poll(void);
-+int channel_output_poll(void);
-
- int channel_not_very_much_buffered_data(void);
- void channel_close_all(void);
-@@ -208,21 +212,21 @@ void channel_add_permitted_opens(char *
- int channel_add_adm_permitted_opens(char *, int);
- void channel_clear_permitted_opens(void);
- void channel_clear_adm_permitted_opens(void);
--int channel_input_port_forward_request(int, int);
-+int channel_input_port_forward_request(int, int, int, int);
- int channel_connect_to(const char *, u_short);
- int channel_connect_by_listen_address(u_short);
- int channel_request_remote_forwarding(const char *, u_short,
- const char *, u_short);
- int channel_setup_local_fwd_listener(const char *, u_short,
-- const char *, u_short, int);
-+ const char *, u_short, int, int, int);
- void channel_request_rforward_cancel(const char *host, u_short port);
--int channel_setup_remote_fwd_listener(const char *, u_short, int);
-+int channel_setup_remote_fwd_listener(const char *, u_short, int, int, int);
- int channel_cancel_rport_listener(const char *, u_short);
-
- /* x11 forwarding */
-
- int x11_connect_display(void);
--int x11_create_display_inet(int, int, int, u_int *, int **);
-+int x11_create_display_inet(int, int, int, u_int *, int **, int, int);
- void x11_input_open(int, u_int32_t, void *);
- void x11_request_forwarding_with_spoofing(int, const char *, const char *,
- const char *);
-diff -NupwB ../4.7/openssh-4.7p1/cipher.c openssh-4.7p1/cipher.c
---- ../4.7/openssh-4.7p1/cipher.c 2006-08-04 22:39:39.000000000 -0400
-+++ openssh-4.7p1/cipher.c 2008-02-06 13:28:54.000000000 -0500
-@@ -55,6 +55,7 @@ extern const EVP_CIPHER *evp_ssh1_bf(voi
- extern const EVP_CIPHER *evp_ssh1_3des(void);
- extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
- extern const EVP_CIPHER *evp_aes_128_ctr(void);
-+extern const EVP_CIPHER *evp_aes_ctr_mt(void);
- extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
-
- struct Cipher {
-@@ -81,9 +82,9 @@ struct Cipher {
- { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
- { "rijndael-cbc@lysator.liu.se",
- SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
-- { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
-- { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
-- { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
-+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_ctr_mt },
-+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_ctr_mt },
-+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_ctr_mt },
- #ifdef USE_CIPHER_ACSS
- { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
- #endif
-@@ -156,7 +157,8 @@ ciphers_valid(const char *names)
- for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
- (p = strsep(&cp, CIPHER_SEP))) {
- c = cipher_by_name(p);
-- if (c == NULL || c->number != SSH_CIPHER_SSH2) {
-+ if (c == NULL || (c->number != SSH_CIPHER_SSH2 &&
-+c->number != SSH_CIPHER_NONE)) {
- debug("bad cipher %s [%s]", p, names);
- xfree(cipher_list);
- return 0;
-@@ -330,6 +332,7 @@ cipher_get_keyiv(CipherContext *cc, u_ch
- int evplen;
-
- switch (c->number) {
-+ case SSH_CIPHER_NONE:
- case SSH_CIPHER_SSH2:
- case SSH_CIPHER_DES:
- case SSH_CIPHER_BLOWFISH:
-@@ -364,6 +367,7 @@ cipher_set_keyiv(CipherContext *cc, u_ch
- int evplen = 0;
-
- switch (c->number) {
-+ case SSH_CIPHER_NONE:
- case SSH_CIPHER_SSH2:
- case SSH_CIPHER_DES:
- case SSH_CIPHER_BLOWFISH:
-diff -NupwB ../4.7/openssh-4.7p1/cipher-ctr-mt.c openssh-4.7p1/cipher-ctr-mt.c
---- ../4.7/openssh-4.7p1/cipher-ctr-mt.c 1969-12-31 19:00:00.000000000 -0500
-+++ openssh-4.7p1/cipher-ctr-mt.c 2008-02-06 13:28:54.000000000 -0500
-@@ -0,0 +1,473 @@
-+/*
-+ * OpenSSH Multi-threaded AES-CTR Cipher
-+ *
-+ * Author: Benjamin Bennett <ben@psc.edu>
-+ * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
-+ *
-+ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
-+ * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
-+ *
-+ * Permission to use, copy, modify, and distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+#include "includes.h"
-+
-+#include <sys/types.h>
-+
-+#include <stdarg.h>
-+#include <string.h>
-+
-+#include <openssl/evp.h>
-+
-+#include "xmalloc.h"
-+#include "log.h"
-+
-+/* compatibility with old or broken OpenSSL versions */
-+#include "openbsd-compat/openssl-compat.h"
-+
-+#ifndef USE_BUILTIN_RIJNDAEL
-+#include <openssl/aes.h>
-+#endif
-+
-+#include <pthread.h>
-+
-+/*-------------------- TUNABLES --------------------*/
-+/* Number of pregen threads to use */
-+#define CIPHER_THREADS 2
-+
-+/* Number of keystream queues */
-+#define NUMKQ (CIPHER_THREADS + 2)
-+
-+/* Length of a keystream queue */
-+#define KQLEN 4096
-+
-+/* Processor cacheline length */
-+#define CACHELINE_LEN 64
-+
-+/* Collect thread stats and print at cancellation when in debug mode */
-+// #define CIPHER_THREAD_STATS
-+
-+/* Use single-byte XOR instead of 8-byte XOR */
-+// #define CIPHER_BYTE_XOR
-+/*-------------------- END TUNABLES --------------------*/
-+
-+
-+const EVP_CIPHER *evp_aes_ctr_mt(void);
-+
-+#ifdef CIPHER_THREAD_STATS
-+/*
-+ * Struct to collect thread stats
-+ */
-+struct thread_stats {
-+ u_int fills;
-+ u_int skips;
-+ u_int waits;
-+ u_int drains;
-+};
-+
-+/*
-+ * Debug print the thread stats
-+ * Use with pthread_cleanup_push for displaying at thread cancellation
-+ */
-+static void
-+thread_loop_stats(void *x)
-+{
-+ struct thread_stats *s = x;
-+
-+ debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
-+ s->fills, s->skips, s->waits);
-+}
-+
-+ #define STATS_STRUCT(s) struct thread_stats s
-+ #define STATS_INIT(s) { memset(&s, 0, sizeof(s)); }
-+ #define STATS_FILL(s) { s.fills++; }
-+ #define STATS_SKIP(s) { s.skips++; }
-+ #define STATS_WAIT(s) { s.waits++; }
-+ #define STATS_DRAIN(s) { s.drains++; }
-+#else
-+ #define STATS_STRUCT(s)
-+ #define STATS_INIT(s)
-+ #define STATS_FILL(s)
-+ #define STATS_SKIP(s)
-+ #define STATS_WAIT(s)
-+ #define STATS_DRAIN(s)
-+#endif
-+
-+/* Keystream Queue state */
-+enum {
-+ KQINIT,
-+ KQEMPTY,
-+ KQFILLING,
-+ KQFULL,
-+ KQDRAINING
-+};
-+
-+/* Keystream Queue struct */
-+struct kq {
-+ u_char keys[KQLEN][AES_BLOCK_SIZE];
-+ u_char ctr[AES_BLOCK_SIZE];
-+ u_char pad0[CACHELINE_LEN];
-+ volatile int qstate;
-+ pthread_mutex_t lock;
-+ pthread_cond_t cond;
-+ u_char pad1[CACHELINE_LEN];
-+};
-+
-+/* Context struct */
-+struct ssh_aes_ctr_ctx
-+{
-+ struct kq q[NUMKQ];
-+ AES_KEY aes_ctx;
-+ STATS_STRUCT(stats);
-+ u_char aes_counter[AES_BLOCK_SIZE];
-+ pthread_t tid[CIPHER_THREADS];
-+ int state;
-+ int qidx;
-+ int ridx;
-+};
-+
-+/* <friedl>
-+ * increment counter 'ctr',
-+ * the counter is of size 'len' bytes and stored in network-byte-order.
-+ * (LSB at ctr[len-1], MSB at ctr[0])
-+ */
-+static void
-+ssh_ctr_inc(u_char *ctr, u_int len)
-+{
-+ int i;
-+
-+ for (i = len - 1; i >= 0; i--)
-+ if (++ctr[i]) /* continue on overflow */
-+ return;
-+}
-+
-+/*
-+ * Add num to counter 'ctr'
-+ */
-+static void
-+ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
-+{
-+ int i;
-+ uint16_t n;
-+
-+ for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
-+ n = ctr[i] + (num & 0xff) + n;
-+ num >>= 8;
-+ ctr[i] = n & 0xff;
-+ n >>= 8;
-+ }
-+}
-+
-+/*
-+ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
-+ */
-+static void
-+thread_loop_cleanup(void *x)
-+{
-+ pthread_mutex_unlock((pthread_mutex_t *)x);
-+}
-+
-+/*
-+ * The life of a pregen thread:
-+ * Find empty keystream queues and fill them using their counter.
-+ * When done, update counter for the next fill.
-+ */
-+static void *
-+thread_loop(void *x)
-+{
-+ AES_KEY key;
-+ STATS_STRUCT(stats);
-+ struct ssh_aes_ctr_ctx *c = x;
-+ struct kq *q;
-+ int i;
-+ int qidx;
-+
-+ /* Threads stats on cancellation */
-+ STATS_INIT(stats);
-+#ifdef CIPHER_THREAD_STATS
-+ pthread_cleanup_push(thread_loop_stats, &stats);
-+#endif
-+
-+ /* Thread local copy of AES key */
-+ memcpy(&key, &c->aes_ctx, sizeof(key));
-+
-+ /*
-+ * Handle the special case of startup, one thread must fill
-+ * the first KQ then mark it as draining. Lock held throughout.
-+ */
-+ if (pthread_equal(pthread_self(), c->tid[0])) {
-+ q = &c->q[0];
-+ pthread_mutex_lock(&q->lock);
-+ if (q->qstate == KQINIT) {
-+ for (i = 0; i < KQLEN; i++) {
-+ AES_encrypt(q->ctr, q->keys[i], &key);
-+ ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
-+ }
-+ ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
-+ q->qstate = KQDRAINING;
-+ STATS_FILL(stats);
-+ pthread_cond_broadcast(&q->cond);
-+ }
-+ pthread_mutex_unlock(&q->lock);
-+ }
-+ else
-+ STATS_SKIP(stats);
-+
-+ /*
-+ * Normal case is to find empty queues and fill them, skipping over
-+ * queues already filled by other threads and stopping to wait for
-+ * a draining queue to become empty.
-+ *
-+ * Multiple threads may be waiting on a draining queue and awoken
-+ * when empty. The first thread to wake will mark it as filling,
-+ * others will move on to fill, skip, or wait on the next queue.
-+ */
-+ for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
-+ /* Check if I was cancelled, also checked in cond_wait */
-+ pthread_testcancel();
-+
-+ /* Lock queue and block if its draining */
-+ q = &c->q[qidx];
-+ pthread_mutex_lock(&q->lock);
-+ pthread_cleanup_push(thread_loop_cleanup, &q->lock);
-+ while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
-+ STATS_WAIT(stats);
-+ pthread_cond_wait(&q->cond, &q->lock);
-+ }
-+ pthread_cleanup_pop(0);
-+
-+ /* If filling or full, somebody else got it, skip */
-+ if (q->qstate != KQEMPTY) {
-+ pthread_mutex_unlock(&q->lock);
-+ STATS_SKIP(stats);
-+ continue;
-+ }
-+
-+ /*
-+ * Empty, let's fill it.
-+ * Queue lock is relinquished while we do this so others
-+ * can see that it's being filled.
-+ */
-+ q->qstate = KQFILLING;
-+ pthread_mutex_unlock(&q->lock);
-+ for (i = 0; i < KQLEN; i++) {
-+ AES_encrypt(q->ctr, q->keys[i], &key);
-+ ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
-+ }
-+
-+ /* Re-lock, mark full and signal consumer */
-+ pthread_mutex_lock(&q->lock);
-+ ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
-+ q->qstate = KQFULL;
-+ STATS_FILL(stats);
-+ pthread_cond_signal(&q->cond);
-+ pthread_mutex_unlock(&q->lock);
-+ }
-+
-+#ifdef CIPHER_THREAD_STATS
-+ /* Stats */
-+ pthread_cleanup_pop(1);
-+#endif
-+
-+ return NULL;
-+}
-+
-+static int
-+ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
-+ u_int len)
-+{
-+ struct ssh_aes_ctr_ctx *c;
-+ struct kq *q, *oldq;
-+ int ridx;
-+ u_char *buf;
-+
-+ if (len == 0)
-+ return (1);
-+ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
-+ return (0);
-+
-+ q = &c->q[c->qidx];
-+ ridx = c->ridx;
-+
-+ /* src already padded to block multiple */
-+ while (len > 0) {
-+ buf = q->keys[ridx];
-+
-+#ifdef CIPHER_BYTE_XOR
-+ dest[0] = src[0] ^ buf[0];
-+ dest[1] = src[1] ^ buf[1];
-+ dest[2] = src[2] ^ buf[2];
-+ dest[3] = src[3] ^ buf[3];
-+ dest[4] = src[4] ^ buf[4];
-+ dest[5] = src[5] ^ buf[5];
-+ dest[6] = src[6] ^ buf[6];
-+ dest[7] = src[7] ^ buf[7];
-+ dest[8] = src[8] ^ buf[8];
-+ dest[9] = src[9] ^ buf[9];
-+ dest[10] = src[10] ^ buf[10];
-+ dest[11] = src[11] ^ buf[11];
-+ dest[12] = src[12] ^ buf[12];
-+ dest[13] = src[13] ^ buf[13];
-+ dest[14] = src[14] ^ buf[14];
-+ dest[15] = src[15] ^ buf[15];
-+#else
-+ *(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
-+ *(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
-+ *(uint64_t *)(buf + 8);
-+#endif
-+
-+ dest += 16;
-+ src += 16;
-+ len -= 16;
-+ ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
-+
-+ /* Increment read index, switch queues on rollover */
-+ if ((ridx = (ridx + 1) % KQLEN) == 0) {
-+ oldq = q;
-+
-+ /* Mark next queue draining, may need to wait */
-+ c->qidx = (c->qidx + 1) % NUMKQ;
-+ q = &c->q[c->qidx];
-+ pthread_mutex_lock(&q->lock);
-+ while (q->qstate != KQFULL) {
-+ STATS_WAIT(c->stats);
-+ pthread_cond_wait(&q->cond, &q->lock);
-+ }
-+ q->qstate = KQDRAINING;
-+ pthread_mutex_unlock(&q->lock);
-+
-+ /* Mark consumed queue empty and signal producers */
-+ pthread_mutex_lock(&oldq->lock);
-+ oldq->qstate = KQEMPTY;
-+ STATS_DRAIN(c->stats);
-+ pthread_cond_broadcast(&oldq->cond);
-+ pthread_mutex_unlock(&oldq->lock);
-+ }
-+ }
-+ c->ridx = ridx;
-+ return (1);
-+}
-+
-+#define HAVE_NONE 0
-+#define HAVE_KEY 1
-+#define HAVE_IV 2
-+static int
-+ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
-+ int enc)
-+{
-+ struct ssh_aes_ctr_ctx *c;
-+ int i;
-+
-+ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-+ c = xmalloc(sizeof(*c));
-+
-+ c->state = HAVE_NONE;
-+ for (i = 0; i < NUMKQ; i++) {
-+ pthread_mutex_init(&c->q[i].lock, NULL);
-+ pthread_cond_init(&c->q[i].cond, NULL);
-+ }
-+
-+ STATS_INIT(c->stats);
-+
-+ EVP_CIPHER_CTX_set_app_data(ctx, c);
-+ }
-+
-+ if (c->state == (HAVE_KEY | HAVE_IV)) {
-+ /* Cancel pregen threads */
-+ for (i = 0; i < CIPHER_THREADS; i++)
-+ pthread_cancel(c->tid[i]);
-+ for (i = 0; i < CIPHER_THREADS; i++)
-+ pthread_join(c->tid[i], NULL);
-+ /* Start over getting key & iv */
-+ c->state = HAVE_NONE;
-+ }
-+
-+ if (key != NULL) {
-+ AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+ &c->aes_ctx);
-+ c->state |= HAVE_KEY;
-+ }
-+
-+ if (iv != NULL) {
-+ memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
-+ c->state |= HAVE_IV;
-+ }
-+
-+ if (c->state == (HAVE_KEY | HAVE_IV)) {
-+ /* Clear queues */
-+ memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
-+ c->q[0].qstate = KQINIT;
-+ for (i = 1; i < NUMKQ; i++) {
-+ memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
-+ ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
-+ c->q[i].qstate = KQEMPTY;
-+ }
-+ c->qidx = 0;
-+ c->ridx = 0;
-+
-+ /* Start threads */
-+ for (i = 0; i < CIPHER_THREADS; i++) {
-+ pthread_create(&c->tid[i], NULL, thread_loop, c);
-+ }
-+ pthread_mutex_lock(&c->q[0].lock);
-+ while (c->q[0].qstate != KQDRAINING)
-+ pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
-+ pthread_mutex_unlock(&c->q[0].lock);
-+
-+ }
-+ return (1);
-+}
-+
-+static int
-+ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
-+{
-+ struct ssh_aes_ctr_ctx *c;
-+ int i;
-+
-+ if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-+#ifdef CIPHER_THREAD_STATS
-+ debug("main thread: %u drains, %u waits", c->stats.drains,
-+ c->stats.waits);
-+#endif
-+ /* Cancel pregen threads */
-+ for (i = 0; i < CIPHER_THREADS; i++)
-+ pthread_cancel(c->tid[i]);
-+ for (i = 0; i < CIPHER_THREADS; i++)
-+ pthread_join(c->tid[i], NULL);
-+
-+ memset(c, 0, sizeof(*c));
-+ xfree(c);
-+ EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-+ }
-+ return (1);
-+}
-+
-+/* <friedl> */
-+const EVP_CIPHER *
-+evp_aes_ctr_mt(void)
-+{
-+ static EVP_CIPHER aes_ctr;
-+
-+ memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
-+ aes_ctr.nid = NID_undef;
-+ aes_ctr.block_size = AES_BLOCK_SIZE;
-+ aes_ctr.iv_len = AES_BLOCK_SIZE;
-+ aes_ctr.key_len = 16;
-+ aes_ctr.init = ssh_aes_ctr_init;
-+ aes_ctr.cleanup = ssh_aes_ctr_cleanup;
-+ aes_ctr.do_cipher = ssh_aes_ctr;
-+#ifndef SSH_OLD_EVP
-+ aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
-+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
-+#endif
-+ return (&aes_ctr);
-+}
-diff -NupwB ../4.7/openssh-4.7p1/clientloop.c openssh-4.7p1/clientloop.c
---- ../4.7/openssh-4.7p1/clientloop.c 2007-08-15 05:13:42.000000000 -0400
-+++ openssh-4.7p1/clientloop.c 2008-02-06 13:28:23.000000000 -0500
-@@ -910,13 +910,16 @@ client_process_control(fd_set *readset)
-
- set_nonblock(client_fd);
-
-+ if (options.hpn_disabled)
- window = CHAN_SES_WINDOW_DEFAULT;
-+ else
-+ window = options.hpn_buffer_size;
-+
- packetmax = CHAN_SES_PACKET_DEFAULT;
- if (cctx->want_tty) {
- window >>= 1;
- packetmax >>= 1;
- }
--
- c = channel_new("session", SSH_CHANNEL_OPENING,
- new_fd[0], new_fd[1], new_fd[2], window, packetmax,
- CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
-@@ -1018,7 +1021,8 @@ process_cmdline(void)
- if (local) {
- if (channel_setup_local_fwd_listener(fwd.listen_host,
- fwd.listen_port, fwd.connect_host,
-- fwd.connect_port, options.gateway_ports) < 0) {
-+ fwd.connect_port, options.gateway_ports,
-+ options.hpn_disabled, options.hpn_buffer_size) < 0) {
- logit("Port forwarding failed.");
- goto out;
- }
-@@ -1717,10 +1721,16 @@ client_request_forwarded_tcpip(const cha
- xfree(listen_address);
- return NULL;
- }
-+ if (options.hpn_disabled)
- c = channel_new("forwarded-tcpip",
- SSH_CHANNEL_CONNECTING, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
- originator_address, 1);
-+ else
-+ c = channel_new("forwarded-tcpip",
-+ SSH_CHANNEL_CONNECTING, sock, sock, -1,
-+ options.hpn_buffer_size, options.hpn_buffer_size, 0,
-+ originator_address, 1);
- xfree(originator_address);
- xfree(listen_address);
- return c;
-@@ -1754,9 +1764,15 @@ client_request_x11(const char *request_t
- sock = x11_connect_display();
- if (sock < 0)
- return NULL;
-+ /* again is this really necessary for X11? */
-+ if (options.hpn_disabled)
- c = channel_new("x11",
- SSH_CHANNEL_X11_OPEN, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
-+ else
-+ c = channel_new("x11",
-+ SSH_CHANNEL_X11_OPEN, sock, sock, -1,
-+ options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
- c->force_drain = 1;
- return c;
- }
-@@ -1775,10 +1791,17 @@ client_request_agent(const char *request
- sock = ssh_get_authentication_socket();
- if (sock < 0)
- return NULL;
-+ /* not sure this is really needed here either */
-+ if (options.hpn_disabled)
- c = channel_new("authentication agent connection",
- SSH_CHANNEL_OPEN, sock, sock, -1,
- CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
- "authentication agent connection", 1);
-+ else
-+ c = channel_new("authentication agent connection",
-+ SSH_CHANNEL_OPEN, sock, sock, -1,
-+ options.hpn_buffer_size, options.hpn_buffer_size, 0,
-+ "authentication agent connection", 1);
- c->force_drain = 1;
- return c;
- }
-@@ -1805,10 +1828,18 @@ client_request_tun_fwd(int tun_mode, int
- return -1;
- }
-
-+ if(options.hpn_disabled)
- c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
-- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
-+ CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
-+ 0, "tun", 1);
-+ else
-+ c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
-+ options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
-+ 0, "tun", 1);
- c->datagram = 1;
-
-+
-+
- #if defined(SSH_TUN_FILTER)
- if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
- channel_register_filter(c->self, sys_tun_infilter,
-diff -NupwB ../4.7/openssh-4.7p1/compat.c openssh-4.7p1/compat.c
---- ../4.7/openssh-4.7p1/compat.c 2007-01-05 00:26:46.000000000 -0500
-+++ openssh-4.7p1/compat.c 2008-02-06 13:28:23.000000000 -0500
-@@ -169,6 +169,15 @@ compat_datafellows(const char *version)
- strlen(check[i].pat), 0) == 1) {
- debug("match: %s pat %s", version, check[i].pat);
- datafellows = check[i].bugs;
-+ /* Check to see if the remote side is OpenSSH and not HPN */
-+ if(strstr(version,"OpenSSH") != NULL)
-+ {
-+ if (strstr(version,"hpn") == NULL)
-+ {
-+ datafellows |= SSH_BUG_LARGEWINDOW;
-+ debug("Remote is NON-HPN aware");
-+ }
-+ }
- return;
- }
- }
-diff -NupwB ../4.7/openssh-4.7p1/compat.h openssh-4.7p1/compat.h
---- ../4.7/openssh-4.7p1/compat.h 2007-01-05 00:26:46.000000000 -0500
-+++ openssh-4.7p1/compat.h 2008-02-06 13:28:23.000000000 -0500
-@@ -57,6 +57,7 @@
- #define SSH_BUG_FIRSTKEX 0x00800000
- #define SSH_OLD_FORWARD_ADDR 0x01000000
- #define SSH_BUG_RFWD_ADDR 0x02000000
-+#define SSH_BUG_LARGEWINDOW 0x04000000
-
- void enable_compat13(void);
- void enable_compat20(void);
-Common subdirectories: ../4.7/openssh-4.7p1/contrib and openssh-4.7p1/contrib
-diff -NupwB ../4.7/openssh-4.7p1/HPN12-README openssh-4.7p1/HPN12-README
---- ../4.7/openssh-4.7p1/HPN12-README 1969-12-31 19:00:00.000000000 -0500
-+++ openssh-4.7p1/HPN12-README 2008-02-06 13:28:23.000000000 -0500
-@@ -0,0 +1,111 @@
-+Notes:
-+
-+To use the NONE option you must have the NoneEnabled switch set on the server and
-+you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE
-+feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not
-+spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will
-+be disabled.
-+
-+The performance increase will only be as good as the network and TCP stack tuning
-+on the reciever side of the connection allows. As a rule of thumb a user will need
-+at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The
-+HPN-SSH home page describes this in greater detail.
-+
-+http://www.psc.edu/networking/projects/hpn-ssh
-+
-+Buffer Sizes:
-+
-+If HPN is disabled the receive buffer size will be set to the
-+OpenSSH default of 64K.
-+
-+If an HPN system connects to a nonHPN system the receive buffer will
-+be set to the HPNBufferSize value. The default is 2MB but user adjustable.
-+
-+If an HPN to HPN connection is established a number of different things might
-+happen based on the user options and conditions.
-+
-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
-+HPN Buffer Size = up to 64MB
-+This is the default state. The HPN buffer size will grow to a maximum of 64MB
-+as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is
-+geared towards 10GigE transcontinental connections.
-+
-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
-+HPN Buffer Size = TCP receive buffer value.
-+Users on non-autotuning systesm should disable TCPRcvBufPoll in the
-+ssh_cofig and sshd_config
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
-+HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize.
-+This would be the system defined TCP receive buffer (RWIN).
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
-+HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize.
-+Generally there is no need to set both.
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
-+HPN Buffer Size = grows to HPNBufferSize
-+The buffer will grow up to the maximum size specified here.
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET
-+HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize.
-+Generally there is no need to set both of these, especially on autotuning
-+systems. However, if the users wishes to override the autotuning this would be
-+one way to do it.
-+
-+Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET
-+HPN Buffer Size = TCPRcvBuf.
-+This will override autotuning and set the TCP recieve buffer to the user defined
-+value.
-+
-+
-+HPN Specific Configuration options
-+
-+TcpRcvBuf=[int]KB client
-+ set the TCP socket receive buffer to n Kilobytes. It can be set up to the
-+maximum socket size allowed by the system. This is useful in situations where
-+the tcp receive window is set low but the maximum buffer size is set
-+higher (as is typical). This works on a per TCP connection basis. You can also
-+use this to artifically limit the transfer rate of the connection. In these
-+cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB.
-+Default is the current system wide tcp receive buffer size.
-+
-+TcpRcvBufPoll=[yes/no] client/server
-+ enable of disable the polling of the tcp receive buffer through the life
-+of the connection. You would want to make sure that this option is enabled
-+for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista)
-+default is yes.
-+
-+NoneEnabled=[yes/no] client/server
-+ enable or disable the use of the None cipher. Care must always be used
-+when enabling this as it will allow users to send data in the clear. However,
-+it is important to note that authentication information remains encrypted
-+even if this option is enabled. Set to no by default.
-+
-+NoneSwitch=[yes/no] client
-+ Switch the encryption cipher being used to the None cipher after
-+authentication takes place. NoneEnabled must be enabled on both the client
-+and server side of the connection. When the connection switches to the NONE
-+cipher a warning is sent to STDERR. The connection attempt will fail with an
-+error if a client requests a NoneSwitch from the server that does not explicitly
-+have NoneEnabled set to yes. Note: The NONE cipher cannot be used in
-+interactive (shell) sessions and it will fail silently. Set to no by default.
-+
-+HPNDisabled=[yes/no] client/server
-+ In some situations, such as transfers on a local area network, the impact
-+of the HPN code produces a net decrease in performance. In these cases it is
-+helpful to disable the HPN functionality. By default HPNDisabled is set to no.
-+
-+HPNBufferSize=[int]KB client/server
-+ This is the default buffer size the HPN functionality uses when interacting
-+with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf
-+option as applied to the internal SSH flow control. This value can range from
-+1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance
-+problems depending on the length of the network path. The default size of this buffer
-+is 2MB.
-+
-+
-+Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu)
-+ The majority of the actual coding for versions up to HPN12v1 was performed
-+ by Michael Stevens (mstevens@andrew.cmu.edu). This work was financed, in part,
-+ by Cisco System, Inc., and the National Science Foundation.
-diff -NupwB ../4.7/openssh-4.7p1/kex.c openssh-4.7p1/kex.c
---- ../4.7/openssh-4.7p1/kex.c 2007-06-05 04:30:18.000000000 -0400
-+++ openssh-4.7p1/kex.c 2008-02-06 13:29:19.000000000 -0500
-@@ -48,6 +48,7 @@
- #include "match.h"
- #include "dispatch.h"
- #include "monitor.h"
-+#include "canohost.h"
-
- #define KEX_COOKIE_LEN 16
-
-@@ -64,7 +65,8 @@ static void kex_kexinit_finish(Kex *);
- static void kex_choose_conf(Kex *);
-
- /* put algorithm proposal into buffer */
--static void
-+/* used in sshconnect.c as well as kex.c */
-+void
- kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
- {
- u_int i;
-@@ -376,6 +378,13 @@ kex_choose_conf(Kex *kex)
- int nenc, nmac, ncomp;
- u_int mode, ctos, need;
- int first_kex_follows, type;
-+ int log_flag = 0;
-+
-+ int auth_flag;
-+
-+ auth_flag = packet_authentication_state();
-+
-+ debug ("AUTH STATE IS %d", auth_flag);
-
- my = kex_buf2prop(&kex->my, NULL);
- peer = kex_buf2prop(&kex->peer, &first_kex_follows);
-@@ -400,11 +409,34 @@ kex_choose_conf(Kex *kex)
- choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]);
- choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]);
- choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
-+ debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
-+ if (strcmp(newkeys->enc.name, "none") == 0) {
-+ debug("Requesting NONE. Authflag is %d", auth_flag);
-+ if (auth_flag == 1) {
-+ debug("None requested post authentication.");
-+ } else {
-+ fatal("Pre-authentication none cipher requests are not allowed.");
-+ }
-+ }
- debug("kex: %s %s %s %s",
- ctos ? "client->server" : "server->client",
- newkeys->enc.name,
- newkeys->mac.name,
- newkeys->comp.name);
-+ /* client starts withctos = 0 && log flag = 0 and no log*/
-+ /* 2nd client pass ctos=1 and flag = 1 so no log*/
-+ /* server starts with ctos =1 && log_flag = 0 so log */
-+ /* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
-+ /* -cjr*/
-+ if (ctos && !log_flag) {
-+ logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
-+ get_remote_ipaddr(),
-+ get_remote_port(),
-+ newkeys->enc.name,
-+ newkeys->mac.name,
-+ newkeys->comp.name);
-+ }
-+ log_flag = 1;
- }
- choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
- choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
-diff -NupwB ../4.7/openssh-4.7p1/kex.h openssh-4.7p1/kex.h
---- ../4.7/openssh-4.7p1/kex.h 2007-06-11 00:01:42.000000000 -0400
-+++ openssh-4.7p1/kex.h 2008-02-06 13:28:23.000000000 -0500
-@@ -127,6 +127,8 @@ struct Kex {
- void (*kex[KEX_MAX])(Kex *);
- };
-
-+void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
-+
- Kex *kex_setup(char *[PROPOSAL_MAX]);
- void kex_finish(Kex *);
-
-diff -NupwB ../4.7/openssh-4.7p1/Makefile.in openssh-4.7p1/Makefile.in
---- ../4.7/openssh-4.7p1/Makefile.in 2007-06-11 00:01:42.000000000 -0400
-+++ openssh-4.7p1/Makefile.in 2008-02-06 13:28:54.000000000 -0500
-@@ -43,7 +43,7 @@ CC=@CC@
- LD=@LD@
- CFLAGS=@CFLAGS@
- CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
--LIBS=@LIBS@
-+LIBS=@LIBS@ -lpthread
- SSHDLIBS=@SSHDLIBS@
- LIBEDIT=@LIBEDIT@
- AR=@AR@
-@@ -64,7 +64,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-a
-
- LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
- canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
-- cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
-+ cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \
- compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
- log.o match.o md-sha256.o moduli.o nchan.o packet.o \
- readpass.o rsa.o ttymodes.o xmalloc.o \
-diff -NupwB ../4.7/openssh-4.7p1/myproposal.h openssh-4.7p1/myproposal.h
---- ../4.7/openssh-4.7p1/myproposal.h 2007-06-11 00:01:42.000000000 -0400
-+++ openssh-4.7p1/myproposal.h 2008-02-06 13:28:23.000000000 -0500
-@@ -46,6 +46,8 @@
- "arcfour128,arcfour256,arcfour," \
- "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
- "aes128-ctr,aes192-ctr,aes256-ctr"
-+#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
-+ ",none"
- #define KEX_DEFAULT_MAC \
- "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
- "hmac-ripemd160@openssh.com," \
-Common subdirectories: ../4.7/openssh-4.7p1/openbsd-compat and openssh-4.7p1/openbsd-compat
-diff -NupwB ../4.7/openssh-4.7p1/packet.c openssh-4.7p1/packet.c
---- ../4.7/openssh-4.7p1/packet.c 2007-06-11 00:01:42.000000000 -0400
-+++ openssh-4.7p1/packet.c 2008-02-06 13:29:19.000000000 -0500
-@@ -710,7 +710,7 @@ packet_enable_delayed_compress(void)
- /*
- * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
- */
--static void
-+static int
- packet_send2_wrapped(void)
- {
- u_char type, *cp, *macbuf = NULL;
-@@ -822,11 +822,13 @@ packet_send2_wrapped(void)
- set_newkeys(MODE_OUT);
- else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
- packet_enable_delayed_compress();
-+ return(packet_length);
- }
-
--static void
-+static int
- packet_send2(void)
- {
-+ static int packet_length = 0;
- static int rekeying = 0;
- struct packet *p;
- u_char type, *cp;
-@@ -844,7 +846,7 @@ packet_send2(void)
- memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
- buffer_init(&outgoing_packet);
- TAILQ_INSERT_TAIL(&outgoing, p, next);
-- return;
-+ return(sizeof(Buffer));
- }
- }
-
-@@ -852,7 +854,7 @@ packet_send2(void)
- if (type == SSH2_MSG_KEXINIT)
- rekeying = 1;
-
-- packet_send2_wrapped();
-+ packet_length = packet_send2_wrapped();
-
- /* after a NEWKEYS message we can send the complete queue */
- if (type == SSH2_MSG_NEWKEYS) {
-@@ -865,19 +867,22 @@ packet_send2(void)
- sizeof(Buffer));
- TAILQ_REMOVE(&outgoing, p, next);
- xfree(p);
-- packet_send2_wrapped();
-+ packet_length += packet_send2_wrapped();
- }
- }
-+ return(packet_length);
- }
-
--void
-+int
- packet_send(void)
- {
-+ int packet_len = 0;
- if (compat20)
-- packet_send2();
-+ packet_len = packet_send2();
- else
- packet_send1();
- DBG(debug("packet_send done"));
-+ return(packet_len);
- }
-
- /*
-@@ -1415,21 +1420,23 @@ packet_disconnect(const char *fmt,...)
-
- /* Checks if there is any buffered output, and tries to write some of the output. */
-
--void
-+int
- packet_write_poll(void)
- {
-- int len = buffer_len(&output);
-+ int len = 0;
-+ len = buffer_len(&output);
-
- if (len > 0) {
- len = write(connection_out, buffer_ptr(&output), len);
- if (len <= 0) {
- if (errno == EAGAIN)
-- return;
-+ return (0);
- else
- fatal("Write failed: %.100s", strerror(errno));
- }
- buffer_consume(&output, len);
- }
-+ return(len);
- }
-
- /*
-@@ -1437,14 +1444,15 @@ packet_write_poll(void)
- * written.
- */
-
--void
-+int
- packet_write_wait(void)
- {
- fd_set *setp;
-+ u_int bytes_sent = 0;
-
- setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
- sizeof(fd_mask));
-- packet_write_poll();
-+ bytes_sent += packet_write_poll();
- while (packet_have_data_to_write()) {
- memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
- sizeof(fd_mask));
-@@ -1452,9 +1460,10 @@ packet_write_wait(void)
- while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&
- (errno == EAGAIN || errno == EINTR))
- ;
-- packet_write_poll();
-+ bytes_sent += packet_write_poll();
- }
- xfree(setp);
-+ return (bytes_sent);
- }
-
- /* Returns true if there is buffered data to write to the connection. */
-@@ -1576,12 +1585,24 @@ packet_send_ignore(int nbytes)
- }
- }
-
-+int rekey_requested = 0;
-+void
-+packet_request_rekeying(void)
-+{
-+ rekey_requested = 1;
-+}
-+
- #define MAX_PACKETS (1U<<31)
- int
- packet_need_rekeying(void)
- {
- if (datafellows & SSH_BUG_NOREKEY)
- return 0;
-+ if (rekey_requested == 1)
-+ {
-+ rekey_requested = 0;
-+ return 1;
-+ }
- return
- (p_send.packets > MAX_PACKETS) ||
- (p_read.packets > MAX_PACKETS) ||
-@@ -1606,3 +1627,9 @@ packet_set_authenticated(void)
- {
- after_authentication = 1;
- }
-+
-+int
-+packet_authentication_state(void)
-+{
-+ return(after_authentication);
-+}
-diff -NupwB ../4.7/openssh-4.7p1/packet.h openssh-4.7p1/packet.h
---- ../4.7/openssh-4.7p1/packet.h 2006-03-25 22:30:02.000000000 -0500
-+++ openssh-4.7p1/packet.h 2008-02-06 13:29:19.000000000 -0500
-@@ -20,6 +20,9 @@
-
- #include <openssl/bn.h>
-
-+void
-+packet_request_rekeying(void);
-+
- void packet_set_connection(int, int);
- void packet_set_nonblocking(void);
- int packet_get_connection_in(void);
-@@ -34,6 +37,7 @@ void packet_set_interactive(int);
- int packet_is_interactive(void);
- void packet_set_server(void);
- void packet_set_authenticated(void);
-+int packet_authentication_state(void);
-
- void packet_start(u_char);
- void packet_put_char(int ch);
-@@ -43,7 +47,7 @@ void packet_put_bignum2(BIGNUM * val
- void packet_put_string(const void *buf, u_int len);
- void packet_put_cstring(const char *str);
- void packet_put_raw(const void *buf, u_int len);
--void packet_send(void);
-+int packet_send(void);
-
- int packet_read(void);
- void packet_read_expect(int type);
-@@ -71,8 +75,8 @@ void packet_set_state(int, u_int32_t, u
- int packet_get_ssh1_cipher(void);
- void packet_set_iv(int, u_char *);
-
--void packet_write_poll(void);
--void packet_write_wait(void);
-+int packet_write_poll(void);
-+int packet_write_wait(void);
- int packet_have_data_to_write(void);
- int packet_not_very_much_data_to_write(void);
-
-diff -NupwB ../4.7/openssh-4.7p1/readconf.c openssh-4.7p1/readconf.c
---- ../4.7/openssh-4.7p1/readconf.c 2007-03-21 05:46:03.000000000 -0400
-+++ openssh-4.7p1/readconf.c 2008-02-06 13:28:23.000000000 -0500
-@@ -130,6 +130,8 @@ typedef enum {
- oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
- oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
- oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
-+ oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
-+ oHPNBufferSize,
- oDeprecated, oUnsupported
- } OpCodes;
-
-@@ -226,6 +228,12 @@ static struct {
- { "tunneldevice", oTunnelDevice },
- { "localcommand", oLocalCommand },
- { "permitlocalcommand", oPermitLocalCommand },
-+ { "noneenabled", oNoneEnabled },
-+ { "tcprcvbufpoll", oTcpRcvBufPoll },
-+ { "tcprcvbuf", oTcpRcvBuf },
-+ { "noneswitch", oNoneSwitch },
-+ { "hpndisabled", oHPNDisabled },
-+ { "hpnbuffersize", oHPNBufferSize },
- { NULL, oBadOption }
- };
-
-@@ -453,6 +461,37 @@ parse_flag:
- intptr = &options->check_host_ip;
- goto parse_flag;
-
-+ case oNoneEnabled:
-+ intptr = &options->none_enabled;
-+ goto parse_flag;
-+
-+ /* we check to see if the command comes from the */
-+ /* command line or not. If it does then enable it */
-+ /* otherwise fail. NONE should never be a default configuration */
-+ case oNoneSwitch:
-+ if(strcmp(filename,"command-line")==0)
-+ {
-+ intptr = &options->none_switch;
-+ goto parse_flag;
-+ } else {
-+ error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
-+ error("Continuing...");
-+ debug("NoneSwitch directive found in %.200s.", filename);
-+ return 0;
-+ }
-+
-+ case oHPNDisabled:
-+ intptr = &options->hpn_disabled;
-+ goto parse_flag;
-+
-+ case oHPNBufferSize:
-+ intptr = &options->hpn_buffer_size;
-+ goto parse_int;
-+
-+ case oTcpRcvBufPoll:
-+ intptr = &options->tcp_rcv_buf_poll;
-+ goto parse_flag;
-+
- case oVerifyHostKeyDNS:
- intptr = &options->verify_host_key_dns;
- goto parse_yesnoask;
-@@ -632,6 +671,10 @@ parse_int:
- intptr = &options->connection_attempts;
- goto parse_int;
-
-+ case oTcpRcvBuf:
-+ intptr = &options->tcp_rcv_buf;
-+ goto parse_int;
-+
- case oCipher:
- intptr = &options->cipher;
- arg = strdelim(&s);
-@@ -1065,6 +1108,12 @@ initialize_options(Options * options)
- options->tun_remote = -1;
- options->local_command = NULL;
- options->permit_local_command = -1;
-+ options->none_switch = -1;
-+ options->none_enabled = -1;
-+ options->hpn_disabled = -1;
-+ options->hpn_buffer_size = -1;
-+ options->tcp_rcv_buf_poll = -1;
-+ options->tcp_rcv_buf = -1;
- }
-
- /*
-@@ -1187,6 +1236,29 @@ fill_default_options(Options * options)
- options->server_alive_interval = 0;
- if (options->server_alive_count_max == -1)
- options->server_alive_count_max = 3;
-+ if (options->none_switch == -1)
-+ options->none_switch = 0;
-+ if (options->hpn_disabled == -1)
-+ options->hpn_disabled = 0;
-+ if (options->hpn_buffer_size > -1)
-+ {
-+ /* if a user tries to set the size to 0 set it to 1KB */
-+ if (options->hpn_buffer_size == 0)
-+ options->hpn_buffer_size = 1024;
-+ /*limit the buffer to 64MB*/
-+ if (options->hpn_buffer_size > 65536)
-+ {
-+ options->hpn_buffer_size = 65536*1024;
-+ debug("User requested buffer larger than 64MB. Request reverted to 64MB");
-+ }
-+ debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
-+ }
-+ if (options->tcp_rcv_buf == 0)
-+ options->tcp_rcv_buf = 1;
-+ if (options->tcp_rcv_buf > -1)
-+ options->tcp_rcv_buf *=1024;
-+ if (options->tcp_rcv_buf_poll == -1)
-+ options->tcp_rcv_buf_poll = 1;
- if (options->control_master == -1)
- options->control_master = 0;
- if (options->hash_known_hosts == -1)
-diff -NupwB ../4.7/openssh-4.7p1/readconf.h openssh-4.7p1/readconf.h
---- ../4.7/openssh-4.7p1/readconf.h 2006-08-04 22:39:40.000000000 -0400
-+++ openssh-4.7p1/readconf.h 2008-02-06 13:28:23.000000000 -0500
-@@ -56,6 +56,11 @@ typedef struct {
- int compression_level; /* Compression level 1 (fast) to 9
- * (best). */
- int tcp_keep_alive; /* Set SO_KEEPALIVE. */
-+ int tcp_rcv_buf; /* user switch to set tcp recv buffer */
-+ int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */
-+ int hpn_disabled; /* Switch to disable HPN buffer management */
-+ int hpn_buffer_size; /* User definable size for HPN buffer window */
-+
- LogLevel log_level; /* Level for logging. */
-
- int port; /* Port to connect. */
-@@ -101,6 +106,8 @@ typedef struct {
-
- int enable_ssh_keysign;
- int rekey_limit;
-+ int none_switch; /* Use none cipher */
-+ int none_enabled; /* Allow none to be used */
- int no_host_authentication_for_localhost;
- int identities_only;
- int server_alive_interval;
-Common subdirectories: ../4.7/openssh-4.7p1/regress and openssh-4.7p1/regress
-Common subdirectories: ../4.7/openssh-4.7p1/scard and openssh-4.7p1/scard
-diff -NupwB ../4.7/openssh-4.7p1/scp.c openssh-4.7p1/scp.c
---- ../4.7/openssh-4.7p1/scp.c 2007-08-08 00:29:58.000000000 -0400
-+++ openssh-4.7p1/scp.c 2008-02-06 13:28:23.000000000 -0500
-@@ -585,7 +585,7 @@ source(int argc, char **argv)
- off_t i, amt, statbytes;
- size_t result;
- int fd = -1, haderr, indx;
-- char *last, *name, buf[2048], encname[MAXPATHLEN];
-+ char *last, *name, buf[16384], encname[MAXPATHLEN];
- int len;
-
- for (indx = 0; indx < argc; ++indx) {
-@@ -645,7 +645,7 @@ syserr: run_err("%s: %s", name, strerr
- (void) atomicio(vwrite, remout, buf, strlen(buf));
- if (response() < 0)
- goto next;
-- if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
-+ if ((bp = allocbuf(&buffer, fd, sizeof(buf))) == NULL) {
- next: if (fd != -1) {
- (void) close(fd);
- fd = -1;
-@@ -813,7 +813,7 @@ sink(int argc, char **argv)
- mode_t mode, omode, mask;
- off_t size, statbytes;
- int setimes, targisdir, wrerrno = 0;
-- char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
-+ char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
- struct timeval tv[2];
-
- #define atime tv[0]
-@@ -974,7 +974,7 @@ bad: run_err("%s: %s", np, strerror(er
- continue;
- }
- (void) atomicio(vwrite, remout, "", 1);
-- if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) {
-+ if ((bp = allocbuf(&buffer, ofd, sizeof(buf))) == NULL) {
- (void) close(ofd);
- continue;
- }
-@@ -984,8 +984,8 @@ bad: run_err("%s: %s", np, strerror(er
- statbytes = 0;
- if (showprogress)
- start_progress_meter(curfile, size, &statbytes);
-- for (count = i = 0; i < size; i += 4096) {
-- amt = 4096;
-+ for (count = i = 0; i < size; i += sizeof(buf)) {
-+ amt = sizeof(buf);
- if (i + amt > size)
- amt = size - i;
- count += amt;
-@@ -1002,7 +1002,7 @@ bad: run_err("%s: %s", np, strerror(er
- } while (amt > 0);
-
- if (limit_rate)
-- bwlimit(4096);
-+ bwlimit(sizeof(buf));
-
- if (count == bp->cnt) {
- /* Keep reading so we stay sync'd up. */
-diff -NupwB ../4.7/openssh-4.7p1/servconf.c openssh-4.7p1/servconf.c
---- ../4.7/openssh-4.7p1/servconf.c 2007-05-20 01:03:16.000000000 -0400
-+++ openssh-4.7p1/servconf.c 2008-02-06 13:28:23.000000000 -0500
-@@ -122,11 +122,19 @@ initialize_server_options(ServerOptions
- options->permit_tun = -1;
- options->num_permitted_opens = -1;
- options->adm_forced_command = NULL;
-+ options->none_enabled = -1;
-+ options->tcp_rcv_buf_poll = -1;
-+ options->hpn_disabled = -1;
-+ options->hpn_buffer_size = -1;
- }
-
- void
- fill_default_server_options(ServerOptions *options)
- {
-+ int sock;
-+ int socksize;
-+ int socksizelen = sizeof(int);
-+
- /* Portable-specific options */
- if (options->use_pam == -1)
- options->use_pam = 0;
-@@ -250,6 +258,42 @@ fill_default_server_options(ServerOption
- if (options->permit_tun == -1)
- options->permit_tun = SSH_TUNMODE_NO;
-
-+ if (options->hpn_disabled == -1)
-+ options->hpn_disabled = 0;
-+
-+ if (options->hpn_buffer_size == -1) {
-+ /* option not explicitly set. Now we have to figure out */
-+ /* what value to use */
-+ if (options->hpn_disabled == 1) {
-+ options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
-+ } else {
-+ /* get the current RCV size and set it to that */
-+ /*create a socket but don't connect it */
-+ /* we use that the get the rcv socket size */
-+ sock = socket(AF_INET, SOCK_STREAM, 0);
-+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-+ &socksize, &socksizelen);
-+ close(sock);
-+ options->hpn_buffer_size = socksize;
-+ debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
-+
-+ }
-+ } else {
-+ /* we have to do this incase the user sets both values in a contradictory */
-+ /* manner. hpn_disabled overrrides hpn_buffer_size*/
-+ if (options->hpn_disabled <= 0) {
-+ if (options->hpn_buffer_size == 0)
-+ options->hpn_buffer_size = 1;
-+ /* limit the maximum buffer to 64MB */
-+ if (options->hpn_buffer_size > 64*1024) {
-+ options->hpn_buffer_size = 64*1024*1024;
-+ } else {
-+ options->hpn_buffer_size *= 1024;
-+ }
-+ } else
-+ options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
-+ }
-+
- /* Turn privilege separation on by default */
- if (use_privsep == -1)
- use_privsep = 1;
-@@ -292,7 +336,8 @@ typedef enum {
- sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
- sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
- sMatch, sPermitOpen, sForceCommand,
-- sUsePrivilegeSeparation,
-+ sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll,
-+ sHPNDisabled, sHPNBufferSize,
- sDeprecated, sUnsupported
- } ServerOpCodes;
-
-@@ -403,6 +448,10 @@ static struct {
- { "match", sMatch, SSHCFG_ALL },
- { "permitopen", sPermitOpen, SSHCFG_ALL },
- { "forcecommand", sForceCommand, SSHCFG_ALL },
-+ { "noneenabled", sNoneEnabled },
-+ { "hpndisabled", sHPNDisabled },
-+ { "hpnbuffersize", sHPNBufferSize },
-+ { "tcprcvbufpoll", sTcpRcvBufPoll },
- { NULL, sBadOption, 0 }
- };
-
-@@ -418,6 +467,7 @@ parse_token(const char *cp, const char *
-
- for (i = 0; keywords[i].name; i++)
- if (strcasecmp(cp, keywords[i].name) == 0) {
-+ debug ("Config token is %s", keywords[i].name);
- *flags = keywords[i].flags;
- return keywords[i].opcode;
- }
-@@ -827,6 +877,22 @@ parse_flag:
- *intptr = value;
- break;
-
-+ case sNoneEnabled:
-+ intptr = &options->none_enabled;
-+ goto parse_flag;
-+
-+ case sTcpRcvBufPoll:
-+ intptr = &options->tcp_rcv_buf_poll;
-+ goto parse_flag;
-+
-+ case sHPNDisabled:
-+ intptr = &options->hpn_disabled;
-+ goto parse_flag;
-+
-+ case sHPNBufferSize:
-+ intptr = &options->hpn_buffer_size;
-+ goto parse_int;
-+
- case sIgnoreUserKnownHosts:
- intptr = &options->ignore_user_known_hosts;
- goto parse_flag;
-diff -NupwB ../4.7/openssh-4.7p1/servconf.h openssh-4.7p1/servconf.h
---- ../4.7/openssh-4.7p1/servconf.h 2007-02-19 06:25:38.000000000 -0500
-+++ openssh-4.7p1/servconf.h 2008-02-06 13:28:23.000000000 -0500
-@@ -137,6 +137,10 @@ typedef struct {
- char *adm_forced_command;
-
- int use_pam; /* Enable auth via PAM */
-+ int none_enabled; /* enable NONE cipher switch */
-+ int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/
-+ int hpn_disabled; /* disable hpn functionality. false by default */
-+ int hpn_buffer_size; /* set the hpn buffer size - default 3MB */
-
- int permit_tun;
-
-diff -NupwB ../4.7/openssh-4.7p1/serverloop.c openssh-4.7p1/serverloop.c
---- ../4.7/openssh-4.7p1/serverloop.c 2007-01-28 18:16:28.000000000 -0500
-+++ openssh-4.7p1/serverloop.c 2008-02-06 13:29:19.000000000 -0500
-@@ -92,10 +92,10 @@ static int fdin; /* Descriptor for stdi
- static int fdout; /* Descriptor for stdout (for reading);
- May be same number as fdin. */
- static int fderr; /* Descriptor for stderr. May be -1. */
--static long stdin_bytes = 0; /* Number of bytes written to stdin. */
--static long stdout_bytes = 0; /* Number of stdout bytes sent to client. */
--static long stderr_bytes = 0; /* Number of stderr bytes sent to client. */
--static long fdout_bytes = 0; /* Number of stdout bytes read from program. */
-+static u_long stdin_bytes = 0; /* Number of bytes written to stdin. */
-+static u_long stdout_bytes = 0; /* Number of stdout bytes sent to client. */
-+static u_long stderr_bytes = 0; /* Number of stderr bytes sent to client. */
-+static u_long fdout_bytes = 0; /* Number of stdout bytes read from program. */
- static int stdin_eof = 0; /* EOF message received from client. */
- static int fdout_eof = 0; /* EOF encountered reading from fdout. */
- static int fderr_eof = 0; /* EOF encountered readung from fderr. */
-@@ -120,6 +120,20 @@ static volatile sig_atomic_t received_si
- static void server_init_dispatch(void);
-
- /*
-+ * Returns current time in seconds from Jan 1, 1970 with the maximum
-+ * available resolution.
-+ */
-+
-+static double
-+get_current_time(void)
-+{
-+ struct timeval tv;
-+ gettimeofday(&tv, NULL);
-+ return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
-+}
-+
-+
-+/*
- * we write to this pipe if a SIGCHLD is caught in order to avoid
- * the race between select() and child_terminated
- */
-@@ -408,6 +422,7 @@ process_input(fd_set *readset)
- } else {
- /* Buffer any received data. */
- packet_process_incoming(buf, len);
-+ fdout_bytes += len;
- }
- }
- if (compat20)
-@@ -430,6 +445,7 @@ process_input(fd_set *readset)
- } else {
- buffer_append(&stdout_buffer, buf, len);
- fdout_bytes += len;
-+ debug ("FD out now: %ld", fdout_bytes);
- }
- }
- /* Read and buffer any available stderr data from the program. */
-@@ -496,7 +512,7 @@ process_output(fd_set *writeset)
- }
- /* Send any buffered packet data to the client. */
- if (FD_ISSET(connection_out, writeset))
-- packet_write_poll();
-+ stdin_bytes += packet_write_poll();
- }
-
- /*
-@@ -813,8 +829,10 @@ server_loop2(Authctxt *authctxt)
- {
- fd_set *readset = NULL, *writeset = NULL;
- int rekeying = 0, max_fd, nalloc = 0;
-+ double start_time, total_time;
-
- debug("Entering interactive session for SSH2.");
-+ start_time = get_current_time();
-
- mysignal(SIGCHLD, sigchld_handler);
- child_terminated = 0;
-@@ -876,6 +894,11 @@ server_loop2(Authctxt *authctxt)
-
- /* free remaining sessions, e.g. remove wtmp entries */
- session_destroy_all(NULL);
-+ total_time = get_current_time() - start_time;
-+ logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
-+ get_remote_ipaddr(), get_remote_port(),
-+ stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time,
-+ fdout_bytes / total_time);
- }
-
- static void
-@@ -957,9 +980,14 @@ server_request_direct_tcpip(void)
- xfree(originator);
- if (sock < 0)
- return NULL;
-+ if (options.hpn_disabled)
- c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
- sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
- CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
-+ else
-+ c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
-+ sock, sock, -1, options.hpn_buffer_size,
-+ CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
- return c;
- }
-
-@@ -994,8 +1022,12 @@ server_request_tun(void)
- sock = tun_open(tun, mode);
- if (sock < 0)
- goto done;
-+ if (options.hpn_disabled)
- c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
-+ else
-+ c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
-+ options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
- c->datagram = 1;
- #if defined(SSH_TUN_FILTER)
- if (mode == SSH_TUNMODE_POINTOPOINT)
-@@ -1025,6 +1057,8 @@ server_request_session(void)
- c = channel_new("session", SSH_CHANNEL_LARVAL,
- -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
- 0, "server-session", 1);
-+ if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled))
-+ c->dynamic_window = 1;
- if (session_open(the_authctxt, c->self) != 1) {
- debug("session open failed, free channel %d", c->self);
- channel_free(c);
-@@ -1121,7 +1155,8 @@ server_input_global_request(int type, u_
- } else {
- /* Start listening on the port */
- success = channel_setup_remote_fwd_listener(
-- listen_address, listen_port, options.gateway_ports);
-+ listen_address, listen_port, options.gateway_ports,
-+ options.hpn_disabled, options.hpn_buffer_size);
- }
- xfree(listen_address);
- } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
-diff -NupwB ../4.7/openssh-4.7p1/session.c openssh-4.7p1/session.c
---- ../4.7/openssh-4.7p1/session.c 2007-08-16 09:28:04.000000000 -0400
-+++ openssh-4.7p1/session.c 2008-02-06 13:28:23.000000000 -0500
-@@ -211,6 +211,7 @@ auth_input_request_forwarding(struct pas
- packet_disconnect("listen: %.100s", strerror(errno));
-
- /* Allocate a channel for the authentication agent socket. */
-+ /* this shouldn't matter if its hpn or not - cjr */
- nc = channel_new("auth socket",
- SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
- CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
-@@ -348,7 +349,8 @@ do_authenticated1(Authctxt *authctxt)
- }
- debug("Received TCP/IP port forwarding request.");
- if (channel_input_port_forward_request(s->pw->pw_uid == 0,
-- options.gateway_ports) < 0) {
-+ options.gateway_ports, options.hpn_disabled,
-+ options.hpn_buffer_size) < 0) {
- debug("Port forwarding failed.");
- break;
- }
-@@ -2058,11 +2060,18 @@ session_set_fds(Session *s, int fdin, in
- */
- if (s->chanid == -1)
- fatal("no channel for session %d", s->self);
-+ if(options.hpn_disabled)
- channel_set_fds(s->chanid,
- fdout, fdin, fderr,
- fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
- 1,
- CHAN_SES_WINDOW_DEFAULT);
-+ else
-+ channel_set_fds(s->chanid,
-+ fdout, fdin, fderr,
-+ fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
-+ 1,
-+ options.hpn_buffer_size);
- }
-
- /*
-@@ -2407,7 +2416,8 @@ session_setup_x11fwd(Session *s)
- }
- if (x11_create_display_inet(options.x11_display_offset,
- options.x11_use_localhost, s->single_connection,
-- &s->display_number, &s->x11_chanids) == -1) {
-+ &s->display_number, &s->x11_chanids,
-+ options.hpn_disabled, options.hpn_buffer_size) == -1) {
- debug("x11_create_display_inet failed.");
- return 0;
- }
-diff -NupwB ../4.7/openssh-4.7p1/ssh.c openssh-4.7p1/ssh.c
---- ../4.7/openssh-4.7p1/ssh.c 2007-08-08 00:32:41.000000000 -0400
-+++ openssh-4.7p1/ssh.c 2008-02-06 13:28:23.000000000 -0500
-@@ -502,9 +502,6 @@ main(int ac, char **av)
- no_shell_flag = 1;
- no_tty_flag = 1;
- break;
-- case 'T':
-- no_tty_flag = 1;
-- break;
- case 'o':
- dummy = 1;
- line = xstrdup(optarg);
-@@ -513,6 +510,13 @@ main(int ac, char **av)
- exit(255);
- xfree(line);
- break;
-+ case 'T':
-+ no_tty_flag = 1;
-+ /* ensure that the user doesn't try to backdoor a */
-+ /* null cipher switch on an interactive session */
-+ /* so explicitly disable it no matter what */
-+ options.none_switch=0;
-+ break;
- case 's':
- subsystem_flag = 1;
- break;
-@@ -829,7 +833,8 @@ ssh_init_forwarding(void)
- options.local_forwards[i].listen_port,
- options.local_forwards[i].connect_host,
- options.local_forwards[i].connect_port,
-- options.gateway_ports);
-+ options.gateway_ports, options.hpn_disabled,
-+ options.hpn_buffer_size);
- }
- if (i > 0 && success != i && options.exit_on_forward_failure)
- fatal("Could not request local forwarding.");
-@@ -1142,6 +1147,9 @@ ssh_session2_open(void)
- {
- Channel *c;
- int window, packetmax, in, out, err;
-+ int sock;
-+ int socksize;
-+ int socksizelen = sizeof(int);
-
- if (stdin_null_flag) {
- in = open(_PATH_DEVNULL, O_RDONLY);
-@@ -1162,9 +1170,70 @@ ssh_session2_open(void)
- if (!isatty(err))
- set_nonblock(err);
-
-- window = CHAN_SES_WINDOW_DEFAULT;
-+ /* we need to check to see if what they want to do about buffer */
-+ /* sizes here. In a hpn to nonhpn connection we want to limit */
-+ /* the window size to something reasonable in case the far side */
-+ /* has the large window bug. In hpn to hpn connection we want to */
-+ /* use the max window size but allow the user to override it */
-+ /* lastly if they disabled hpn then use the ssh std window size */
-+
-+ /* so why don't we just do a getsockopt() here and set the */
-+ /* ssh window to that? In the case of a autotuning receive */
-+ /* window the window would get stuck at the initial buffer */
-+ /* size generally less than 96k. Therefore we need to set the */
-+ /* maximum ssh window size to the maximum hpn buffer size */
-+ /* unless the user has specifically set the tcprcvbufpoll */
-+ /* to no. In which case we *can* just set the window to the */
-+ /* minimum of the hpn buffer size and tcp receive buffer size */
-+
-+ if(options.hpn_disabled)
-+ {
-+ options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
-+ }
-+ else if (datafellows & SSH_BUG_LARGEWINDOW)
-+ {
-+ debug("HPN to Non-HPN Connection");
-+ if (options.hpn_buffer_size < 0)
-+ options.hpn_buffer_size = 2*1024*1024;
-+ }
-+ else
-+ {
-+ if (options.hpn_buffer_size < 0)
-+ options.hpn_buffer_size = BUFFER_MAX_LEN_HPN;
-+
-+ /*create a socket but don't connect it */
-+ /* we use that the get the rcv socket size */
-+ sock = socket(AF_INET, SOCK_STREAM, 0);
-+ /* if they are using the tcp_rcv_buf option */
-+ /* attempt to set the buffer size to that */
-+ if (options.tcp_rcv_buf)
-+ setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf,
-+ sizeof(options.tcp_rcv_buf));
-+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-+ &socksize, &socksizelen);
-+ close(sock);
-+ debug("socksize %d", socksize);
-+ if (options.tcp_rcv_buf_poll <= 0)
-+ {
-+ options.hpn_buffer_size = MIN(socksize,options.hpn_buffer_size);
-+ debug ("MIN of TCP RWIN and HPNBufferSize: %d", options.hpn_buffer_size);
-+ }
-+ else
-+ {
-+ if (options.tcp_rcv_buf > 0)
-+ options.hpn_buffer_size = MIN(options.tcp_rcv_buf, options.hpn_buffer_size);
-+ debug ("MIN of TCPRcvBuf and HPNBufferSize: %d", options.hpn_buffer_size);
-+ }
-+
-+ }
-+
-+ debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
-+
-+ window = options.hpn_buffer_size;
-+
- packetmax = CHAN_SES_PACKET_DEFAULT;
- if (tty_flag) {
-+ window = 4*CHAN_SES_PACKET_DEFAULT;
- window >>= 1;
- packetmax >>= 1;
- }
-@@ -1172,7 +1241,10 @@ ssh_session2_open(void)
- "session", SSH_CHANNEL_OPENING, in, out, err,
- window, packetmax, CHAN_EXTENDED_WRITE,
- "client-session", /*nonblock*/0);
--
-+ if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
-+ c->dynamic_window = 1;
-+ debug ("Enabled Dynamic Window Scaling\n");
-+ }
- debug3("ssh_session2_open: channel_new: %d", c->self);
-
- channel_send_open(c->self);
-diff -NupwB ../4.7/openssh-4.7p1/sshconnect2.c openssh-4.7p1/sshconnect2.c
---- ../4.7/openssh-4.7p1/sshconnect2.c 2007-05-20 01:11:33.000000000 -0400
-+++ openssh-4.7p1/sshconnect2.c 2008-02-06 13:28:23.000000000 -0500
-@@ -73,6 +73,12 @@
- extern char *client_version_string;
- extern char *server_version_string;
- extern Options options;
-+extern Kex *xxx_kex;
-+
-+/* tty_flag is set in ssh.c. use this in ssh_userauth2 */
-+/* if it is set then prevent the switch to the null cipher */
-+
-+extern int tty_flag;
-
- /*
- * SSH2 key exchange
-@@ -326,6 +332,28 @@ ssh_userauth2(const char *local_user, co
- pubkey_cleanup(&authctxt);
- dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
-
-+ /* if the user wants to use the none cipher do it */
-+ /* post authentication and only if the right conditions are met */
-+ /* both of the NONE commands must be true and there must be no */
-+ /* tty allocated */
-+ if ((options.none_switch == 1) && (options.none_enabled == 1))
-+ {
-+ if (!tty_flag) /* no null on tty sessions */
-+ {
-+ debug("Requesting none rekeying...");
-+ myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
-+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
-+ kex_prop2buf(&xxx_kex->my,myproposal);
-+ packet_request_rekeying();
-+ fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n");
-+ }
-+ else
-+ {
-+ /* requested NONE cipher when in a tty */
-+ debug("Cannot switch to NONE cipher with tty allocated");
-+ fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n");
-+ }
-+ }
- debug("Authentication succeeded (%s).", authctxt.method->name);
- }
-
-diff -NupwB ../4.7/openssh-4.7p1/sshconnect.c openssh-4.7p1/sshconnect.c
---- ../4.7/openssh-4.7p1/sshconnect.c 2006-10-23 13:02:24.000000000 -0400
-+++ openssh-4.7p1/sshconnect.c 2008-02-06 13:28:23.000000000 -0500
-@@ -164,6 +164,31 @@ ssh_proxy_connect(const char *host, u_sh
- }
-
- /*
-+ * Set TCP receive buffer if requested.
-+ * Note: tuning needs to happen after the socket is
-+ * created but before the connection happens
-+ * so winscale is negotiated properly -cjr
-+ */
-+static void
-+ssh_set_socket_recvbuf(int sock)
-+{
-+ void *buf = (void *)&options.tcp_rcv_buf;
-+ int sz = sizeof(options.tcp_rcv_buf);
-+ int socksize;
-+ int socksizelen = sizeof(int);
-+
-+ debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf);
-+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
-+ getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen);
-+ debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize);
-+ }
-+ else
-+ error("Couldn't set socket receive buffer to %d: %.100s",
-+ options.tcp_rcv_buf, strerror(errno));
-+}
-+
-+
-+/*
- * Creates a (possibly privileged) socket for use as the ssh connection.
- */
- static int
-@@ -186,12 +211,18 @@ ssh_create_socket(int privileged, struct
- strerror(errno));
- else
- debug("Allocated local port %d.", p);
-+
-+ if (options.tcp_rcv_buf > 0)
-+ ssh_set_socket_recvbuf(sock);
- return sock;
- }
- sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (sock < 0)
- error("socket: %.100s", strerror(errno));
-
-+ if (options.tcp_rcv_buf > 0)
-+ ssh_set_socket_recvbuf(sock);
-+
- /* Bind the socket to an alternative local IP address */
- if (options.bind_address == NULL)
- return sock;
-@@ -487,7 +518,7 @@ ssh_exchange_identification(void)
- snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
- compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
- compat20 ? PROTOCOL_MINOR_2 : minor1,
-- SSH_VERSION);
-+ SSH_RELEASE);
- if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
- fatal("write: %.100s", strerror(errno));
- client_version_string = xstrdup(buf);
-diff -NupwB ../4.7/openssh-4.7p1/sshd.c openssh-4.7p1/sshd.c
---- ../4.7/openssh-4.7p1/sshd.c 2007-06-05 04:22:32.000000000 -0400
-+++ openssh-4.7p1/sshd.c 2008-02-06 13:29:19.000000000 -0500
-@@ -134,6 +134,9 @@ int deny_severity = LOG_WARNING;
- #define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3)
- #define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4)
-
-+int myflag = 0;
-+
-+
- extern char *__progname;
-
- /* Server configuration options. */
-@@ -419,7 +422,7 @@ sshd_exchange_identification(int sock_in
- major = PROTOCOL_MAJOR_1;
- minor = PROTOCOL_MINOR_1;
- }
-- snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
-+ snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE);
- server_version_string = xstrdup(buf);
-
- /* Send our protocol version identification. */
-@@ -470,6 +473,9 @@ sshd_exchange_identification(int sock_in
- }
- debug("Client protocol version %d.%d; client software version %.100s",
- remote_major, remote_minor, remote_version);
-+ logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
-+ get_remote_ipaddr(), get_remote_port(),
-+ remote_major, remote_minor, remote_version);
-
- compat_datafellows(remote_version);
-
-@@ -942,6 +948,8 @@ server_listen(void)
- int ret, listen_sock, on = 1;
- struct addrinfo *ai;
- char ntop[NI_MAXHOST], strport[NI_MAXSERV];
-+ int socksize;
-+ int socksizelen = sizeof(int);
-
- for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
- if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
-@@ -979,6 +987,11 @@ server_listen(void)
-
- debug("Bind to port %s on %s.", strport, ntop);
-
-+ getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF,
-+ &socksize, &socksizelen);
-+ debug("Server TCP RWIN socket size: %d", socksize);
-+ debug("HPN Buffer Size: %d", options.hpn_buffer_size);
-+
- /* Bind the socket to the desired port. */
- if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
- error("Bind to port %s on %s failed: %.200s.",
-@@ -2094,9 +2107,15 @@ do_ssh2_kex(void)
- {
- Kex *kex;
-
-+ myflag++;
-+ debug ("MYFLAG IS %d", myflag);
- if (options.ciphers != NULL) {
- myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
-+ } else if (options.none_enabled == 1) {
-+ debug ("WARNING: None cipher enabled");
-+ myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
- }
- myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
-diff -NupwB ../4.7/openssh-4.7p1/sshd_config openssh-4.7p1/sshd_config
---- ../4.7/openssh-4.7p1/sshd_config 2007-03-21 05:42:25.000000000 -0400
-+++ openssh-4.7p1/sshd_config 2008-02-06 13:28:23.000000000 -0500
-@@ -109,6 +109,20 @@ Protocol 2
- # override default of no subsystems
- Subsystem sftp /usr/libexec/sftp-server
-
-+# the following are HPN related configuration options
-+# tcp receive buffer polling. disable in non autotuning kernels
-+#TcpRcvBufPoll yes
-+
-+# allow the use of the none cipher
-+#NoneEnabled no
-+
-+# disable hpn performance boosts.
-+#HPNDisabled no
-+
-+# buffer size for hpn to non-hpn connections
-+#HPNBufferSize 2048
-+
-+
- # Example of overriding settings on a per-user basis
- #Match User anoncvs
- # X11Forwarding no
-diff -NupwB ../4.7/openssh-4.7p1/version.h openssh-4.7p1/version.h
---- ../4.7/openssh-4.7p1/version.h 2007-08-15 05:14:52.000000000 -0400
-+++ openssh-4.7p1/version.h 2008-02-06 15:31:47.000000000 -0500
-@@ -3,4 +3,5 @@
- #define SSH_VERSION "OpenSSH_4.7"
-
- #define SSH_PORTABLE "p1"
--#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
-+#define SSH_HPN "-hpn13v1"
-+#define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN
+++ /dev/null
-#%PAM-1.0
-auth required pam_listfile.so item=user sense=deny file=/etc/security/blacklist.passwd onerr=succeed
-auth include system-auth
-account include system-auth
-password include system-auth