SockAddr name_lookup(const char *host, int port, char **canonicalname, Conf *conf, int addressfamily, void *frontend, const char *reason) { char *logmsg; if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE && do_proxy_dns(conf) && proxy_for_destination(NULL, host, port, conf)) { if (frontend) { logmsg = dupprintf("Leaving host lookup to proxy of \"%s\"" " (for %s)", host, reason); logevent(frontend, logmsg); sfree(logmsg); } *canonicalname = dupstr(host); return sk_nonamelookup(host); } else { if (frontend) { logmsg = dns_log_msg(host, addressfamily, reason); logevent(frontend, logmsg); sfree(logmsg); } return sk_namelookup(host, canonicalname, addressfamily); } }
SockAddr name_lookup(char *host, int port, char **canonicalname, const Config *cfg, int addressfamily) { if (cfg->proxy_type != PROXY_NONE && do_proxy_dns(cfg) && proxy_for_destination(NULL, host, port, cfg)) { *canonicalname = dupstr(host); return sk_nonamelookup(host); } return sk_namelookup(host, canonicalname, addressfamily); }
SockAddr name_lookup(char *host, int port, char **canonicalname, Conf *conf, int addressfamily) { if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE && do_proxy_dns(conf) && proxy_for_destination(NULL, host, port, conf)) { *canonicalname = dupstr(host); return sk_nonamelookup(host); } return sk_namelookup(host, canonicalname, addressfamily); }
/* * Called to set up the raw connection. * * Returns an error message, or NULL on success. * * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ static char *raw_init(char *host, int port, char **realhost, int nodelay) { static struct plug_function_table fn_table = { raw_closing, raw_receive, raw_sent }, *fn_table_ptr = &fn_table; SockAddr addr; char *err; /* * Try to find host. */ { char buf[200]; sprintf(buf, "Looking up host \"%.170s\"", host); logevent(buf); } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) return err; if (port < 0) port = 23; /* default telnet port */ /* * Open socket. */ { char buf[200], addrbuf[100]; sk_getaddr(addr, addrbuf, 100); sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); logevent(buf); } s = new_connection(addr, *realhost, port, 0, 1, nodelay, &fn_table_ptr); if ((err = sk_socket_error(s))) return err; sk_addr_free(addr); return NULL; }
/* * Called when receiving a PORT OPEN from the server */ char *pfd_newconnect(Socket *s, char *hostname, int port, void *c) { static struct plug_function_table fn_table = { pfd_closing, pfd_receive, pfd_sent, NULL }; SockAddr addr; char *err, *dummy_realhost; struct PFwdPrivate *pr; /* * Try to find host. */ addr = sk_namelookup(hostname, &dummy_realhost); if ((err = sk_addr_error(addr))) return err; /* * Open socket. */ pr = (struct PFwdPrivate *) smalloc(sizeof(struct PFwdPrivate)); pr->fn = &fn_table; pr->throttled = pr->throttle_override = 0; pr->ready = 1; pr->c = c; pr->s = *s = sk_new(addr, port, 0, 1, 0, (Plug) pr); if ((err = sk_socket_error(*s))) { sfree(pr); return err; } sk_set_private_ptr(*s, pr); sk_addr_free(addr); return NULL; }
SockAddr *name_lookup(const char *host, int port, char **canonicalname, Conf *conf, int addressfamily, LogContext *logctx, const char *reason) { if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE && do_proxy_dns(conf) && proxy_for_destination(NULL, host, port, conf)) { if (logctx) logeventf(logctx, "Leaving host lookup to proxy of \"%s\"" " (for %s)", host, reason); *canonicalname = dupstr(host); return sk_nonamelookup(host); } else { if (logctx) logevent_and_free( logctx, dns_log_msg(host, addressfamily, reason)); return sk_namelookup(host, canonicalname, addressfamily); } }
Socket new_connection(SockAddr addr, const char *hostname, int port, int privport, int oobinline, int nodelay, int keepalive, Plug plug, Conf *conf) { static const struct socket_function_table socket_fn_table = { sk_proxy_plug, sk_proxy_close, sk_proxy_write, sk_proxy_write_oob, sk_proxy_write_eof, sk_proxy_flush, sk_proxy_set_frozen, sk_proxy_socket_error, NULL, /* peer_info */ }; static const struct plug_function_table plug_fn_table = { plug_proxy_log, plug_proxy_closing, plug_proxy_receive, plug_proxy_sent, plug_proxy_accepting}; if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE && proxy_for_destination(addr, hostname, port, conf)) { Proxy_Socket ret; Proxy_Plug pplug; SockAddr proxy_addr; char *proxy_canonical_name; const char *proxy_type; Socket sret; int type; if ((sret = platform_new_connection(addr, hostname, port, privport, oobinline, nodelay, keepalive, plug, conf)) != NULL) return sret; ret = snew(struct Socket_proxy_tag); ret->fn = &socket_fn_table; ret->conf = conf_copy(conf); ret->plug = plug; ret->remote_addr = addr; /* will need to be freed on close */ ret->remote_port = port; ret->error = NULL; ret->pending_flush = 0; ret->pending_eof = 0; ret->freeze = 0; bufchain_init(&ret->pending_input_data); bufchain_init(&ret->pending_output_data); bufchain_init(&ret->pending_oob_output_data); ret->sub_socket = NULL; ret->state = PROXY_STATE_NEW; ret->negotiate = NULL; type = conf_get_int(conf, CONF_proxy_type); if (type == PROXY_HTTP) { ret->negotiate = proxy_http_negotiate; proxy_type = "HTTP"; } else if (type == PROXY_SOCKS4) { ret->negotiate = proxy_socks4_negotiate; proxy_type = "SOCKS 4"; } else if (type == PROXY_SOCKS5) { ret->negotiate = proxy_socks5_negotiate; proxy_type = "SOCKS 5"; } else if (type == PROXY_TELNET) { ret->negotiate = proxy_telnet_negotiate; proxy_type = "Telnet"; } else { ret->error = "Proxy error: Unknown proxy method"; return (Socket)ret; } { char *logmsg = dupprintf("Will use %s proxy at %s:%d to connect" " to %s:%d", proxy_type, conf_get_str(conf, CONF_proxy_host), conf_get_int(conf, CONF_proxy_port), hostname, port); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } /* create the proxy plug to map calls from the actual * socket into our proxy socket layer */ pplug = snew(struct Plug_proxy_tag); pplug->fn = &plug_fn_table; pplug->proxy_socket = ret; { char *logmsg = dns_log_msg(conf_get_str(conf, CONF_proxy_host), conf_get_int(conf, CONF_addressfamily), "proxy"); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } /* look-up proxy */ proxy_addr = sk_namelookup(conf_get_str(conf, CONF_proxy_host), &proxy_canonical_name, conf_get_int(conf, CONF_addressfamily)); if (sk_addr_error(proxy_addr) != NULL) { ret->error = "Proxy error: Unable to resolve proxy host name"; sfree(pplug); sk_addr_free(proxy_addr); return (Socket)ret; } sfree(proxy_canonical_name); { char addrbuf[256], *logmsg; sk_getaddr(proxy_addr, addrbuf, lenof(addrbuf)); logmsg = dupprintf("Connecting to %s proxy at %s port %d", proxy_type, addrbuf, conf_get_int(conf, CONF_proxy_port)); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } /* create the actual socket we will be using, * connected to our proxy server and port. */ ret->sub_socket = sk_new(proxy_addr, conf_get_int(conf, CONF_proxy_port), privport, oobinline, nodelay, keepalive, (Plug)pplug); if (sk_socket_error(ret->sub_socket) != NULL) return (Socket)ret; /* start the proxy negotiation process... */ sk_set_frozen(ret->sub_socket, 0); ret->negotiate(ret, PROXY_CHANGE_NEW); return (Socket)ret; }
Socket new_connection(SockAddr addr, char *hostname, int port, int privport, int oobinline, int nodelay, int keepalive, Plug plug, const Config *cfg) { static const struct socket_function_table socket_fn_table = { sk_proxy_plug, sk_proxy_close, sk_proxy_write, sk_proxy_write_oob, sk_proxy_flush, sk_proxy_set_private_ptr, sk_proxy_get_private_ptr, sk_proxy_set_frozen, sk_proxy_socket_error }; static const struct plug_function_table plug_fn_table = { plug_proxy_log, plug_proxy_closing, plug_proxy_receive, plug_proxy_sent, plug_proxy_accepting }; if (cfg->proxy_type != PROXY_NONE && proxy_for_destination(addr, hostname, port, cfg)) { Proxy_Socket ret; Proxy_Plug pplug; SockAddr proxy_addr; char *proxy_canonical_name; Socket sret; if ((sret = platform_new_connection(addr, hostname, port, privport, oobinline, nodelay, keepalive, plug, cfg)) != NULL) return sret; ret = snew(struct Socket_proxy_tag); ret->fn = &socket_fn_table; ret->cfg = *cfg; /* STRUCTURE COPY */ ret->plug = plug; ret->remote_addr = addr; /* will need to be freed on close */ ret->remote_port = port; ret->error = NULL; ret->pending_flush = 0; ret->freeze = 0; bufchain_init(&ret->pending_input_data); bufchain_init(&ret->pending_output_data); bufchain_init(&ret->pending_oob_output_data); ret->sub_socket = NULL; ret->state = PROXY_STATE_NEW; ret->negotiate = NULL; if (cfg->proxy_type == PROXY_HTTP) { ret->negotiate = proxy_http_negotiate; } else if (cfg->proxy_type == PROXY_SOCKS4) { ret->negotiate = proxy_socks4_negotiate; } else if (cfg->proxy_type == PROXY_SOCKS5) { ret->negotiate = proxy_socks5_negotiate; } else if (cfg->proxy_type == PROXY_TELNET) { ret->negotiate = proxy_telnet_negotiate; } else { ret->error = "Proxy error: Unknown proxy method"; return (Socket) ret; } /* create the proxy plug to map calls from the actual * socket into our proxy socket layer */ pplug = snew(struct Plug_proxy_tag); pplug->fn = &plug_fn_table; pplug->proxy_socket = ret; /* look-up proxy */ proxy_addr = sk_namelookup(cfg->proxy_host, &proxy_canonical_name, cfg->addressfamily); if (sk_addr_error(proxy_addr) != NULL) { ret->error = "Proxy error: Unable to resolve proxy host name"; return (Socket)ret; } sfree(proxy_canonical_name); /* create the actual socket we will be using, * connected to our proxy server and port. */ ret->sub_socket = sk_new(proxy_addr, cfg->proxy_port, privport, oobinline, nodelay, keepalive, (Plug) pplug); if (sk_socket_error(ret->sub_socket) != NULL) return (Socket) ret; /* start the proxy negotiation process... */ sk_set_frozen(ret->sub_socket, 0); ret->negotiate(ret, PROXY_CHANGE_NEW); return (Socket) ret; }
Socket *new_connection(SockAddr *addr, const char *hostname, int port, bool privport, bool oobinline, bool nodelay, bool keepalive, Plug *plug, Conf *conf) { if (conf_get_int(conf, CONF_proxy_type) != PROXY_NONE && proxy_for_destination(addr, hostname, port, conf)) { ProxySocket *ret; SockAddr *proxy_addr; char *proxy_canonical_name; const char *proxy_type; Socket *sret; int type; if ((sret = platform_new_connection(addr, hostname, port, privport, oobinline, nodelay, keepalive, plug, conf)) != NULL) return sret; ret = snew(ProxySocket); ret->sock.vt = &ProxySocket_sockvt; ret->plugimpl.vt = &ProxySocket_plugvt; ret->conf = conf_copy(conf); ret->plug = plug; ret->remote_addr = addr; /* will need to be freed on close */ ret->remote_port = port; ret->error = NULL; ret->pending_flush = false; ret->pending_eof = false; ret->freeze = false; bufchain_init(&ret->pending_input_data); bufchain_init(&ret->pending_output_data); bufchain_init(&ret->pending_oob_output_data); ret->sub_socket = NULL; ret->state = PROXY_STATE_NEW; ret->negotiate = NULL; type = conf_get_int(conf, CONF_proxy_type); if (type == PROXY_HTTP) { ret->negotiate = proxy_http_negotiate; proxy_type = "HTTP"; } else if (type == PROXY_SOCKS4) { ret->negotiate = proxy_socks4_negotiate; proxy_type = "SOCKS 4"; } else if (type == PROXY_SOCKS5) { ret->negotiate = proxy_socks5_negotiate; proxy_type = "SOCKS 5"; } else if (type == PROXY_TELNET) { ret->negotiate = proxy_telnet_negotiate; proxy_type = "Telnet"; } else { ret->error = "Proxy error: Unknown proxy method"; return &ret->sock; } { char *logmsg = dupprintf("Will use %s proxy at %s:%d to connect" " to %s:%d", proxy_type, conf_get_str(conf, CONF_proxy_host), conf_get_int(conf, CONF_proxy_port), hostname, port); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } { char *logmsg = dns_log_msg(conf_get_str(conf, CONF_proxy_host), conf_get_int(conf, CONF_addressfamily), "proxy"); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } /* look-up proxy */ proxy_addr = sk_namelookup(conf_get_str(conf, CONF_proxy_host), &proxy_canonical_name, conf_get_int(conf, CONF_addressfamily)); if (sk_addr_error(proxy_addr) != NULL) { ret->error = "Proxy error: Unable to resolve proxy host name"; sk_addr_free(proxy_addr); return &ret->sock; } sfree(proxy_canonical_name); { char addrbuf[256], *logmsg; sk_getaddr(proxy_addr, addrbuf, lenof(addrbuf)); logmsg = dupprintf("Connecting to %s proxy at %s port %d", proxy_type, addrbuf, conf_get_int(conf, CONF_proxy_port)); plug_log(plug, 2, NULL, 0, logmsg, 0); sfree(logmsg); } /* create the actual socket we will be using, * connected to our proxy server and port. */ ret->sub_socket = sk_new(proxy_addr, conf_get_int(conf, CONF_proxy_port), privport, oobinline, nodelay, keepalive, &ret->plugimpl); if (sk_socket_error(ret->sub_socket) != NULL) return &ret->sock; /* start the proxy negotiation process... */ sk_set_frozen(ret->sub_socket, 0); ret->negotiate(ret, PROXY_CHANGE_NEW); return &ret->sock; } /* no proxy, so just return the direct socket */ return sk_new(addr, port, privport, oobinline, nodelay, keepalive, plug); }
/* * Called to set up the rlogin connection. * * Returns an error message, or NULL on success. * * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ static char *rlogin_init(char *host, int port, char **realhost, int nodelay) { static struct plug_function_table fn_table = { rlogin_closing, rlogin_receive, rlogin_sent }, *fn_table_ptr = &fn_table; SockAddr addr; char *err; /* * Try to find host. */ { char buf[200]; sprintf(buf, "Looking up host \"%.170s\"", host); logevent(buf); } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) return err; if (port < 0) port = 513; /* default rlogin port */ /* * Open socket. */ { char buf[200], addrbuf[100]; sk_getaddr(addr, addrbuf, 100); sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); logevent(buf); } s = sk_new(addr, port, 1, 0, nodelay, &fn_table_ptr); if ((err = sk_socket_error(s))) return err; sk_addr_free(addr); /* * Send local username, remote username, terminal/speed */ { char z = 0; char *p; sk_write(s, &z, 1); sk_write(s, cfg.localusername, strlen(cfg.localusername)); sk_write(s, &z, 1); sk_write(s, cfg.username, strlen(cfg.username)); sk_write(s, &z, 1); sk_write(s, cfg.termtype, strlen(cfg.termtype)); sk_write(s, "/", 1); for (p = cfg.termspeed; isdigit(*p); p++); sk_write(s, cfg.termspeed, p - cfg.termspeed); rlogin_bufsize = sk_write(s, &z, 1); } return NULL; }