Exemplo n.º 1
0
static void plug_proxy_log(Plug plug, int type, SockAddr addr, int port,
		const char *error_msg, int error_code) {
	Proxy_Plug pp = (Proxy_Plug) plug;
	Proxy_Socket ps = pp->proxy_socket;

	plug_log(ps->plug, type, addr, port, error_msg, error_code);
}
Exemplo n.º 2
0
Arquivo: proxy.c Projeto: Riatre/PuTTY
static void plug_proxy_log(Plug plug, int type, SockAddr addr, int port,
			   const char *error_msg, int error_code)
{
    ProxySocket *ps = FROMFIELD(plug, ProxySocket, plugvt);

    plug_log(ps->plug, type, addr, port, error_msg, error_code);
}
Exemplo n.º 3
0
static void plug_proxy_log(Plug *plug, int type, SockAddr *addr, int port,
			   const char *error_msg, int error_code)
{
    ProxySocket *ps = container_of(plug, ProxySocket, plugimpl);

    plug_log(ps->plug, type, addr, port, error_msg, error_code);
}
Exemplo n.º 4
0
void log_proxy_stderr(Plug plug, bufchain *buf, const void *vdata, int len)
{
    const char *data = (const char *)vdata;
    int pos = 0;
    int msglen;
    char *nlpos, *msg, *fullmsg;

    /*
     * This helper function allows us to collect the data written to a
     * local proxy command's standard error in whatever size chunks we
     * happen to get from its pipe, and whenever we have a complete
     * line, we pass it to plug_log.
     *
     * Prerequisites: a plug to log to, and a bufchain stored
     * somewhere to collect the data in.
     */

    while (pos < len && (nlpos = memchr(data+pos, '\n', len-pos)) != NULL) {
        /*
         * Found a newline in the current input buffer. Append it to
         * the bufchain (which may contain a partial line from last
         * time).
         */
        bufchain_add(buf, data + pos, nlpos - (data + pos));

        /*
         * Collect the resulting line of data and pass it to plug_log.
         */
        msglen = bufchain_size(buf);
        msg = snewn(msglen+1, char);
        bufchain_fetch(buf, msg, msglen);
        bufchain_consume(buf, msglen);
        msg[msglen] = '\0';
        fullmsg = dupprintf("proxy: %s", msg);
        plug_log(plug, 2, NULL, 0, fullmsg, 0);
        sfree(fullmsg);
        sfree(msg);

        /*
         * Advance past the newline.
         */
        pos += (int)(nlpos+1 - (data + pos));
    }

    /*
     * Now any remaining data is a partial line, which we save for
     * next time.
     */
    bufchain_add(buf, data + pos, len - pos);
}
Exemplo n.º 5
0
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;
  }
Exemplo n.º 6
0
Socket platform_new_connection(SockAddr addr, const char *hostname,
			       int port, int privport,
			       int oobinline, int nodelay, int keepalive,
			       Plug plug, Conf *conf)
{
    char *cmd;

    static const struct socket_function_table socket_fn_table = {
	sk_localproxy_plug,
	sk_localproxy_close,
	sk_localproxy_write,
	sk_localproxy_write_oob,
	sk_localproxy_write_eof,
	sk_localproxy_flush,
	sk_localproxy_set_frozen,
	sk_localproxy_socket_error,
        NULL, /* peer_info */
    };

    Local_Proxy_Socket ret;
    int to_cmd_pipe[2], from_cmd_pipe[2], cmd_err_pipe[2], pid, proxytype;

    proxytype = conf_get_int(conf, CONF_proxy_type);
    if (proxytype != PROXY_CMD && proxytype != PROXY_FUZZ)
	return NULL;

    ret = snew(struct Socket_localproxy_tag);
    ret->fn = &socket_fn_table;
    ret->plug = plug;
    ret->error = NULL;
    ret->outgoingeof = EOF_NO;

    bufchain_init(&ret->pending_input_data);
    bufchain_init(&ret->pending_output_data);
    bufchain_init(&ret->pending_error_data);

    if (proxytype == PROXY_CMD) {
	cmd = format_telnet_command(addr, port, conf);

        if (flags & FLAG_STDERR) {
            /* If we have a sensible stderr, the proxy command can
             * send its own standard error there, so we won't
             * interfere. */
            cmd_err_pipe[0] = cmd_err_pipe[1] = -1;
        } else {
            /* If we don't have a sensible stderr, we should catch the
             * proxy command's standard error to put in our event
             * log. */
            cmd_err_pipe[0] = cmd_err_pipe[1] = 0;
        }

        {
            char *logmsg = dupprintf("Starting local proxy command: %s", cmd);
            plug_log(plug, 2, NULL, 0, logmsg, 0);
            sfree(logmsg);
        }

	/*
	 * Create the pipes to the proxy command, and spawn the proxy
	 * command process.
	 */
	if (pipe(to_cmd_pipe) < 0 ||
	    pipe(from_cmd_pipe) < 0 ||
            (cmd_err_pipe[0] == 0 && pipe(cmd_err_pipe) < 0)) {
	    ret->error = dupprintf("pipe: %s", strerror(errno));
	    sfree(cmd);
	    return (Socket)ret;
	}
	cloexec(to_cmd_pipe[1]);
	cloexec(from_cmd_pipe[0]);
	if (cmd_err_pipe[0] >= 0)
            cloexec(cmd_err_pipe[0]);

	pid = fork();

	if (pid < 0) {
	    ret->error = dupprintf("fork: %s", strerror(errno));
	    sfree(cmd);
	    return (Socket)ret;
	} else if (pid == 0) {
	    close(0);
	    close(1);
	    dup2(to_cmd_pipe[0], 0);
	    dup2(from_cmd_pipe[1], 1);
	    close(to_cmd_pipe[0]);
	    close(from_cmd_pipe[1]);
	    if (cmd_err_pipe[0] >= 0) {
                dup2(cmd_err_pipe[1], 2);
                close(cmd_err_pipe[1]);
            }
	    noncloexec(0);
	    noncloexec(1);
	    execl("/bin/sh", "sh", "-c", cmd, (void *)NULL);
	    _exit(255);
	}

	sfree(cmd);

	close(to_cmd_pipe[0]);
	close(from_cmd_pipe[1]);
        if (cmd_err_pipe[0] >= 0)
            close(cmd_err_pipe[1]);

	ret->to_cmd = to_cmd_pipe[1];
	ret->from_cmd = from_cmd_pipe[0];
	ret->cmd_err = cmd_err_pipe[0];
    } else {
	cmd = format_telnet_command(addr, port, conf);
	ret->to_cmd = open("/dev/null", O_WRONLY);
	if (ret->to_cmd == -1) {
	    ret->error = dupprintf("/dev/null: %s", strerror(errno));
	    sfree(cmd);
	    return (Socket)ret;
	}
	ret->from_cmd = open(cmd, O_RDONLY);
	if (ret->from_cmd == -1) {
	    ret->error = dupprintf("%s: %s", cmd, strerror(errno));
	    sfree(cmd);
	    return (Socket)ret;
	}
	sfree(cmd);
	ret->cmd_err = -1;
    }

    if (!localproxy_by_fromfd)
	localproxy_by_fromfd = newtree234(localproxy_fromfd_cmp);
    if (!localproxy_by_tofd)
	localproxy_by_tofd = newtree234(localproxy_tofd_cmp);
    if (!localproxy_by_errfd)
	localproxy_by_errfd = newtree234(localproxy_errfd_cmp);

    add234(localproxy_by_fromfd, ret);
    add234(localproxy_by_tofd, ret);
    if (ret->cmd_err >= 0)
        add234(localproxy_by_errfd, ret);

    uxsel_set(ret->from_cmd, 1, localproxy_select_result);
    if (ret->cmd_err >= 0)
        uxsel_set(ret->cmd_err, 1, localproxy_select_result);

    /* We are responsible for this and don't need it any more */
    sk_addr_free(addr);

    return (Socket) ret;
}
Exemplo n.º 7
0
Socket platform_new_connection(SockAddr addr,
                               const char *hostname,
                               int port,
                               int privport,
                               int oobinline,
                               int nodelay,
                               int keepalive,
                               Plug plug,
                               Conf *conf)
{
  char *cmd;
  HANDLE us_to_cmd, cmd_from_us;
  HANDLE us_from_cmd, cmd_to_us;
  HANDLE us_from_cmd_err, cmd_err_to_us;
  SECURITY_ATTRIBUTES sa;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
    return NULL;

  cmd = format_telnet_command(addr, port, conf);

  /* We are responsible for this and don't need it any more */
  sk_addr_free(addr);

  {
    char *msg = dupprintf("Starting local proxy command: %s", cmd);
    plug_log(plug, 2, NULL, 0, msg, 0);
    sfree(msg);
  }

  /*
   * Create the pipes to the proxy command, and spawn the proxy
   * command process.
   */
  sa.nLength = sizeof(sa);
  sa.lpSecurityDescriptor = NULL; /* default */
  sa.bInheritHandle = TRUE;
  if (!CreatePipe(&us_from_cmd, &cmd_to_us, &sa, 0)) {
    Socket ret =
        new_error_socket("Unable to create pipes for proxy command", plug);
    sfree(cmd);
    return ret;
  }

  if (!CreatePipe(&cmd_from_us, &us_to_cmd, &sa, 0)) {
    Socket ret =
        new_error_socket("Unable to create pipes for proxy command", plug);
    sfree(cmd);
    CloseHandle(us_from_cmd);
    CloseHandle(cmd_to_us);
    return ret;
  }

  if (flags & FLAG_STDERR) {
    /* If we have a sensible stderr, the proxy command can send
     * its own standard error there, so we won't interfere. */
    us_from_cmd_err = cmd_err_to_us = NULL;
  } else {
    /* If we don't have a sensible stderr, we should catch the
     * proxy command's standard error to put in our event log. */
    if (!CreatePipe(&us_from_cmd_err, &cmd_err_to_us, &sa, 0)) {
      Socket ret =
          new_error_socket("Unable to create pipes for proxy command", plug);
      sfree(cmd);
      CloseHandle(us_from_cmd);
      CloseHandle(cmd_to_us);
      CloseHandle(us_to_cmd);
      CloseHandle(cmd_from_us);
      return ret;
    }
  }

  SetHandleInformation(us_to_cmd, HANDLE_FLAG_INHERIT, 0);
  SetHandleInformation(us_from_cmd, HANDLE_FLAG_INHERIT, 0);
  if (us_from_cmd_err != NULL)
    SetHandleInformation(us_from_cmd_err, HANDLE_FLAG_INHERIT, 0);

  si.cb = sizeof(si);
  si.lpReserved = NULL;
  si.lpDesktop = NULL;
  si.lpTitle = NULL;
  si.dwFlags = STARTF_USESTDHANDLES;
  si.cbReserved2 = 0;
  si.lpReserved2 = NULL;
  si.hStdInput = cmd_from_us;
  si.hStdOutput = cmd_to_us;
  si.hStdError = cmd_err_to_us;
  CreateProcess(NULL,
                cmd,
                NULL,
                NULL,
                TRUE,
                CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS,
                NULL,
                NULL,
                &si,
                &pi);
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);

  sfree(cmd);

  CloseHandle(cmd_from_us);
  CloseHandle(cmd_to_us);

  if (cmd_err_to_us != NULL)
    CloseHandle(cmd_err_to_us);

  return make_handle_socket(
      us_to_cmd, us_from_cmd, us_from_cmd_err, plug, FALSE);
}
Exemplo n.º 8
0
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);
}