Ignore:
Timestamp:
Jan 9, 2017, 11:09:38 AM (2 years ago)
Author:
jrpelegrina
Message:

Update new version: 3.15.02

File:
1 edited

Legend:

Unmodified
Added
Removed
  • filezilla/trunk/fuentes/src/putty/unix/uxproxy.c

    r130 r3185  
    2222    /* the above variable absolutely *must* be the first in this structure */
    2323
    24     int to_cmd, from_cmd;              /* fds */
     24    int to_cmd, from_cmd, cmd_err;     /* fds */
    2525
    2626    char *error;
     
    3030    bufchain pending_output_data;
    3131    bufchain pending_input_data;
     32    bufchain pending_error_data;
    3233    enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
    3334};
     
    3839 * Trees to look up the pipe fds in.
    3940 */
    40 static tree234 *localproxy_by_fromfd, *localproxy_by_tofd;
     41static tree234 *localproxy_by_fromfd;
     42static tree234 *localproxy_by_tofd;
     43static tree234 *localproxy_by_errfd;
    4144static int localproxy_fromfd_cmp(void *av, void *bv)
    4245{
     
    7679        return -1;
    7780    if (a > b->to_cmd)
     81        return +1;
     82    return 0;
     83}
     84static int localproxy_errfd_cmp(void *av, void *bv)
     85{
     86    Local_Proxy_Socket a = (Local_Proxy_Socket)av;
     87    Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
     88    if (a->cmd_err < b->cmd_err)
     89        return -1;
     90    if (a->cmd_err > b->cmd_err)
     91        return +1;
     92    return 0;
     93}
     94static int localproxy_errfd_find(void *av, void *bv)
     95{
     96    int a = *(int *)av;
     97    Local_Proxy_Socket b = (Local_Proxy_Socket)bv;
     98    if (a < b->cmd_err)
     99        return -1;
     100    if (a > b->cmd_err)
    78101        return +1;
    79102    return 0;
     
    104127    uxsel_del(ps->from_cmd);
    105128    close(ps->from_cmd);
     129
     130    del234(localproxy_by_errfd, ps);
     131    uxsel_del(ps->cmd_err);
     132    close(ps->cmd_err);
     133
     134    bufchain_clear(&ps->pending_input_data);
     135    bufchain_clear(&ps->pending_output_data);
     136    bufchain_clear(&ps->pending_error_data);
    106137
    107138    sfree(ps);
     
    208239
    209240    if (!(s = find234(localproxy_by_fromfd, &fd, localproxy_fromfd_find)) &&
     241        !(s = find234(localproxy_by_fromfd, &fd, localproxy_errfd_find)) &&
    210242        !(s = find234(localproxy_by_tofd, &fd, localproxy_tofd_find)) )
    211243        return 1;                      /* boggle */
    212244
    213245    if (event == 1) {
    214         assert(fd == s->from_cmd);
    215         ret = read(fd, buf, sizeof(buf));
    216         if (ret < 0) {
    217             return plug_closing(s->plug, strerror(errno), errno, 0);
    218         } else if (ret == 0) {
    219             return plug_closing(s->plug, NULL, 0, 0);
    220         } else {
    221             return plug_receive(s->plug, 0, buf, ret);
    222         }
     246        if (fd == s->cmd_err) {
     247            ret = read(fd, buf, sizeof(buf));
     248            if (ret > 0)
     249                log_proxy_stderr(s->plug, &s->pending_error_data, buf, ret);
     250        } else {
     251            assert(fd == s->from_cmd);
     252            ret = read(fd, buf, sizeof(buf));
     253            if (ret < 0) {
     254                return plug_closing(s->plug, strerror(errno), errno, 0);
     255            } else if (ret == 0) {
     256                return plug_closing(s->plug, NULL, 0, 0);
     257            } else {
     258                return plug_receive(s->plug, 0, buf, ret);
     259            }
     260        }
    223261    } else if (event == 2) {
    224262        assert(fd == s->to_cmd);
     
    251289
    252290    Local_Proxy_Socket ret;
    253     int to_cmd_pipe[2], from_cmd_pipe[2], pid;
    254 
    255     if (conf_get_int(conf, CONF_proxy_type) != PROXY_CMD)
     291    int to_cmd_pipe[2], from_cmd_pipe[2], cmd_err_pipe[2], pid, proxytype;
     292
     293    proxytype = conf_get_int(conf, CONF_proxy_type);
     294    if (proxytype != PROXY_CMD && proxytype != PROXY_FUZZ)
    256295        return NULL;
    257 
    258     cmd = format_telnet_command(addr, port, conf);
    259296
    260297    ret = snew(struct Socket_localproxy_tag);
     
    266303    bufchain_init(&ret->pending_input_data);
    267304    bufchain_init(&ret->pending_output_data);
    268 
    269     /*
    270      * Create the pipes to the proxy command, and spawn the proxy
    271      * command process.
    272      */
    273     if (pipe(to_cmd_pipe) < 0 ||
    274         pipe(from_cmd_pipe) < 0) {
    275         ret->error = dupprintf("pipe: %s", strerror(errno));
    276         sfree(cmd);
    277         return (Socket)ret;
    278     }
    279     cloexec(to_cmd_pipe[1]);
    280     cloexec(from_cmd_pipe[0]);
    281 
    282     pid = fork();
    283 
    284     if (pid < 0) {
    285         ret->error = dupprintf("fork: %s", strerror(errno));
    286         sfree(cmd);
    287         return (Socket)ret;
    288     } else if (pid == 0) {
    289         close(0);
    290         close(1);
    291         dup2(to_cmd_pipe[0], 0);
    292         dup2(from_cmd_pipe[1], 1);
     305    bufchain_init(&ret->pending_error_data);
     306
     307    if (proxytype == PROXY_CMD) {
     308        cmd = format_telnet_command(addr, port, conf);
     309
     310        if (flags & FLAG_STDERR) {
     311            /* If we have a sensible stderr, the proxy command can
     312             * send its own standard error there, so we won't
     313             * interfere. */
     314            cmd_err_pipe[0] = cmd_err_pipe[1] = -1;
     315        } else {
     316            /* If we don't have a sensible stderr, we should catch the
     317             * proxy command's standard error to put in our event
     318             * log. */
     319            cmd_err_pipe[0] = cmd_err_pipe[1] = 0;
     320        }
     321
     322        {
     323            char *logmsg = dupprintf("Starting local proxy command: %s", cmd);
     324            plug_log(plug, 2, NULL, 0, logmsg, 0);
     325            sfree(logmsg);
     326        }
     327
     328        /*
     329         * Create the pipes to the proxy command, and spawn the proxy
     330         * command process.
     331         */
     332        if (pipe(to_cmd_pipe) < 0 ||
     333            pipe(from_cmd_pipe) < 0 ||
     334            (cmd_err_pipe[0] == 0 && pipe(cmd_err_pipe) < 0)) {
     335            ret->error = dupprintf("pipe: %s", strerror(errno));
     336            sfree(cmd);
     337            return (Socket)ret;
     338        }
     339        cloexec(to_cmd_pipe[1]);
     340        cloexec(from_cmd_pipe[0]);
     341        if (cmd_err_pipe[0] >= 0)
     342            cloexec(cmd_err_pipe[0]);
     343
     344        pid = fork();
     345
     346        if (pid < 0) {
     347            ret->error = dupprintf("fork: %s", strerror(errno));
     348            sfree(cmd);
     349            return (Socket)ret;
     350        } else if (pid == 0) {
     351            close(0);
     352            close(1);
     353            dup2(to_cmd_pipe[0], 0);
     354            dup2(from_cmd_pipe[1], 1);
     355            close(to_cmd_pipe[0]);
     356            close(from_cmd_pipe[1]);
     357            if (cmd_err_pipe[0] >= 0) {
     358                dup2(cmd_err_pipe[1], 2);
     359                close(cmd_err_pipe[1]);
     360            }
     361            noncloexec(0);
     362            noncloexec(1);
     363            execl("/bin/sh", "sh", "-c", cmd, (void *)NULL);
     364            _exit(255);
     365        }
     366
     367        sfree(cmd);
     368
    293369        close(to_cmd_pipe[0]);
    294370        close(from_cmd_pipe[1]);
    295         noncloexec(0);
    296         noncloexec(1);
    297         execl("/bin/sh", "sh", "-c", cmd, (void *)NULL);
    298         _exit(255);
     371        if (cmd_err_pipe[0] >= 0)
     372            close(cmd_err_pipe[1]);
     373
     374        ret->to_cmd = to_cmd_pipe[1];
     375        ret->from_cmd = from_cmd_pipe[0];
     376        ret->cmd_err = cmd_err_pipe[0];
     377    } else {
     378        cmd = format_telnet_command(addr, port, conf);
     379        ret->to_cmd = open("/dev/null", O_WRONLY);
     380        if (ret->to_cmd == -1) {
     381            ret->error = dupprintf("/dev/null: %s", strerror(errno));
     382            sfree(cmd);
     383            return (Socket)ret;
     384        }
     385        ret->from_cmd = open(cmd, O_RDONLY);
     386        if (ret->from_cmd == -1) {
     387            ret->error = dupprintf("%s: %s", cmd, strerror(errno));
     388            sfree(cmd);
     389            return (Socket)ret;
     390        }
     391        sfree(cmd);
     392        ret->cmd_err = -1;
    299393    }
    300 
    301     sfree(cmd);
    302 
    303     close(to_cmd_pipe[0]);
    304     close(from_cmd_pipe[1]);
    305 
    306     ret->to_cmd = to_cmd_pipe[1];
    307     ret->from_cmd = from_cmd_pipe[0];
    308394
    309395    if (!localproxy_by_fromfd)
     
    311397    if (!localproxy_by_tofd)
    312398        localproxy_by_tofd = newtree234(localproxy_tofd_cmp);
     399    if (!localproxy_by_errfd)
     400        localproxy_by_errfd = newtree234(localproxy_errfd_cmp);
    313401
    314402    add234(localproxy_by_fromfd, ret);
    315403    add234(localproxy_by_tofd, ret);
     404    if (ret->cmd_err >= 0)
     405        add234(localproxy_by_errfd, ret);
    316406
    317407    uxsel_set(ret->from_cmd, 1, localproxy_select_result);
     408    if (ret->cmd_err >= 0)
     409        uxsel_set(ret->cmd_err, 1, localproxy_select_result);
    318410
    319411    /* We are responsible for this and don't need it any more */
Note: See TracChangeset for help on using the changeset viewer.