1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
/*
* 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;
/* Parameters needed to make further connections to the proxy */
SockAddr *proxy_addr;
int proxy_port;
bool proxy_privport, proxy_oobinline, proxy_nodelay, proxy_keepalive;
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;
/* Set to request the centralised code to make a fresh connection
* to the proxy server, e.g. because an HTTP proxy slammed the
* connection shut after sending 407 Proxy Auth Required. */
bool reconnect;
};
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 functions to allow ProxyNegotiators to get hold of a
* prompts_t, and to deal with SeatPromptResults coming back.
*/
prompts_t *proxy_new_prompts(ProxySocket *ps);
void proxy_spr_abort(ProxyNegotiator *pn, SeatPromptResult spr);
/*
* 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);
DeferredSocketOpener *local_proxy_opener(
SockAddr *addr, int port, Plug *plug, Conf *conf, Interactor *itr);
void local_proxy_opener_set_socket(DeferredSocketOpener *opener,
Socket *socket);
char *platform_setup_local_proxy(Socket *socket, const char *cmd);
#include "cproxy.h"
#endif
|