proxy.exe - Proxy Server Utility Program for Windows ==================================================== This file: proxy.txt Author: Dave Edwards Original date: Aug 4, 2006 Last updated: Jul 18, 2007 (c) Copyright Dave Edwards, 2006 - 2008. All rights reserved. NOTICE: This software is provided on an "as is" basis, without any support or warranty. If you choose to use it, you do so at your own risk. The author is not responsible for any expenses, damages, loss of data, etc. that may occur from use of this software. Web home page: http://canpub.com/teammpg/de/proxyde1 1. Introduction and overview 2. Specifics of this proxy program 3. Command-line operands 4. Parameter file statements 5. Examples 6. Tunnelling protocol - - - - - 1. Introduction and Overview ---------------------------- proxy.exe is a freeware program for Windows, written by Dave Edwards. There is no charge for personal, non-commercial use. The program is (c) Copyright by Dave Edwards. All rights reserved. It acts as a proxy server, also known as a TCP/IP port forwarder program. A proxy server is an intermediary between a TCP/IP client program and the corresponding TCP/IP server program. Instead of connecting directly to the server, the client connects instead to the proxy, which then connects to the server. The proxy reads TCP/IP socket data from the client and writes it to the server, and at the same time reads data from the server and writes it to the client. In most cases, the proxy does not alter the data. The proxy is transparent (invisible) to the client and server programs, except that performance may be decreased slightly and they may have to be configured to use different TCP/IP port numbers and host names or IP addresses. It's also possible to have a chain of 2 or more proxies between the client and server. client ------> proxy ------> server or: client -----> proxy 1 -----> proxy 2 -----> server So, if the proxy is transparent, why use one? The answer is that, since the proxy sees all the data passing between the client and server, it can provide some "value-added" services. For example, it can display the data. It can filter incoming connections from clients, based on IP address, allowing some addresses and rejecting others (similar to a basic firewall). If 2 proxies are used, one on the client side and one on the server side, they can authenticate each other and encrypt all data passing between the client and server, thus establishing a secure "tunnel" between them. This tunnel protects the data from being viewed or modified by any software or hardware in the TCP/IP path between the two proxies. This is important for protecting usernames, passwords, and other confidential data. Proxy tunnelling is used most often for telnet (or tn3270 or tn5250) connections, but works with most client/server connections. It does not work with the FTP file transfer protocol, because FTP uses a separate data connection which is negotiated for each file transfer; you can log in with FTP, but file transfer and directory listings do not work when using the proxy. However, if you use Passive Mode (PASV) and can configure the FTP server to use a small number of specific listening port numbers for the data connections, it's possible to use Proxy-DE to secure FTP, encrypting both the control and data traffic. For details see http://canpub.com/teammpg/de/mcgweb/securftp.txt Another possibility is for the proxy to act as a web (HTTP) proxy: HTTP requests from a web browser (the client) are passed to the proxy, which modifies the request header and passes the request on to the appropriate web server. In this way, the web proxy can provide Internet connection sharing for web browsing on machines in a local network. Machines on the local network pass their web requests to a web proxy running on one machine which has a connection to the Internet, allowing the machines to share that one connection. If the web proxy is smart enough, it can even handle SSL (https) web requests. All these proxy services can be done without having to modify the source of the client and server programs. Only their configuration (port numbers, etc.) may have to be changed. In most cases, you only have to configure the client to use a different port number and host name to connect to: tell it to connect to the port number and host name (usually localhost or 127.0.0.1) of the proxy, instead of the port number and host name of the server. You do not have to change the server configuration. This makes it possible to display socket data, use an encrypted tunnel, etc., even when using clients and servers for which you do not have source code. Therefore the proxy can be a valuable software tool. 2. Specifics of this proxy program ---------------------------------- This proxy.exe runs under Windows (98, NT, 2000, XP, and later versions), as a Console application (text-mode command-line program) in a Command window. You start it by entering the proxy command in Start --> Run or at the command prompt in a Command window. You can open a new Command window by Start --> Programs --> Accessories --> Command Prompt, or by Start --> Run and entering cmd.exe (for Win 2000 and Win XP) or command.com (for Win 95 and Win 98). To make it accessible, copy the proxy.exe file to one of the directories in your execution path. The program uses Winsock 2.2, therefore it does not run on the original Windows 95. If you need a version for Win 95, please contact the author - see the contact info on the home page. Unlike some other proxy programs for Windows, this program is completely self-contained and does not require any other software components to be installed. Installation is very easy - just download the .exe file and copy it to a directory in your execution path. The command to start the program is: proxy options listenport connectsite connectport Example: proxy -t 2001 server.somesite.com 23 In the example command, clients connect to port 2001 on this machine, and the proxy (which listens for incoming connections on port 2001) connects to port 23 of site server.somesite.com. The site to connect to can be specified as a host name or an IP address (dotted decimal form). The -t option tells the proxy to display data passing between the client and server. The options and other parameters are described in detail in the next section. To get a short description of the command operands, enter the proxy command without any operands. The specifics of this proxy program are: - It is freeware (no charge for personal, noncommercial use). (If you wish to use it in a commercial, educational, institutional, or governmental environment, please contact the author - see the contact info on the home page.) The program is (c) Copyright by Dave Edwards. All rights reserved. - No source code is provided. - NOTICE: This software is provided on an "as is" basis, without any support or warranty. If you choose to use it, you do so at your own risk. The author is not responsible for any expenses, damages, loss of data, etc. that may occur from use of this software. - Each instance of the program accepts up to 40 simultaneous client connections (unless the -1 option is used). For each client connection, the proxy program establishes a corresponding connection to the server. Therefore there may be up to 40 pairs of connections at any given time, each identified by an id number from 1 to 40. The id number, followed by ":", appears at the beginning of most console messages, to indicate which client connection the message refers to. In messages, "conn 1" refers to the proxy's TCP/IP connection to the client, and "conn 2" refers to its connection to the server. - The program can be manually terminated by typing Ctrl+C (or Ctrl+Break on some systems). If the -1 (single incoming connection) is used, the program automatically terminates when that connection ends. Otherwise it runs indefinitely, in order to accept new incoming connections from clients. Another way to terminate the proxy is just to close its Command window. - The -t option can be used to display socket data passing through the proxy. Data is displayed in hex, EBCDIC, and Ascii. (IBM mainframes use the EBCDIC character set, rather than Ascii, and the EBCDIC display is useful for tn3270 and tn5250 telnet connections.) When tunnelling is used (see below), the unencrypted data is displayed. - The -d option can be used to cause additional debugging info to be displayed by the proxy, at various levels. This is useful to see more details of the internal workings of the proxy. - There is a problem when output is directed to a file (by > filename at the end of the command): if the program is terminated manually by Ctrl+C or Ctrl+Break, the output file MAY be empty. You can get around this by using the -1 option, or (if the output is small) let the output go to the screen then copy it later. Another solution is to open the output file in Notepad while the program is still running, which gives you most of the output (except possibly for the last few lines), and save it to another file. You can avoid losing the data you want by opening a dummy connection (to cause more output) before terminating the program. Directing the output to a file is useful for debugging, when you want to see all the TCP/IP traffic and the amount of data is large. For example: proxy -buf=4096 -t=4096 3000 localhost 23 > c:\temp1\proxy_log.txt - The command option -f=filespec can be used to specify a parameter file, which contains statements for defining IP filtering, tunnelling, and other options that are too lengthy to be specified on the command. The parameter file is described in a later section. - Incoming connections from clients can be filtered by IP address. This means that connections from some client IP addresses are accepted, while others are rejected. The default is to allow all clients. - When 2 proxies are used (one on the client side and one on the server side), tunnelling can be specified by tunnel statements in the parameter file. This causes the 2 proxies to authenticate each other, using a username and a shared secret (a password or pass phrase), and to encrypt the socket data passing between them: client ---> client-side ==============> server-side ---> server proxy encrypted proxy tunnel The authentication and encryption protocol used is believed to be secure and "strong". It uses recognized security algorithms such as Triple-DES and RC4 encryption, HMAC-SHA1 (keyed Message Authentication Code using the SHA1 digest algorithm) for check sums, and RFC 2898 (PKCS#5 ver.2) for derivation of session keys using a high iteration count. When RC4 is used for encryption, the first 256 bytes of the RC4 stream are discarded, for better security. Tunnel usernames and secrets can be entered by prompting at execution time, to avoid having to store them in a parameter file. - When tunnelling is used, the proxy program updates two small files sysrand1.bin and sysrand2.bin in the root directory of the C: drive. The files are created if they do not exist. Their purpose is to store state information that is used to increase the entropy (amount of random input) when generating random session keys. - When the -w option is used, the proxy program acts as a basic web (HTTP) proxy server. HTTP requests from the client (normally a web browser that has been configured to use a proxy) are passed on to the server. This proxy does not modify or cache the HTTP requests. It supports https (secure) requests (via the CONNECT method from the client), which allows SSL (secure web traffic) to pass through the proxy. *** NOTE: The -w option is not fully implemented. - To make sure you have a valid copy of the program, verify the proxy.exe file's MD5 or SHA1 check sum after download, with the check sums given in the readme file. - The web home page for this proxy program is: http://canpub.com/teammpg/de/proxyde1 - There is a Yahoo discussion group, Proxy-DE, for this program. Go to http://groups.yahoo.com/group/Proxy-DE where you can read messages posted by users and announcements of updates. To post messages or access the Files area, you have to join the group, by clicking on "Join This Group!" near the top of the Home page for the group. The group's moderator has to approve new members (to help prevent spam), so it may take a day or so for your membership to take effect. 3. Command-line operands ------------------------ Usage: proxy options listenport connsite connport options Options start with the "-" character, may appear in any order, and may be interspersed with the other operands. Options cannot be combined: for example -dt is not valid. -1 (Single use) Specifies that the proxy will accept only 1 connection on the listen port number. After that, the listening socket is closed. When either connection (1) (between the client and the proxy) or connection (2) (between the proxy and the server) ends, the proxy program terminates. Without this option, the proxy program acts as a continuing server, accepting multiple incoming connections on the listen port. A new entry in the Server Table is created for each accepted connection. Each table entry represents a pair of connections (1) and (2). The maximum number of table entries is 40. -b=n.n.n.n -b=domainname -b=any -b=localhost Specifies the IP address (TCP/IP interface address) on which incoming connections are accepted. This IP address, along with the listen port number, is used in the socket bind() call that is done when the proxy program starts. -b=any means the same as -b=0.0.0.0 and accepts connections on any interface (if not disallowed by IP address filtering). -b=any is the default. The specified IP address must be a valid interface address for the machine (or 0.0.0.0). For example, if you want the proxy to accept connections only from the local machine, specify: -b=localhost or -b=127.0.0.1 If you are running the proxy on the same machine as the client, it is recommended to use -b=localhost, to block use of the proxy by other machines, for security reasons. -buf=n Buffer size n (number of bytes) to be used for socket reads and writes. Default: -buf=8192 Each pair of connections (1) and (2) uses 2 buffers of that size, allocated dynamically. Therefore, for each entry in the Server Table, 2n bytes are allocated for socket buffers. Depending on the client and server applications, adjusting n up or down MAY increase performance. If n is less than 512, 512 is automatically used. Maximum n is 200000. Note: If encryption (tunnelling) is involved, n limits the size of the encrypted socket message, which is longer than the plain-text message because of header, HMAC, and round-up overhead. Also, n must be big enough to allow for the encryption options used (minmsglen, msglenmult). See the section below on the parameter file. -d -d=n (Debug) Specifies the debugging level n. Higher n gives more output. Default is 0 (no debug). -d implies 1. Currently the highest level is 5 (-d=5), but higher levels may be added in future versions. Debug levels greater than 0 (especially -d=2 and -d=3) are useful for seeing the internal workings of the program. -f=filespec Specifies a text file from which additional parameter info is read. Records in the file can specify things such as client IP addresses from which incoming connections are to be allowed or denied (IP address filtering), and parameters for encrypting the data on connection (1) and/or (2) and doing authentication of two proxy programs to each other (referred to as "tunnelling"). For a description of the statements that can be used in a parameter file, see the section below. -t -t=n (Trace) Requests that incoming data on each of the the connections be displayed. For each socket read operation, the first n bytes of data read is displayed in hex, EBCDIC, and Ascii. Default is no tracing. Default n is 512. If tunnelling is in effect, it is the decrypted data that is displayed. This tracing does not apply to the initial authentication messages used for tunnelling. This option is very useful for seeing the data passing between a client and server. -v Displays version number and copyright info. -w (Web) Specifies that the proxy program should act as a basic web proxy server. Then a web browser can specify the proxy (the machine the proxy is running on and the listen port number) in its configuration. HTTP requests from the browser are then sent to the proxy, which passes the request on to the actual web server. In this mode, the proxy program acts as a basic web proxy. It does not cache pages or modify HTTP header records or HTTP entity data. SSL (https) is supported by handling the CONNECT method request from the browser. When the -w option is used, the connsite and connport parameters are ignored and can be omitted, since that information is obtained from the browser's HTTP request. *** Note: The -w option is not fully implemented yet. It will be supported in a future version. listenport The port number on which the proxy listens for incoming connections. A connection request comes from a client program (or from another proxy between the client and this proxy). If accepted, it establishes TCP/IP connection (1); the proxy then establishes connection (2) to the specified server. See also the -b option. The port number must be a 1- to 5-digit number with value from 1 to 65535. connsite The site (a domain name or an IP address in dotted decimal n.n.n.n form) to which the proxy connects (connection (2)), after accepting an incoming connection (1). Connection (2) is with the server (or with another proxy between this proxy and the server). If the server (or other proxy) is on the same machine as this proxy, you can specify localhost or 127.0.0.1 for connsite. If the -w option is used, this operand is ignored and can be omitted. connport The port number to which the proxy connects for connection (2). If the -w option is used, this operand is ignored and can be omitted (if connsite is also omitted). The port number must be a 1- to 5-digit number with value from 1 to 65535. 4. Parameter file statements ---------------------------- This section describes the statements that can be used in a parameter file. The name (which may include a drive letter and path) of the file is specified in the -f=filespec option on the proxy command, if a parameter file is needed. A parameter file is needed in order to specify IP address filtering and use of tunnelling. Tunnelling refers to authentication of one proxy to another, and encryption of the data passing between them. See the discussion in the introduction section above. When tunnelling is used, one of the proxies runs on the client side (the client end of the tunnel, usually on the same machine as the client, or on a nearby machine), and the other proxy runs on the server side (the server end of the tunnel, usually on the same machine as the server, or on a nearby machine). The clientside proxy specifies a parameter file containing a "tunnel clientside" statement (described below). The serverside proxy specifies a parameter file containing one or more "tunnel serverside" statements, one for each username the serverside proxy can accept during authentication. It's possible for a proxy to act as both a clientside and serverside proxy, but that is unusual. Clientside authentication is done on connection (2) (between proxy and server). Serverside authentication is done on connection (1) (between client and proxy). General notes on parameter statements: - Case is not significant, except in the values of the username and secret parameters. - Items are separated by 1 or more blanks. - The first item may be indented i.e. preceded by 1 or more blanks. - Any tab character is changed to a single blank. - End of record is indicated by CR LF or LF. - Records may be as long as necessary. - Some keywords can be abbreviated and/or have aliases. - Optional items are indicated by [ ] in the descriptions below. (Do not type the square brackets.) - After the required initial keywords for a statement, order is not significant. For example: tunnel clientside username fred secret 1234 and tunnel clientside secret 1234 username fred are equivalent. But a keyword and its associated value must be kept together. The number of required initial keywords is: 2 for the tunnel and filter statements. - A record starting with * or # or ; is a comment, and is ignored, except that it may be displayed. The comment character must be in column 1 of the record. A blank or null record is also ignored. A parameter file can contain the following statements (records): list on - Displays subsequent records on the console, identified by "Param:". Even comment records are listed. A LIST statement itself is not listed (if "LIST" or "list" appears starting in column 1 of the record). list off - Turns off the listing of records. LIST OFF is the default at the beginning of the parameter file. filter allow n1[.n2[.n3[.n4]]] [comment] filter deny n1[.n2[.n3[.n4]]] [comment] - One or more of these statements define the IP address filtering to be done for incoming connections from clients. If no statements, connections are allowed from all IP addresses (i.e. the same as having a single statement FILTER ALLOW ALL). The order of the statements is important. The first one that matches the client's IP address determines whether the connection is allowed or denied. The value after ALLOW or DENY is ALL or a full or partial IP addr. E.g. 129 matches any IP addr of the form 129.*.*.*; 129.100 matches any IP addr of the form 129.100.*.*; etc. If no match is found, the connection is allowed. ALL (or ANY) matches any IP addr. ACCEPT is an alias for ALLOW. REFUSE and REJECT are aliases for DENY. The max number of filter statements is currently 500. - Abbreviations: filt tunnel clientside username u secret x - This statement specifies authentication and encryption of data between the proxy and the server. The proxy program is acting as a client, i.e. at the client end of the tunnel. - u and x are the parameters for authentication and negotiation of session encryption keys between the proxy (acting as a client) and the server (which is actually another instance of the proxy which uses "tunnel serverside" statements). - This causes data sent to the server (conn 2) to be encrypted, and data received from the server to be decrypted. - u is a 1- to 80-char username, case-sensitive, no embedded blanks, or is ? (prompt for username at proxy start-up) or ?? (prompt for username, when needed, at EACH connection time). - x is a secret string which is shared between the client and server, or is ? or ?? to prompt for it. It can be 0 to 128 chars long. If it contains blanks, it must be enclosed in quotes ("), and an actual quote in the string is represented by 2 quotes. Any char can be used except 0x00, CR (0x0D), LF (0x0A). A tab char (0x09) is changed to a blank. x is used during the authentication negotiation, acts as a password for username, and is used to generate session encryption and HMAC keys for the encryption. It is recommended that x be long (e.g. 20 chars or more), to prevent off-line password cracking by an attacker. - Only one "tunnel clientside" statement is used. If the parameter file contains more than one, only the last one is used. - Abbreviations: cl, clside, user, sec tunnel serverside username u1 secret x1 tunnel serverside username u2 secret x2 ... - This statement specifies authentication and encryption of data between the client and the proxy. The proxy program is acting as a server, i.e. at the server end of the tunnel. (The client is actually another instance of the proxy which uses a "tunnel clientside" statement.) - This causes data sent to the client (conn 2) to be encrypted, and data received from the client to be decrypted. - The username and secret parameters are as for the "tunnel clientside" statement, except username must not be ? or ?? (i.e. no prompting for username), and multiple "tunnel serverside" statements can be used. When a client connects, the client sends its username to the proxy during authentication, and the proxy looks up the corresponding secret in the table built from these statements. For authentication to be successful, that secret must be the same as the client's secret. - The maximum number of serverside usernames is currently 50. - ?? should not normally be specified for a secret, since that would hold up the server side while the user responds, which would affect other connections, and make the server interactive after start-up. However, ?? can be used, if desired. - Abbreviations: serv, servside, user, sec tunnel options minmsglen m msglenmult n encrtype x - m and n are numeric values for padding of the length of outgoing encrypted messages. They are security options that can help prevent traffic analysis by an attacker. - x is the type of encryption for tunnelling: RC4 XOR by a pseudo-random stream of bytes generated by the RC4 algorithm. Note: At the start of the stream, the first 256 bytes are discarded, for better security. DES3 Triple-DES, in CFB (Cipher Feedback) mode. - Defaults: m: 0 n: 256 x: RC4 - Abbreviations: opt - minmsglen option: For tunnelling, an encrypted message consists of a header field, payload data, 0 or more padding bytes, and a final check sum (HMAC) field. If the minmsglen value is specified, the number of padding bytes is increased to make the total length of the encrypted record at least minmsglen bytes. - msglenmult option: For tunnelling, the number of padding bytes in an encrypted record is increased, if necessary, to make the total length of the encrypted record an exact multiple of msglenmult. - The minmsglen option is applied first, then msglenmult is applied. - Note: The socket buffer size (the value s in the option -buf=s on the proxy command) must be large enough in relation to minmsglen and msglenmult, so that an encrypted record will fit in the buffer. Also, the final length of an encrypted record must be an exact multiple of the encryption blocksize x (currently x=16). The recommended way of satisfying these conditions is to choose msglenmult as some multiple of the encryption blocksize x, then choose minmsglen as some multiple (or 0) of msglenmult, then choose s (buffer size) greater than or equal to both of them. 5. Examples ----------- Example 1: In this example, we use a single proxy between the client and server to display the socket data passing between the client and server. The proxy could be located on any machine, but we will run it on the same machine as the client. We assume the domain name (site name) of the server is server.abc.com. We assume the server listens on port 23 (telnetd). We set up the proxy to listen on port 1500 (any port number could be used). client ------------> proxy ----//-----------> server port 1500 port 23 |--------client machine--------| |---server.abc.com---| Proxy command: proxy -t=64 -b=localhost 1500 server.abc.com 23 The client (e.g. a telnet client) should be configured to connect to localhost, port 1500 (instead of server.abc.com, port 23). The option -t=64 tells the proxy to display the first 64 bytes of each TCP/IP message passing between the client and server. The option -b=localhost tells the proxy to bind to (accept connections only on) localhost i.e. 127.0.0.1. This means that it accepts incoming connections only from the local machine. This is a security option that prevents other machines from connecting to the proxy. If we wanted to use the proxy only for one client/server session, we could specify the -1 option. When you are finished, type Ctrl+C to terminate the proxy (or just close its Command window). The following is sample proxy output for this example. (A tn3270 client was used to connect to a mainframe MUSIC/SP system running under the Sim390 mainframe emulator.) ------------------ Sample output for Example 1 ------------------------------ C:\data>proxy -t=64 -b=localhost 1500 server.abc.com 23 proxy 1.1 Listening for connections on port 1500, socn3=744 2006/08/04 09:44:06 connection from 127.0.0.1 remoteport=4920 socn1=732 Id number for this connection is 1 Connecting to server.abc.com (134.99.99.111), port 23, socn2=724 1: Connected to server 1: ---------- From server: 3 bytes: 0000: FFFD18 *...* *...* 1: ---------- From client: 3 bytes: 0000: FFFB18 *...* *...* 1: ---------- From server: 6 bytes: 0000: FFFA1801 FFF0 *.....0* *......* 1: ---------- From client: 18 bytes: 0000: FFFA1800 49424D2D 33323739 2D322D45 *......(.........* *....IBM-3279-2-E* 0010: FFF0 *.0* *..* 1: ---------- From server: 12 bytes: 0000: FFFD00FF FB00FFFD 19FFFB19 *............* *............* 1: ---------- From client: 12 bytes: 0000: FFFB00FF FD00FFFB 19FFFD19 *............* *............* 1: ---------- From server: 11 bytes: 0000: 0D401140 4013FFEF 02FFEF *. . ......* *.@.@@......* 1: ---------- From client: 1925 bytes: 0000: 60404000 00000000 00000000 00000000 *- .............* *`@@.............* 0010: 00000000 00000000 00000000 00000000 *................* *................* 0020: 00000000 00000000 00000000 00000000 *................* *................* 0030: 00000000 00000000 00000000 00000000 *................* *................* 0040: ... 1: ---------- From server: 719 bytes: 0000: 05C7115D 7F1D6011 404011C2 5F1DE8D4 *.G.)".-. .B^.YM* *...]..`.@@.._...* 0010: D4404040 404040D4 D44040E4 E4404040 *M MM UU * *.@@@@@@..@@..@@@* 0020: 4040E4E4 404040E2 E2E2E2E2 E2E24040 * UU SSSSSSS * *@@..@@@.......@@* 0030: 40C9C9C9 C9C9C940 4040C3C3 C3C3C3C3 * IIIIII CCCCCC* *@......@@@......* 0040: ... ............[output omitted].................. 1: ** Socket EOF on conn 1 1: Connection closed 2006/08/04 09:46:43. ------------------ End of sample output for Example 1 ----------------------- Example 2: This example is similar to Example 1, but uses tunnelling. The clientside proxy runs on the same machine as the client, listens on port 1500, and connects to the serverside proxy, which runs on the same machine (server.abc.com) as the server and listens on port 1600. The server itself listens on port 23. The clientside proxy uses username fred to authenticate to the serverside proxy. client --------> proxy =======//========> proxy -------> server 1500 clientside tunnel 1600 serverside 23 |--------client machine------| |------server.abc.com--------| 135.8.8.22 Proxy command (clientside): proxy -f=parm1.txt -b=localhost 1500 server.abc.com 1600 Clientside parameter file parm1.txt: * Proxy parameter file for client side tunnel options minmsglen 512 msglenmult 256 encrtype des3 filter allow 127.0.0.1 filter deny all tunnel clientside username fred secret my-secret-123-npwTAd Proxy command (serverside): proxy -f=parm2.txt 1600 localhost 23 Serverside parameter file parm2.txt: * Proxy parameter file for server side tunnel options minmsglen 512 msglenmult 256 encrtype des3 filter allow 135.8.8 filter deny all tunnel serverside username johnny secret his-secret-456-xxx tunnel serverside username fred secret my-secret-123-npwTAd tunnel serverside username jane secret her-secret-789-yyyy An exercise: Add a third proxy to this example, to verify that the data passing between the two proxies is encrypted. 6. Tunnelling protocol ---------------------- This proxy program uses its own protocol for tunnelling (authentication and encryption). The protocol is based on standard security algorithms. Authentication involves the exchange of four 128-byte messages (Msg1 to Msg4) between proxy A (at the client end of the tunnel) and proxy B (at the server end of the tunnel). The following is a summary of the protocol. - Standard routine pwd2key (with a high iteration count) is used as needed below, to derive HMAC key and session encr/decr key from an original random key x. pwd2key() uses RFC 2898 algorithm. HMAC is the standard HMAC-SHA1 algorithm. || denotes concatenation. Encryption is Triple-DES (in Cipher Feedback mode) or RC4 (byte-by-byte XOR by RC4 random stream after discarding 1st 256 bytes of stream). - Authentication messages (except Msg1) have a check sum (HMAC) field at the end, and are then encrypted. They are fixed length 128 bytes. - A and B must have the same secret, and use the same encryption type (algorithm). These are specified in the parameter files for the instances of the proxy program. - If either A or B detects an error (e.g. bad message, or check sum field does not match the data), it closes the connection. - A sends Msg1, containing random cnonce1 and username, to B. B looks up the username in its table of names, to get the corresponding secret, which should be the same as A's secret. If the username is unknown to B, B closes the connection. A and B both use x=secret||cnonce1 as a key to generate HMAC key HK1 and session keys K1, which are used on Msg2 (encr by B, decr by A). (K1 is actually 2 sessions keys: K1A for encr by A and decr by B, and K1B for encr by B and decr by A. In this case, K1A is not used.) - B sends Msg2 (encrypted, as described above) to A: it echoes cnonce1 and contains snonce1 generated by B. If B knows the username, but the username is currently not allowed, Msg2 MAY contain a nonzero rc1 to tell the client of this, in which case B closes the connection. A decrypts Msg2, checks the HMAC, checks for a valid message, and verifies the echoed cnonce1. This authenticates B to A, since B needs the correct secret to be able to generate a correct Msg2. (If the received Msg2 is invalid, or the check sum is incorrect, this means the sender has the wrong secret, or is using the wrong protocol.) A and B both use x=secret||snonce1||cnonce1 as a key to generate HMAC key HK2 and session keys K2, which are used on Msg3 and Msg4. (As above for K1, K2 is actually 2 session keys K2A and K2B.) - A sends Msg3 (encrypted, using HK2, K2A) to B: it echoes snonce1 and contains random cnonce2 generated by A. B decrypts and checks Msg2, and verifies the echoed snonce1. This authenticates A to B. - B sends Msg4 (encrypted, using HK2, K2B) to A: it echoes cnonce2 and contains random snonce2 generated by B. It may also contain a nonzero rc2, to notify A of any error conditions. This may be preferable to using rc1 in Msg2, since by now A has been authenticated to B. (In the current implementation in the proxy program, both rc1 and rc2 are zero, and A requires that.) A decrypts and checks Msg4, including verifying cnonce2. - A and B then both use secret||snonce2||cnonce1||snonce1||cnonce2 as a key to generate the final HMAC key HK3, A's encryption key K3A, and B's encryption key K3B, which will be used on all subsequent messages between A and B. This ends the authentication process. Subsequent messages are application data. Each side, when it wants to send plain text D to the other side, formats D into an encrypted message as follows: - Optionally, D may be extended with pad bytes, to make the resulting total (encrypted) msg len LTOT some minimum value, and then again padded to make the total (encrypted) msg len LTOT a multiple of some specified value. (Proxy options minmsglen and msglenmult.) Value msglenmult is forced to be a multiple of the encryption blocksize (currently 16), so that LTOT is an exact multiple of the encryption blocksize. - A header (currently 48 bytes) is added before D, containing L1= original length of D, L2=# of padding bytes that were added to D, and possibly some control bytes (currently they are 0). The header ends with a check sum field (HMAC, by key HK3) calculated from the preceding part of the header. This lets the receiver verify the length values, to avoid using a length which is incorrect (a value too high could make the receiver wait forever for the rest of the message). Currently, all check sum fields are 32 bytes (20-byte HMAC-SHA1, followed by 12 zero bytes). - A check sum field (HMAC, by key HK3) is added at the end, calculated over the header and the padded D. - The resulting total message (length LTOT = 48 + L1 + L2 + 32) is encrypted via key K3A (if the sender is A) or K3B (if the sender is B), and sent to the receiver. Note that the same encryption stream is CONTINUED, when the sender encrypts its next message. - The receiver reverses the above steps, checking the check sum fields, to obtain the original D. The receiver first does a socket read for 48 bytes, to get L1 and L2, then reads the remaining L1 + L2 + 32 bytes from the socket. If any length or check sum is invalid, the receiver closes the connection. - - - - -