Diff

Differences From Artifact [e7555f46a5]:

To Artifact [acd11f96c5]:


5608
5609
5610
5611
5612
5613
5614


5615
5616

5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646































5647
5648
5649
5650
5651

5652
5653
5654
5655
5656
5657
5658
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617

5618
5619





























5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654

5655
5656
5657
5658
5659
5660
5661
5662







+
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+








    /*
     * Now we're authenticated for the connection protocol. The
     * connection protocol will automatically have started at this
     * point; there's no need to send SERVICE_REQUEST.
     */

    ssh->channels = newtree234(ssh_channelcmp);

    /*
     * So now create a channel with a session in it.
     * Create the main session channel.
     */
    ssh->channels = newtree234(ssh_channelcmp);
    ssh->mainchan = snew(struct ssh_channel);
    ssh->mainchan->ssh = ssh;
    ssh->mainchan->localid = alloc_channel_id(ssh);
    ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_OPEN);
    ssh2_pkt_addstring(ssh, "session");
    ssh2_pkt_adduint32(ssh, ssh->mainchan->localid);
    ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
    ssh2_pkt_adduint32(ssh, ssh->mainchan->v.v2.locwindow);/* our window size */
    ssh2_pkt_adduint32(ssh, 0x4000UL);      /* our max pkt size */
    ssh2_pkt_send(ssh);
    crWaitUntilV(ispkt);
    if (ssh->pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
	bombout(("Server refused to open a session"));
	crStopV;
	/* FIXME: error data comes back in FAILURE packet */
    }
    if (ssh_pkt_getuint32(ssh) != ssh->mainchan->localid) {
	bombout(("Server's channel confirmation cited wrong channel"));
	crStopV;
    }
    ssh->mainchan->remoteid = ssh_pkt_getuint32(ssh);
    ssh->mainchan->type = CHAN_MAINSESSION;
    ssh->mainchan->closes = 0;
    ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(ssh);
    ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(ssh);
    bufchain_init(&ssh->mainchan->v.v2.outbuffer);
    add234(ssh->channels, ssh->mainchan);
    logevent("Opened channel for session");
    if (!ssh->cfg.ssh_no_shell) {
	ssh->mainchan = snew(struct ssh_channel);
	ssh->mainchan->ssh = ssh;
	ssh->mainchan->localid = alloc_channel_id(ssh);
	ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_OPEN);
	ssh2_pkt_addstring(ssh, "session");
	ssh2_pkt_adduint32(ssh, ssh->mainchan->localid);
	ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
	ssh2_pkt_adduint32(ssh, ssh->mainchan->v.v2.locwindow);/* our window size */
	ssh2_pkt_adduint32(ssh, 0x4000UL);      /* our max pkt size */
	ssh2_pkt_send(ssh);
	crWaitUntilV(ispkt);
	if (ssh->pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
	    bombout(("Server refused to open a session"));
	    crStopV;
	    /* FIXME: error data comes back in FAILURE packet */
	}
	if (ssh_pkt_getuint32(ssh) != ssh->mainchan->localid) {
	    bombout(("Server's channel confirmation cited wrong channel"));
	    crStopV;
	}
	ssh->mainchan->remoteid = ssh_pkt_getuint32(ssh);
	ssh->mainchan->type = CHAN_MAINSESSION;
	ssh->mainchan->closes = 0;
	ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(ssh);
	ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(ssh);
	bufchain_init(&ssh->mainchan->v.v2.outbuffer);
	add234(ssh->channels, ssh->mainchan);
	logevent("Opened channel for session");
    } else
	ssh->mainchan = NULL;

    /*
     * Potentially enable X11 forwarding.
     */
    if (ssh->cfg.x11_forward) {
    if (ssh->mainchan && ssh->cfg.x11_forward) {
	char proto[20], data[64];
	logevent("Requesting X11 forwarding");
	ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
				       data, sizeof(data), ssh->cfg.x11_auth);
        x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
	ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
	ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
5857
5858
5859
5860
5861
5862
5863
5864

5865
5866
5867
5868
5869
5870
5871
5861
5862
5863
5864
5865
5866
5867

5868
5869
5870
5871
5872
5873
5874
5875







-
+







	    }
	}
    }

    /*
     * Potentially enable agent forwarding.
     */
    if (ssh->cfg.agentfwd && agent_exists()) {
    if (ssh->mainchan && ssh->cfg.agentfwd && agent_exists()) {
	logevent("Requesting OpenSSH-style agent forwarding");
	ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
	ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
	ssh2_pkt_addstring(ssh, "auth-agent-req@openssh.com");
	ssh2_pkt_addbool(ssh, 1);	       /* want reply */
	ssh2_pkt_send(ssh);

5893
5894
5895
5896
5897
5898
5899
5900

5901
5902
5903
5904
5905
5906
5907
5897
5898
5899
5900
5901
5902
5903

5904
5905
5906
5907
5908
5909
5910
5911







-
+







	    ssh->agentfwd_enabled = TRUE;
	}
    }

    /*
     * Now allocate a pty for the session.
     */
    if (!ssh->cfg.nopty) {
    if (ssh->mainchan && !ssh->cfg.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(ssh->cfg.termspeed, "%d,%d", &ssh->ospeed, &ssh->ispeed);
	/* Build the pty request. */
	ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
	ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);	/* recipient channel */
5950
5951
5952
5953
5954
5955
5956
5957

5958
5959
5960
5961
5962
5963
5964
5954
5955
5956
5957
5958
5959
5960

5961
5962
5963
5964
5965
5966
5967
5968







-
+







    }

    /*
     * 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.
     */
    while (1) {
    if (ssh->mainchan) while (1) {
	int subsys;
	char *cmd;

	if (ssh->fallback_cmd) {
	    subsys = ssh->cfg.ssh_subsys2;
	    cmd = ssh->cfg.remote_cmd_ptr2;
	} else {
6024
6025
6026
6027
6028
6029
6030

6031

6032
6033
6034
6035
6036
6037
6038
6028
6029
6030
6031
6032
6033
6034
6035

6036
6037
6038
6039
6040
6041
6042
6043







+
-
+







	ssh_special(ssh, TS_EOF);

    /*
     * Transfer data!
     */
    if (ssh->ldisc)
	ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
    if (ssh->mainchan)
    ssh->send_ok = 1;
	ssh->send_ok = 1;
    while (1) {
	crReturnV;
	s->try_send = FALSE;
	if (ispkt) {
	    if (ssh->pktin.type == SSH2_MSG_CHANNEL_DATA ||
		ssh->pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
		char *data;
6167
6168
6169
6170
6171
6172
6173


6174
6175

6176
6177
6178
6179
6180
6181
6182
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181

6182
6183
6184
6185
6186
6187
6188
6189







+
+

-
+







		}
		del234(ssh->channels, c);
		bufchain_clear(&c->v.v2.outbuffer);
		sfree(c);

		/*
		 * See if that was the last channel left open.
		 * (This is only our termination condition if we're
		 * not running in -N mode.)
		 */
		if (count234(ssh->channels) == 0) {
		if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
		    logevent("All channels closed. Disconnecting");
#if 0
                    /*
                     * We used to send SSH_MSG_DISCONNECT here,
                     * because I'd believed that _every_ conforming
                     * SSH2 connection had to end with a disconnect
                     * being sent by at least one side; apparently
6448
6449
6450
6451
6452
6453
6454
6455

6456
6457
6458
6459
6460
6461
6462
6455
6456
6457
6458
6459
6460
6461

6462
6463
6464
6465
6466
6467
6468
6469







-
+







		    ssh2_pkt_adduint32(ssh, 0x4000UL);	/* our max pkt size */
		    ssh2_pkt_send(ssh);
		}
	    } else {
		bombout(("Strange packet received: type %d", ssh->pktin.type));
		crStopV;
	    }
	} else {
	} else if (ssh->mainchan) {
	    /*
	     * We have spare data. Add it to the channel buffer.
	     */
	    ssh2_add_channel_data(ssh->mainchan, (char *)in, inlen);
	    s->try_send = TRUE;
	}
	if (s->try_send) {
6768
6769
6770
6771
6772
6773
6774
6775

6776
6777
6778
6779
6780
6781
6782
6775
6776
6777
6778
6779
6780
6781

6782
6783
6784
6785
6786
6787
6788
6789







-
+







      case SSH_STATE_SESSION:
	if (!ssh->cfg.nopty) {
	    if (ssh->version == 1) {
		send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
			    PKT_INT, ssh->term_height,
			    PKT_INT, ssh->term_width,
			    PKT_INT, 0, PKT_INT, 0, PKT_END);
	    } else {
	    } else if (ssh->mainchan) {
		ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
		ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
		ssh2_pkt_addstring(ssh, "window-change");
		ssh2_pkt_addbool(ssh, 0);
		ssh2_pkt_adduint32(ssh, ssh->term_width);
		ssh2_pkt_adduint32(ssh, ssh->term_height);
		ssh2_pkt_adduint32(ssh, 0);
6830
6831
6832
6833
6834
6835
6836
6837

6838
6839
6840
6841
6842
6843
6844
6837
6838
6839
6840
6841
6842
6843

6844
6845
6846
6847
6848
6849
6850
6851







-
+







	     */
	    if (code == TS_EOF)
		ssh->eof_needed = TRUE;
	    return;
	}
	if (ssh->version == 1) {
	    send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
	} else {
	} else if (ssh->mainchan) {
	    ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_EOF);
	    ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
	    ssh2_pkt_send(ssh);
	}
	logevent("Sent EOF message");
    } else if (code == TS_PING || code == TS_NOP) {
	if (ssh->state == SSH_STATE_CLOSED
6852
6853
6854
6855
6856
6857
6858
6859

6860
6861
6862
6863
6864
6865
6866
6859
6860
6861
6862
6863
6864
6865

6866
6867
6868
6869
6870
6871
6872
6873







-
+







	    ssh2_pkt_send(ssh);
	}
    } else if (code == TS_BRK) {
	if (ssh->state == SSH_STATE_CLOSED
	    || ssh->state == SSH_STATE_PREPACKET) return;
	if (ssh->version == 1) {
	    logevent("Unable to send BREAK signal in SSH1");
	} else {
	} else if (ssh->mainchan) {
	    ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
	    ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
	    ssh2_pkt_addstring(ssh, "break");
	    ssh2_pkt_addbool(ssh, 0);
	    ssh2_pkt_adduint32(ssh, 0);   /* default break length */
	    ssh2_pkt_send(ssh);
	}