mirror of
https://github.com/nmap/nmap.git
synced 2025-12-21 06:59:01 +00:00
Added skeletton for having px_info list in each Nsock IOD.
When establishing the tunnel through proxy chain, we need to track status of each proxy (storing R/W buffers, stats, retries...). This patch lets proxies store and manage whatever structure they want to have for this in a Nsock IOD. Since types can differ between proxy types, the proxy_info are stored as a list of void *, ordered like the proxy nodes.
This commit is contained in:
@@ -82,9 +82,6 @@ static struct proxy_parser *proxy_parser_new(const char *proxychainstr);
|
|||||||
static void proxy_parser_next(struct proxy_parser *parser);
|
static void proxy_parser_next(struct proxy_parser *parser);
|
||||||
static void proxy_parser_delete(struct proxy_parser *parser);
|
static void proxy_parser_delete(struct proxy_parser *parser);
|
||||||
|
|
||||||
static struct proxy_node *proxy_node_new(char *proxystr);
|
|
||||||
static void proxy_node_delete(struct proxy_node *proxy);
|
|
||||||
|
|
||||||
|
|
||||||
/* --- Implemented proxy backends --- */
|
/* --- Implemented proxy backends --- */
|
||||||
extern const struct proxy_op proxy_http_ops;
|
extern const struct proxy_op proxy_http_ops;
|
||||||
@@ -133,7 +130,7 @@ void nsock_proxychain_delete(nsock_proxychain chain) {
|
|||||||
|
|
||||||
free(pchain->specstr);
|
free(pchain->specstr);
|
||||||
while ((node = (struct proxy_node *)gh_list_pop(&pchain->nodes)) != NULL) {
|
while ((node = (struct proxy_node *)gh_list_pop(&pchain->nodes)) != NULL) {
|
||||||
proxy_node_delete(node);
|
node->ops->node_delete(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
gh_list_free(&pchain->nodes);
|
gh_list_free(&pchain->nodes);
|
||||||
@@ -157,17 +154,69 @@ int nsp_set_proxychain(nsock_pool nspool, nsock_proxychain chain) {
|
|||||||
struct proxy_chain_context *proxy_chain_context_new(nsock_pool nspool) {
|
struct proxy_chain_context *proxy_chain_context_new(nsock_pool nspool) {
|
||||||
mspool *nsp = (mspool *)nspool;
|
mspool *nsp = (mspool *)nspool;
|
||||||
struct proxy_chain_context *ctx;
|
struct proxy_chain_context *ctx;
|
||||||
|
gh_list_elem *elt;
|
||||||
|
|
||||||
ctx = (struct proxy_chain_context *)safe_malloc(sizeof(struct proxy_chain_context));
|
ctx = (struct proxy_chain_context *)safe_malloc(sizeof(struct proxy_chain_context));
|
||||||
ctx->px_chain = nsp->px_chain;
|
ctx->px_chain = nsp->px_chain;
|
||||||
ctx->px_state = PROXY_STATE_INITIAL;
|
ctx->px_state = PROXY_STATE_INITIAL;
|
||||||
ctx->px_current = GH_LIST_FIRST_ELEM(&nsp->px_chain->nodes);
|
ctx->px_current = GH_LIST_FIRST_ELEM(&nsp->px_chain->nodes);
|
||||||
|
gh_list_init(&ctx->px_info);
|
||||||
|
|
||||||
|
for (elt = GH_LIST_FIRST_ELEM(&nsp->px_chain->nodes); elt != NULL; elt = GH_LIST_ELEM_NEXT(elt)) {
|
||||||
|
struct proxy_node *px = (struct proxy_node *)GH_LIST_ELEM_DATA(elt);
|
||||||
|
void *pinfo = NULL;
|
||||||
|
|
||||||
|
px->ops->info_new(&pinfo);
|
||||||
|
gh_list_append(&ctx->px_info, pinfo);
|
||||||
|
}
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void proxy_chain_context_delete(struct proxy_chain_context *ctx) {
|
void proxy_chain_context_delete(struct proxy_chain_context *ctx) {
|
||||||
if (ctx)
|
if (ctx) {
|
||||||
|
gh_list_elem *pxe;
|
||||||
|
|
||||||
|
assert(GH_LIST_COUNT(&ctx->px_chain->nodes) == GH_LIST_COUNT(&ctx->px_info));
|
||||||
|
|
||||||
|
for (pxe = GH_LIST_FIRST_ELEM(&ctx->px_chain->nodes); pxe != NULL; pxe = GH_LIST_ELEM_NEXT(pxe)) {
|
||||||
|
struct proxy_node *pxn;
|
||||||
|
void *px_info;
|
||||||
|
|
||||||
|
pxn = (struct proxy_node *)GH_LIST_ELEM_DATA(pxe);
|
||||||
|
px_info = gh_list_pop(&ctx->px_info);
|
||||||
|
|
||||||
|
pxn->ops->info_delete(px_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
gh_list_free(&ctx->px_info);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX
|
||||||
|
* This function is just an ugly PoC.
|
||||||
|
*
|
||||||
|
* A clean version should handle:
|
||||||
|
* - both v4 and v6 adresses
|
||||||
|
* - hostnames (how do we want to resolve them though??)
|
||||||
|
* - user:pass@ prefix before host specification
|
||||||
|
*/
|
||||||
|
static struct proxy_node *proxy_node_new(char *proxystr) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; ProxyBackends[i] != NULL; i++) {
|
||||||
|
const struct proxy_op *pxop;
|
||||||
|
|
||||||
|
pxop = ProxyBackends[i];
|
||||||
|
if (strncasecmp(proxystr, pxop->prefix, strlen(pxop->prefix)) == 0) {
|
||||||
|
struct proxy_node *proxy;
|
||||||
|
|
||||||
|
pxop->node_new(&proxy, proxystr);
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fatal("Invalid protocol in proxy specification string: %s", proxystr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proxy_parser *proxy_parser_new(const char *proxychainstr) {
|
struct proxy_parser *proxy_parser_new(const char *proxychainstr) {
|
||||||
@@ -206,37 +255,6 @@ void proxy_parser_delete(struct proxy_parser *parser) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX
|
|
||||||
* This function is just an ugly PoC.
|
|
||||||
*
|
|
||||||
* A clean version should handle:
|
|
||||||
* - both v4 and v6 adresses
|
|
||||||
* - hostnames (how do we want to resolve them though??)
|
|
||||||
* - user:pass@ prefix before host specification
|
|
||||||
*/
|
|
||||||
static struct proxy_node *proxy_node_new(char *proxystr) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; ProxyBackends[i] != NULL; i++) {
|
|
||||||
const struct proxy_op *pxop;
|
|
||||||
|
|
||||||
pxop = ProxyBackends[i];
|
|
||||||
if (strncasecmp(proxystr, pxop->prefix, strlen(pxop->prefix)) == 0) {
|
|
||||||
struct proxy_node *proxy;
|
|
||||||
|
|
||||||
proxy = (struct proxy_node *)safe_zalloc(sizeof(struct proxy_node));
|
|
||||||
pxop->init(proxy, proxystr);
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fatal("Invalid protocol in proxy specification string: %s", proxystr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void proxy_node_delete(struct proxy_node *proxy) {
|
|
||||||
if (proxy)
|
|
||||||
free(proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void forward_event(nsock_pool nspool, nsock_event nsevent, void *udata) {
|
void forward_event(nsock_pool nspool, nsock_event nsevent, void *udata) {
|
||||||
mspool *nsp = (mspool *)nspool;
|
mspool *nsp = (mspool *)nspool;
|
||||||
msevent *nse = (msevent *)nsevent;
|
msevent *nse = (msevent *)nsevent;
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ enum nsock_proxy_state {
|
|||||||
|
|
||||||
/* ------------------- STRUCTURES ------------------- */
|
/* ------------------- STRUCTURES ------------------- */
|
||||||
|
|
||||||
|
/* Static information about a proxy node in the chain. This is generated by
|
||||||
|
* parsing the proxy specification string given by user. Those structures are
|
||||||
|
* then read-only and stored in the nsock_pool. */
|
||||||
struct proxy_node {
|
struct proxy_node {
|
||||||
enum nsock_proxy_type px_type;
|
enum nsock_proxy_type px_type;
|
||||||
|
|
||||||
@@ -95,19 +98,26 @@ struct proxy_node {
|
|||||||
unsigned short port;
|
unsigned short port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Ordered list of proxy nodes, as specified in the proxy specification string. */
|
||||||
struct proxy_chain {
|
struct proxy_chain {
|
||||||
char *specstr;
|
char *specstr;
|
||||||
gh_list nodes;
|
gh_list nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* IOD-specific context. For each IOD we establish a tunnel through the chain of
|
||||||
|
* proxies. This structure stores all the related information. */
|
||||||
struct proxy_chain_context {
|
struct proxy_chain_context {
|
||||||
struct proxy_chain *px_chain;
|
const struct proxy_chain *px_chain;
|
||||||
|
|
||||||
/* Those fields are used to store current state during the tunnel
|
/* Those fields are used to store current state during the tunnel
|
||||||
* establishment phase. */
|
* establishment phase. */
|
||||||
gh_list_elem *px_current;
|
gh_list_elem *px_current;
|
||||||
enum nsock_proxy_state px_state;
|
enum nsock_proxy_state px_state;
|
||||||
|
|
||||||
|
/* Each proxy in the chain maintains a data structure. This can contains r/w
|
||||||
|
* buffers for instance. */
|
||||||
|
gh_list px_info;
|
||||||
|
|
||||||
struct sockaddr_storage target_ss;
|
struct sockaddr_storage target_ss;
|
||||||
size_t target_sslen;
|
size_t target_sslen;
|
||||||
unsigned short target_port;
|
unsigned short target_port;
|
||||||
@@ -118,10 +128,17 @@ struct proxy_op {
|
|||||||
const char *prefix;
|
const char *prefix;
|
||||||
enum nsock_proxy_type type;
|
enum nsock_proxy_type type;
|
||||||
|
|
||||||
void (*init)(struct proxy_node *proxy, char *proxystr);
|
int (*node_new)(struct proxy_node **node, char *proxystr);
|
||||||
|
void (*node_delete)(struct proxy_node *node);
|
||||||
|
|
||||||
|
int (*info_new)(void **info);
|
||||||
|
void (*info_delete)(void *info);
|
||||||
|
|
||||||
void (*handler)(nsock_pool nspool, nsock_event nsevent, void *udata);
|
void (*handler)(nsock_pool nspool, nsock_event nsevent, void *udata);
|
||||||
|
|
||||||
nsock_event_id (*connect_tcp)(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_handler handler, int mstimeout,
|
nsock_event_id (*connect_tcp)(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_handler handler, int mstimeout,
|
||||||
void *userdata, struct sockaddr *saddr, size_t sslen, unsigned short port);
|
void *userdata, struct sockaddr *saddr, size_t sslen, unsigned short port);
|
||||||
|
|
||||||
char *(*encode)(const char *src, size_t len, size_t *dlen);
|
char *(*encode)(const char *src, size_t len, size_t *dlen);
|
||||||
char *(*decode)(const char *src, size_t len, size_t *dlen);
|
char *(*decode)(const char *src, size_t len, size_t *dlen);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -61,9 +61,16 @@
|
|||||||
|
|
||||||
#define DEFAULT_PROXY_PORT_HTTP "8080"
|
#define DEFAULT_PROXY_PORT_HTTP "8080"
|
||||||
|
|
||||||
|
struct http_proxy_info {
|
||||||
|
void *dummy;
|
||||||
|
};
|
||||||
|
|
||||||
/* --- PROXY INTERFACE PROTOTYPES --- */
|
|
||||||
static void proxy_http_init(struct proxy_node *proxy, char *proxystr);
|
/* ---- PROTOTYPES ---- */
|
||||||
|
static int proxy_http_node_new(struct proxy_node **node, char *proxystr);
|
||||||
|
static void proxy_http_node_delete(struct proxy_node *node);
|
||||||
|
static int proxy_http_info_new(void **info);
|
||||||
|
static void proxy_http_info_delete(void *info);
|
||||||
static void proxy_http_handler(nsock_pool nspool, nsock_event nsevent, void *udata);
|
static void proxy_http_handler(nsock_pool nspool, nsock_event nsevent, void *udata);
|
||||||
static nsock_event_id proxy_http_connect_tcp(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_handler handler,
|
static nsock_event_id proxy_http_connect_tcp(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_handler handler,
|
||||||
int timeout_msecs, void *userdata, struct sockaddr *saddr,
|
int timeout_msecs, void *userdata, struct sockaddr *saddr,
|
||||||
@@ -76,7 +83,10 @@ static char *proxy_http_decode(const char *src, size_t len, size_t *dlen);
|
|||||||
const struct proxy_op proxy_http_ops = {
|
const struct proxy_op proxy_http_ops = {
|
||||||
.prefix = "http://",
|
.prefix = "http://",
|
||||||
.type = PROXY_TYPE_HTTP,
|
.type = PROXY_TYPE_HTTP,
|
||||||
.init = proxy_http_init,
|
.node_new = proxy_http_node_new,
|
||||||
|
.node_delete = proxy_http_node_delete,
|
||||||
|
.info_new = proxy_http_info_new,
|
||||||
|
.info_delete = proxy_http_info_delete,
|
||||||
.handler = proxy_http_handler,
|
.handler = proxy_http_handler,
|
||||||
.connect_tcp = proxy_http_connect_tcp,
|
.connect_tcp = proxy_http_connect_tcp,
|
||||||
.encode = proxy_http_encode,
|
.encode = proxy_http_encode,
|
||||||
@@ -84,10 +94,12 @@ const struct proxy_op proxy_http_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void proxy_http_init(struct proxy_node *proxy, char *proxystr) {
|
int proxy_http_node_new(struct proxy_node **node, char *proxystr) {
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin;
|
||||||
|
struct proxy_node *proxy;
|
||||||
char *strhost, *strport, *saveptr;
|
char *strhost, *strport, *saveptr;
|
||||||
|
|
||||||
|
proxy = (struct proxy_node *)safe_zalloc(sizeof(struct proxy_node));
|
||||||
proxy->ops = &proxy_http_ops;
|
proxy->ops = &proxy_http_ops;
|
||||||
|
|
||||||
strhost = strtok_r(proxystr + 7, ":", &saveptr);
|
strhost = strtok_r(proxystr + 7, ":", &saveptr);
|
||||||
@@ -101,6 +113,31 @@ void proxy_http_init(struct proxy_node *proxy, char *proxystr) {
|
|||||||
|
|
||||||
proxy->sslen = sizeof(struct sockaddr_in);
|
proxy->sslen = sizeof(struct sockaddr_in);
|
||||||
proxy->port = (unsigned short)atoi(strport);
|
proxy->port = (unsigned short)atoi(strport);
|
||||||
|
|
||||||
|
*node = proxy;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void proxy_http_node_delete(struct proxy_node *node) {
|
||||||
|
if (node)
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
int proxy_http_info_new(void **info) {
|
||||||
|
struct http_proxy_info *pxi;
|
||||||
|
|
||||||
|
pxi = (struct http_proxy_info *)safe_zalloc(sizeof(struct http_proxy_info));
|
||||||
|
pxi->dummy = NULL; // TODO
|
||||||
|
|
||||||
|
*info = pxi;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void proxy_http_info_delete(void *info) {
|
||||||
|
if (info)
|
||||||
|
free(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proxy_http_handler(nsock_pool nspool, nsock_event nsevent, void *udata) {
|
void proxy_http_handler(nsock_pool nspool, nsock_event nsevent, void *udata) {
|
||||||
|
|||||||
Reference in New Issue
Block a user