From: simon Date: Sat, 21 Sep 2002 14:03:05 +0000 (+0000) Subject: Support username and password authentication when talking to HTTP X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/1549e076bc8f485888261a3b97ce35e442b5fda9 Support username and password authentication when talking to HTTP proxies. git-svn-id: svn://svn.tartarus.org/sgt/putty@1971 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/doc/config.but b/doc/config.but index c9bf6657..c2383b6b 100644 --- a/doc/config.but +++ b/doc/config.but @@ -1,4 +1,4 @@ -\versionid $Id: config.but,v 1.38 2002/09/10 12:30:45 jacob Exp $ +\versionid $Id: config.but,v 1.39 2002/09/21 14:03:05 simon Exp $ \C{config} Configuring PuTTY @@ -1433,9 +1433,16 @@ This excludes both of the above ranges at once. If your proxy requires authentication, you can enter a username and a password in the \q{Username} and \q{Password} boxes. -Currently only the \q{Username} box has any effect, and that only for -SOCKS 4 proxies. ( [FIXME] No forms of authentication are supported -for other types of proxy.) +Authentication is not supported for all forms of proxy. Currently: + +\b Username and password authentication is supported for HTTP proxies. + +\b SOCKS 4 can use the \q{Username} field, but does not support +passwords. + +\b PuTTY does not support authentication in SOCKS 5 at all. + +\b Authentication is meaningless in Telnet proxies. \S{config-proxy-command} Specifying the Telnet proxy command diff --git a/misc.c b/misc.c index 6f2d5448..34e613ef 100644 --- a/misc.c +++ b/misc.c @@ -51,6 +51,35 @@ char *dupcat(char *s1, ...) } /* ---------------------------------------------------------------------- + * Base64 encoding routine. This is required in public-key writing + * but also in HTTP proxy handling, so it's centralised here. + */ + +void base64_encode_atom(unsigned char *data, int n, char *out) +{ + static const char base64_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + unsigned word; + + word = data[0] << 16; + if (n > 1) + word |= data[1] << 8; + if (n > 2) + word |= data[2]; + out[0] = base64_chars[(word >> 18) & 0x3F]; + out[1] = base64_chars[(word >> 12) & 0x3F]; + if (n > 1) + out[2] = base64_chars[(word >> 6) & 0x3F]; + else + out[2] = '='; + if (n > 2) + out[3] = base64_chars[word & 0x3F]; + else + out[3] = '='; +} + +/* ---------------------------------------------------------------------- * Generic routines to deal with send buffers: a linked list of * smallish blocks, with the operations * diff --git a/misc.h b/misc.h index 12d0003f..3a908899 100644 --- a/misc.h +++ b/misc.h @@ -13,6 +13,8 @@ char *dupstr(char *s); char *dupcat(char *s1, ...); +void base64_encode_atom(unsigned char *data, int n, char *out); + struct bufchain_granule; typedef struct bufchain_tag { struct bufchain_granule *head, *tail; diff --git a/proxy.c b/proxy.c index 275e79d5..f73b9ad1 100644 --- a/proxy.c +++ b/proxy.c @@ -425,10 +425,26 @@ int proxy_http_negotiate (Proxy_Socket p, int change) sk_getaddr(p->remote_addr, dest, 64); - sprintf(buf, "CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n\r\n", + sprintf(buf, "CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n", dest, p->remote_port, dest, p->remote_port); sk_write(p->sub_socket, buf, strlen(buf)); + if (cfg.proxy_username[0] || cfg.proxy_password[0]) { + char buf[sizeof(cfg.proxy_username)+sizeof(cfg.proxy_password)]; + char buf2[sizeof(buf)*4/3 + 100]; + int i, j, len; + sprintf(buf, "%s:%s", cfg.proxy_username, cfg.proxy_password); + len = strlen(buf); + sprintf(buf2, "Proxy-Authorization: basic "); + for (i = 0, j = strlen(buf2); i < len; i += 3, j += 4) + base64_encode_atom(buf+i, (len-i > 3 ? 3 : len-i), buf2+j); + strcpy(buf2+j, "\r\n"); + sk_write(p->sub_socket, buf2, strlen(buf2)); + } + + sprintf(buf, "\r\n"); + sk_write(p->sub_socket, buf, strlen(buf)); + p->state = 1; return 0; } diff --git a/sshpubk.c b/sshpubk.c index 8a9b75df..270e6850 100644 --- a/sshpubk.c +++ b/sshpubk.c @@ -949,30 +949,6 @@ int base64_lines(int datalen) return (datalen + 47) / 48; } -void base64_encode_atom(unsigned char *data, int n, char *out) -{ - static const char base64_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - unsigned word; - - word = data[0] << 16; - if (n > 1) - word |= data[1] << 8; - if (n > 2) - word |= data[2]; - out[0] = base64_chars[(word >> 18) & 0x3F]; - out[1] = base64_chars[(word >> 12) & 0x3F]; - if (n > 1) - out[2] = base64_chars[(word >> 6) & 0x3F]; - else - out[2] = '='; - if (n > 2) - out[3] = base64_chars[word & 0x3F]; - else - out[3] = '='; -} - void base64_encode(FILE * fp, unsigned char *data, int datalen, int cpl) { int linelen = 0; diff --git a/windlg.c b/windlg.c index c8f7ec1e..e13cfa12 100644 --- a/windlg.c +++ b/windlg.c @@ -1829,8 +1829,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) IDC_PROXYEXCLUDEEDIT, 100, NULL); staticedit(&cp, "&Username", IDC_PROXYUSERSTATIC, IDC_PROXYUSEREDIT, 60); - staticedit(&cp, "Pass&word", IDC_PROXYPASSSTATIC, - IDC_PROXYPASSEDIT, 60); + staticpassedit(&cp, "Pass&word", IDC_PROXYPASSSTATIC, + IDC_PROXYPASSEDIT, 60); endbox(&cp); beginbox(&cp, "Misc. proxy settings", IDC_BOX_PROXY2); multiedit(&cp,