Diff

Differences From Artifact [904b019e37]:

To Artifact [65cbcd25f6]:


7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
	arg = ssh_tty_parse_boolean(val);
	break;
    }
    ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
    ssh2_pkt_adduint32(pktout, arg);
}

static void ssh2_maybe_setup_x11(struct ssh_channel *c, struct Packet *pktin,
				 void *ctx)
{
    struct ssh2_maybe_setup_x11_state {
	int crLine;
    };
    Ssh ssh = c->ssh;
    struct Packet *pktout;
    crStateP(ssh2_maybe_setup_x11_state, ctx);

    crBeginState;

    /*
     * Potentially enable X11 forwarding.
     */
    if (ssh->mainchan && !ssh->ncmode && conf_get_int(ssh->conf, CONF_x11_forward) &&
	(ssh->x11disp = x11_setup_display(conf_get_str(ssh->conf, CONF_x11_display),
					  conf_get_int(ssh->conf, CONF_x11_auth), ssh->conf))) {
	logevent("Requesting X11 forwarding");
	pktout = ssh2_chanreq_init(ssh->mainchan, "x11-req",
				   ssh2_maybe_setup_x11, s);
	ssh2_pkt_addbool(pktout, 0);	       /* many connections */
	ssh2_pkt_addstring(pktout, ssh->x11disp->remoteauthprotoname);
	/*
	 * Note that while we blank the X authentication data here, we don't
	 * take any special action to blank the start of an X11 channel,
	 * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
	 * without having session blanking enabled is likely to leak your
	 * cookie into the log.
	 */
	dont_log_password(ssh, pktout, PKTLOG_BLANK);
	ssh2_pkt_addstring(pktout, ssh->x11disp->remoteauthdatastring);
	end_log_omission(ssh, pktout);
	ssh2_pkt_adduint32(pktout, ssh->x11disp->screennum);
	ssh2_pkt_send(ssh, pktout);

	crWaitUntilV(pktin);

	if (pktin) {
	    if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
		logevent("X11 forwarding enabled");
		ssh->X11_fwd_enabled = TRUE;
	    } else
		logevent("X11 forwarding refused");
	}
    }
    crFinishFreeV;
}

static void ssh2_maybe_setup_agent(struct ssh_channel *c, struct Packet *pktin,
				   void *ctx)
{
    struct ssh2_maybe_setup_agent_state {
	int crLine;
    };
    Ssh ssh = c->ssh;
    struct Packet *pktout;
    crStateP(ssh2_maybe_setup_agent_state, ctx);

    crBeginState;

    if (ssh->mainchan && !ssh->ncmode && conf_get_int(ssh->conf, CONF_agentfwd) && agent_exists()) {
	logevent("Requesting OpenSSH-style agent forwarding");
	pktout = ssh2_chanreq_init(ssh->mainchan, "auth-agent-req@openssh.com",
				   ssh2_maybe_setup_agent, s);
	ssh2_pkt_send(ssh, pktout);

	crWaitUntilV(pktin);

	if (pktin) {
	    if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
		logevent("Agent forwarding enabled");
		ssh->agentfwd_enabled = TRUE;
	    } else
		logevent("Agent forwarding refused");
	}
    }
    crFinishFreeV;
}

static void ssh2_maybe_setup_pty(struct ssh_channel *c, struct Packet *pktin,
				 void *ctx)
{
    struct ssh2_maybe_setup_pty_state {
	int crLine;
    };
    Ssh ssh = c->ssh;
    struct Packet *pktout;
    crStateP(ssh2_maybe_setup_pty_state, ctx);

    crBeginState;

    if (ssh->mainchan && !ssh->ncmode && !conf_get_int(ssh->conf, CONF_nopty)) {
	/* Unpick the terminal-speed string. */
	/* XXX perhaps we should allow no speeds to be sent. */
        ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
	sscanf(conf_get_str(ssh->conf, CONF_termspeed), "%d,%d", &ssh->ospeed, &ssh->ispeed);
	/* Build the pty request. */
	pktout = ssh2_chanreq_init(ssh->mainchan, "pty-req",
				   ssh2_maybe_setup_pty, s);
	ssh2_pkt_addstring(pktout, conf_get_str(ssh->conf, CONF_termtype));
	ssh2_pkt_adduint32(pktout, ssh->term_width);
	ssh2_pkt_adduint32(pktout, ssh->term_height);
	ssh2_pkt_adduint32(pktout, 0);	       /* pixel width */
	ssh2_pkt_adduint32(pktout, 0);	       /* pixel height */
	ssh2_pkt_addstring_start(pktout);
	parse_ttymodes(ssh, ssh2_send_ttymode, (void *)pktout);
	ssh2_pkt_addbyte(pktout, SSH2_TTY_OP_ISPEED);
	ssh2_pkt_adduint32(pktout, ssh->ispeed);
	ssh2_pkt_addbyte(pktout, SSH2_TTY_OP_OSPEED);
	ssh2_pkt_adduint32(pktout, ssh->ospeed);
	ssh2_pkt_addstring_data(pktout, "\0", 1); /* TTY_OP_END */
	ssh2_pkt_send(ssh, pktout);
	ssh->state = SSH_STATE_INTERMED;

	crWaitUntilV(pktin);

	if (pktin) {
	    if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
		logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
			  ssh->ospeed, ssh->ispeed);
		ssh->got_pty = TRUE;
	    } else {
		c_write_str(ssh, "Server refused to allocate pty\r\n");
		ssh->editing = ssh->echoing = 1;
	    }
	}
    } else {
	ssh->editing = ssh->echoing = 1;
    }
    crFinishFreeV;
}

static void ssh2_setup_env(struct ssh_channel *c, struct Packet *pktin,
			   void *ctx)
{
    struct ssh2_setup_env_state {







|
|

|




|



<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|



|


|




|



<
|
|
|
|

|

|
|
|
|
|
|
|
|



|


|




|



<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
<
<
|







7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482






7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525

7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555

7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589


7590
7591
7592
7593
7594
7595
7596
7597
	arg = ssh_tty_parse_boolean(val);
	break;
    }
    ssh2_pkt_addbyte(pktout, ssh_ttymodes[i].opcode);
    ssh2_pkt_adduint32(pktout, arg);
}

static void ssh2_setup_x11(struct ssh_channel *c, struct Packet *pktin,
                           void *ctx)
{
    struct ssh2_setup_x11_state {
	int crLine;
    };
    Ssh ssh = c->ssh;
    struct Packet *pktout;
    crStateP(ssh2_setup_x11_state, ctx);

    crBeginState;







    logevent("Requesting X11 forwarding");
    pktout = ssh2_chanreq_init(ssh->mainchan, "x11-req",
                               ssh2_setup_x11, s);
    ssh2_pkt_addbool(pktout, 0);	       /* many connections */
    ssh2_pkt_addstring(pktout, ssh->x11disp->remoteauthprotoname);
    /*
     * Note that while we blank the X authentication data here, we don't
     * take any special action to blank the start of an X11 channel,
     * so using MIT-MAGIC-COOKIE-1 and actually opening an X connection
     * without having session blanking enabled is likely to leak your
     * cookie into the log.
     */
    dont_log_password(ssh, pktout, PKTLOG_BLANK);
    ssh2_pkt_addstring(pktout, ssh->x11disp->remoteauthdatastring);
    end_log_omission(ssh, pktout);
    ssh2_pkt_adduint32(pktout, ssh->x11disp->screennum);
    ssh2_pkt_send(ssh, pktout);

    crWaitUntilV(pktin);

    if (pktin) {
        if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
            logevent("X11 forwarding enabled");
            ssh->X11_fwd_enabled = TRUE;
        } else
            logevent("X11 forwarding refused");
    }

    crFinishFreeV;
}

static void ssh2_setup_agent(struct ssh_channel *c, struct Packet *pktin,
				   void *ctx)
{
    struct ssh2_setup_agent_state {
	int crLine;
    };
    Ssh ssh = c->ssh;
    struct Packet *pktout;
    crStateP(ssh2_setup_agent_state, ctx);

    crBeginState;


    logevent("Requesting OpenSSH-style agent forwarding");
    pktout = ssh2_chanreq_init(ssh->mainchan, "auth-agent-req@openssh.com",
                               ssh2_setup_agent, s);
    ssh2_pkt_send(ssh, pktout);

    crWaitUntilV(pktin);

    if (pktin) {
        if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
            logevent("Agent forwarding enabled");
            ssh->agentfwd_enabled = TRUE;
        } else
            logevent("Agent forwarding refused");
    }

    crFinishFreeV;
}

static void ssh2_setup_pty(struct ssh_channel *c, struct Packet *pktin,
				 void *ctx)
{
    struct ssh2_setup_pty_state {
	int crLine;
    };
    Ssh ssh = c->ssh;
    struct Packet *pktout;
    crStateP(ssh2_setup_pty_state, ctx);

    crBeginState;


    /* Unpick the terminal-speed string. */
    /* XXX perhaps we should allow no speeds to be sent. */
    ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
    sscanf(conf_get_str(ssh->conf, CONF_termspeed), "%d,%d", &ssh->ospeed, &ssh->ispeed);
    /* Build the pty request. */
    pktout = ssh2_chanreq_init(ssh->mainchan, "pty-req",
                               ssh2_setup_pty, s);
    ssh2_pkt_addstring(pktout, conf_get_str(ssh->conf, CONF_termtype));
    ssh2_pkt_adduint32(pktout, ssh->term_width);
    ssh2_pkt_adduint32(pktout, ssh->term_height);
    ssh2_pkt_adduint32(pktout, 0);	       /* pixel width */
    ssh2_pkt_adduint32(pktout, 0);	       /* pixel height */
    ssh2_pkt_addstring_start(pktout);
    parse_ttymodes(ssh, ssh2_send_ttymode, (void *)pktout);
    ssh2_pkt_addbyte(pktout, SSH2_TTY_OP_ISPEED);
    ssh2_pkt_adduint32(pktout, ssh->ispeed);
    ssh2_pkt_addbyte(pktout, SSH2_TTY_OP_OSPEED);
    ssh2_pkt_adduint32(pktout, ssh->ospeed);
    ssh2_pkt_addstring_data(pktout, "\0", 1); /* TTY_OP_END */
    ssh2_pkt_send(ssh, pktout);
    ssh->state = SSH_STATE_INTERMED;

    crWaitUntilV(pktin);

    if (pktin) {
        if (pktin->type == SSH2_MSG_CHANNEL_SUCCESS) {
            logeventf(ssh, "Allocated pty (ospeed %dbps, ispeed %dbps)",
                      ssh->ospeed, ssh->ispeed);
            ssh->got_pty = TRUE;
        } else {
            c_write_str(ssh, "Server refused to allocate pty\r\n");
            ssh->editing = ssh->echoing = 1;
        }
    }



    crFinishFreeV;
}

static void ssh2_setup_env(struct ssh_channel *c, struct Packet *pktin,
			   void *ctx)
{
    struct ssh2_setup_env_state {
7617
7618
7619
7620
7621
7622
7623
7624

7625
7626
7627
7628
7629
7630
7631
    /*
     * Send environment variables.
     * 
     * Simplest thing here is to send all the requests at once, and
     * then wait for a whole bunch of successes or failures.
     */
    s->num_env = 0;
    if (ssh->mainchan && !ssh->ncmode) {

	char *key, *val;

	for (val = conf_get_str_strs(ssh->conf, CONF_environmt, NULL, &key);
	     val != NULL;
	     val = conf_get_str_strs(ssh->conf, CONF_environmt, key, &key)) {
	    pktout = ssh2_chanreq_init(ssh->mainchan, "env", ssh2_setup_env, s);
	    ssh2_pkt_addstring(pktout, key);







<
>







7607
7608
7609
7610
7611
7612
7613

7614
7615
7616
7617
7618
7619
7620
7621
    /*
     * Send environment variables.
     * 
     * Simplest thing here is to send all the requests at once, and
     * then wait for a whole bunch of successes or failures.
     */
    s->num_env = 0;

    {
	char *key, *val;

	for (val = conf_get_str_strs(ssh->conf, CONF_environmt, NULL, &key);
	     val != NULL;
	     val = conf_get_str_strs(ssh->conf, CONF_environmt, key, &key)) {
	    pktout = ssh2_chanreq_init(ssh->mainchan, "env", ssh2_setup_env, s);
	    ssh2_pkt_addstring(pktout, key);
9240
9241
9242
9243
9244
9245
9246






9247
9248
9249
9250
9251

9252
9253
9254
9255
9256

9257



9258
9259
9260
9261

9262
9263
9264
9265
9266
9267
9268
9269
     * Send the CHANNEL_REQUESTS for the main channel.  Each one is
     * handled by its own little asynchronous co-routine.
     */

    /*
     * Potentially enable X11 forwarding.
     */






    ssh2_maybe_setup_x11(ssh->mainchan, NULL, NULL);

    /*
     * Potentially enable agent forwarding.
     */

    ssh2_maybe_setup_agent(ssh->mainchan, NULL, NULL);

    /*
     * Now allocate a pty for the session.
     */

    ssh2_maybe_setup_pty(ssh->mainchan, NULL, NULL);




    /*
     * Send environment variables.
     */

    ssh2_setup_env(ssh->mainchan, NULL, NULL);

    /*
     * Start a shell or a remote command. We may have to attempt
     * this twice if the config data has provided a second choice
     * of command.
     */
    if (ssh->mainchan && !ssh->ncmode) while (1) {







>
>
>
>
>
>
|




>
|




>
|
>
>
>




>
|







9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
     * Send the CHANNEL_REQUESTS for the main channel.  Each one is
     * handled by its own little asynchronous co-routine.
     */

    /*
     * Potentially enable X11 forwarding.
     */
    /*
     * Potentially enable X11 forwarding.
     */
    if (ssh->mainchan && !ssh->ncmode && conf_get_int(ssh->conf, CONF_x11_forward) &&
	(ssh->x11disp = x11_setup_display(conf_get_str(ssh->conf, CONF_x11_display),
					  conf_get_int(ssh->conf, CONF_x11_auth), ssh->conf)))
        ssh2_setup_x11(ssh->mainchan, NULL, NULL);

    /*
     * Potentially enable agent forwarding.
     */
    if (ssh->mainchan && !ssh->ncmode && conf_get_int(ssh->conf, CONF_agentfwd) && agent_exists())
        ssh2_setup_agent(ssh->mainchan, NULL, NULL);

    /*
     * Now allocate a pty for the session.
     */
    if (ssh->mainchan && !ssh->ncmode && !conf_get_int(ssh->conf, CONF_nopty)) {
        ssh2_setup_pty(ssh->mainchan, NULL, NULL);
    } else {
	ssh->editing = ssh->echoing = 1;
    }

    /*
     * Send environment variables.
     */
    if (ssh->mainchan && !ssh->ncmode)
        ssh2_setup_env(ssh->mainchan, NULL, NULL);

    /*
     * Start a shell or a remote command. We may have to attempt
     * this twice if the config data has provided a second choice
     * of command.
     */
    if (ssh->mainchan && !ssh->ncmode) while (1) {