1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 09:58:01 +00:00
putty-source/proxy/proxy.h
Simon Tatham 3c21fa54c5 HTTP proxy: implement Digest authentication.
In http.c, this drops in reasonably neatly alongside the existing
support for Basic, now that we're waiting for an initial 407 response
from the proxy to tell us which auth mechanism it would prefer to use.

The rest of this patch is mostly contriving to add testcrypt support
for the function in cproxy.c that generates the complicated output
header to go in the HTTP request: you need about a dozen assorted
parameters, the actual response hash has two more hashes in its
preimage, and there's even an option to hash the username as well if
necessary. Much more complicated than CHAP (which is just plain
HMAC-MD5), so it needs testing!

Happily, RFC 7616 comes with some reasonably useful test cases, and
I've managed to transcribe them directly into cryptsuite.py and
demonstrate that my response-generator agrees with them.

End-to-end testing of the whole system was done against Squid 4.13
(specifically, the squid package in Debian bullseye, version 4.13-10).
2021-11-20 15:08:19 +00:00

111 lines
3.0 KiB
C

/*
* Network proxy abstraction in PuTTY
*
* A proxy layer, if necessary, wedges itself between the
* network code and the higher level backend.
*
* Supported proxies: HTTP CONNECT, generic telnet, SOCKS 4 & 5
*/
#ifndef PUTTY_PROXY_H
#define PUTTY_PROXY_H
typedef struct ProxySocket ProxySocket;
typedef struct ProxyNegotiator ProxyNegotiator;
typedef struct ProxyNegotiatorVT ProxyNegotiatorVT;
struct ProxySocket {
const char *error;
Socket *sub_socket;
Plug *plug;
SockAddr *remote_addr;
int remote_port;
bufchain pending_output_data;
bufchain pending_oob_output_data;
bufchain pending_input_data;
bool pending_eof;
bool freeze; /* should we freeze the underlying socket when
* we are done with the proxy negotiation? this
* simply caches the value of sk_set_frozen calls.
*/
ProxyNegotiator *pn; /* non-NULL if still negotiating */
bufchain output_from_negotiator;
/* configuration, used to look up proxy settings */
Conf *conf;
/* for interaction with the Seat */
Interactor *clientitr;
LogPolicy *clientlp;
Seat *clientseat;
Socket sock;
Plug plugimpl;
Interactor interactor;
};
struct ProxyNegotiator {
const ProxyNegotiatorVT *vt;
/* Standard fields for any ProxyNegotiator. new() and free() don't
* have to set these up; that's done centrally, to save duplication. */
ProxySocket *ps;
bufchain *input;
bufchain_sink output[1];
Interactor *itr; /* NULL if we are not able to interact with the user */
/* Set to report success during proxy negotiation. */
bool done;
/* Set to report an error during proxy negotiation. The main
* ProxySocket will free it, and will then guarantee never to call
* process_queue again. */
char *error;
/* Set to report user abort during proxy negotiation. */
bool aborted;
};
struct ProxyNegotiatorVT {
ProxyNegotiator *(*new)(const ProxyNegotiatorVT *);
void (*process_queue)(ProxyNegotiator *);
void (*free)(ProxyNegotiator *);
const char *type;
};
static inline ProxyNegotiator *proxy_negotiator_new(
const ProxyNegotiatorVT *vt)
{ return vt->new(vt); }
static inline void proxy_negotiator_process_queue(ProxyNegotiator *pn)
{ pn->vt->process_queue(pn); }
static inline void proxy_negotiator_free(ProxyNegotiator *pn)
{ pn->vt->free(pn); }
extern const ProxyNegotiatorVT http_proxy_negotiator_vt;
extern const ProxyNegotiatorVT socks4_proxy_negotiator_vt;
extern const ProxyNegotiatorVT socks5_proxy_negotiator_vt;
extern const ProxyNegotiatorVT telnet_proxy_negotiator_vt;
/*
* Centralised function to allow ProxyNegotiators to get hold of a
* prompts_t.
*/
prompts_t *proxy_new_prompts(ProxySocket *ps);
/*
* This may be reused by local-command proxies on individual
* platforms.
*/
#define TELNET_CMD_MISSING_USERNAME 0x0001
#define TELNET_CMD_MISSING_PASSWORD 0x0002
char *format_telnet_command(SockAddr *addr, int port, Conf *conf,
unsigned *flags_out);
#include "cproxy.h"
#endif