| ︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#define TRUE 1
#endif
#define logevent(s) { logevent(s); \
if (!(flags & FLAG_CONNECTION) && (flags & FLAG_VERBOSE)) \
fprintf(stderr, "%s\n", s); }
#define SSH1_MSG_DISCONNECT 1
#define SSH1_SMSG_PUBLIC_KEY 2
#define SSH1_CMSG_SESSION_KEY 3
#define SSH1_CMSG_USER 4
#define SSH1_CMSG_AUTH_RSA 6
#define SSH1_SMSG_AUTH_RSA_CHALLENGE 7
#define SSH1_CMSG_AUTH_RSA_RESPONSE 8
#define SSH1_CMSG_AUTH_PASSWORD 9
#define SSH1_CMSG_REQUEST_PTY 10
#define SSH1_CMSG_WINDOW_SIZE 11
#define SSH1_CMSG_EXEC_SHELL 12
#define SSH1_CMSG_EXEC_CMD 13
#define SSH1_SMSG_SUCCESS 14
#define SSH1_SMSG_FAILURE 15
#define SSH1_CMSG_STDIN_DATA 16
#define SSH1_SMSG_STDOUT_DATA 17
#define SSH1_SMSG_STDERR_DATA 18
#define SSH1_CMSG_EOF 19
#define SSH1_SMSG_EXIT_STATUS 20
#define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION 21
#define SSH1_MSG_CHANNEL_OPEN_FAILURE 22
#define SSH1_MSG_CHANNEL_DATA 23
#define SSH1_MSG_CHANNEL_CLOSE 24
#define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION 25
#define SSH1_CMSG_AGENT_REQUEST_FORWARDING 30
#define SSH1_SMSG_AGENT_OPEN 31
#define SSH1_CMSG_EXIT_CONFIRMATION 33
#define SSH1_MSG_IGNORE 32
#define SSH1_MSG_DEBUG 36
#define SSH1_CMSG_AUTH_TIS 39
#define SSH1_SMSG_AUTH_TIS_CHALLENGE 40
#define SSH1_CMSG_AUTH_TIS_RESPONSE 41
#define SSH1_CMSG_AUTH_CCARD 70
#define SSH1_SMSG_AUTH_CCARD_CHALLENGE 71
#define SSH1_CMSG_AUTH_CCARD_RESPONSE 72
#define SSH1_AUTH_TIS 5
#define SSH1_AUTH_CCARD 16
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
#define SSH_AGENTC_RSA_CHALLENGE 3
#define SSH_AGENT_RSA_RESPONSE 4
#define SSH_AGENT_FAILURE 5
#define SSH_AGENT_SUCCESS 6
#define SSH_AGENTC_ADD_RSA_IDENTITY 7
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
#define SSH2_MSG_DISCONNECT 1
#define SSH2_MSG_IGNORE 2
#define SSH2_MSG_UNIMPLEMENTED 3
#define SSH2_MSG_DEBUG 4
#define SSH2_MSG_SERVICE_REQUEST 5
#define SSH2_MSG_SERVICE_ACCEPT 6
#define SSH2_MSG_KEXINIT 20
#define SSH2_MSG_NEWKEYS 21
#define SSH2_MSG_KEXDH_INIT 30
#define SSH2_MSG_KEXDH_REPLY 31
#define SSH2_MSG_USERAUTH_REQUEST 50
#define SSH2_MSG_USERAUTH_FAILURE 51
#define SSH2_MSG_USERAUTH_SUCCESS 52
#define SSH2_MSG_USERAUTH_BANNER 53
#define SSH2_MSG_USERAUTH_PK_OK 60
#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60
#define SSH2_MSG_GLOBAL_REQUEST 80
#define SSH2_MSG_REQUEST_SUCCESS 81
#define SSH2_MSG_REQUEST_FAILURE 82
#define SSH2_MSG_CHANNEL_OPEN 90
#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91
#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92
#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93
#define SSH2_MSG_CHANNEL_DATA 94
#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95
#define SSH2_MSG_CHANNEL_EOF 96
#define SSH2_MSG_CHANNEL_CLOSE 97
#define SSH2_MSG_CHANNEL_REQUEST 98
#define SSH2_MSG_CHANNEL_SUCCESS 99
#define SSH2_MSG_CHANNEL_FAILURE 100
#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1
#define SSH2_OPEN_CONNECT_FAILED 2
#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3
#define SSH2_OPEN_RESOURCE_SHORTAGE 4
#define SSH2_EXTENDED_DATA_STDERR 1
#define GET_32BIT(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
((unsigned long)(unsigned char)(cp)[1] << 16) | \
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#define TRUE 1
#endif
#define logevent(s) { logevent(s); \
if (!(flags & FLAG_CONNECTION) && (flags & FLAG_VERBOSE)) \
fprintf(stderr, "%s\n", s); }
#define SSH1_MSG_DISCONNECT 1 /* 0x1 */
#define SSH1_SMSG_PUBLIC_KEY 2 /* 0x2 */
#define SSH1_CMSG_SESSION_KEY 3 /* 0x3 */
#define SSH1_CMSG_USER 4 /* 0x4 */
#define SSH1_CMSG_AUTH_RSA 6 /* 0x6 */
#define SSH1_SMSG_AUTH_RSA_CHALLENGE 7 /* 0x7 */
#define SSH1_CMSG_AUTH_RSA_RESPONSE 8 /* 0x8 */
#define SSH1_CMSG_AUTH_PASSWORD 9 /* 0x9 */
#define SSH1_CMSG_REQUEST_PTY 10 /* 0xa */
#define SSH1_CMSG_WINDOW_SIZE 11 /* 0xb */
#define SSH1_CMSG_EXEC_SHELL 12 /* 0xc */
#define SSH1_CMSG_EXEC_CMD 13 /* 0xd */
#define SSH1_SMSG_SUCCESS 14 /* 0xe */
#define SSH1_SMSG_FAILURE 15 /* 0xf */
#define SSH1_CMSG_STDIN_DATA 16 /* 0x10 */
#define SSH1_SMSG_STDOUT_DATA 17 /* 0x11 */
#define SSH1_SMSG_STDERR_DATA 18 /* 0x12 */
#define SSH1_CMSG_EOF 19 /* 0x13 */
#define SSH1_SMSG_EXIT_STATUS 20 /* 0x14 */
#define SSH1_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* 0x15 */
#define SSH1_MSG_CHANNEL_OPEN_FAILURE 22 /* 0x16 */
#define SSH1_MSG_CHANNEL_DATA 23 /* 0x17 */
#define SSH1_MSG_CHANNEL_CLOSE 24 /* 0x18 */
#define SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* 0x19 */
#define SSH1_CMSG_AGENT_REQUEST_FORWARDING 30 /* 0x1e */
#define SSH1_SMSG_AGENT_OPEN 31 /* 0x1f */
#define SSH1_CMSG_EXIT_CONFIRMATION 33 /* 0x21 */
#define SSH1_MSG_IGNORE 32 /* 0x20 */
#define SSH1_MSG_DEBUG 36 /* 0x24 */
#define SSH1_CMSG_AUTH_TIS 39 /* 0x27 */
#define SSH1_SMSG_AUTH_TIS_CHALLENGE 40 /* 0x28 */
#define SSH1_CMSG_AUTH_TIS_RESPONSE 41 /* 0x29 */
#define SSH1_CMSG_AUTH_CCARD 70 /* 0x46 */
#define SSH1_SMSG_AUTH_CCARD_CHALLENGE 71 /* 0x47 */
#define SSH1_CMSG_AUTH_CCARD_RESPONSE 72 /* 0x48 */
#define SSH1_AUTH_TIS 5 /* 0x5 */
#define SSH1_AUTH_CCARD 16 /* 0x10 */
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 /* 0x1 */
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 /* 0x2 */
#define SSH_AGENTC_RSA_CHALLENGE 3 /* 0x3 */
#define SSH_AGENT_RSA_RESPONSE 4 /* 0x4 */
#define SSH_AGENT_FAILURE 5 /* 0x5 */
#define SSH_AGENT_SUCCESS 6 /* 0x6 */
#define SSH_AGENTC_ADD_RSA_IDENTITY 7 /* 0x7 */
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 /* 0x8 */
#define SSH2_MSG_DISCONNECT 1 /* 0x1 */
#define SSH2_MSG_IGNORE 2 /* 0x2 */
#define SSH2_MSG_UNIMPLEMENTED 3 /* 0x3 */
#define SSH2_MSG_DEBUG 4 /* 0x4 */
#define SSH2_MSG_SERVICE_REQUEST 5 /* 0x5 */
#define SSH2_MSG_SERVICE_ACCEPT 6 /* 0x6 */
#define SSH2_MSG_KEXINIT 20 /* 0x14 */
#define SSH2_MSG_NEWKEYS 21 /* 0x15 */
#define SSH2_MSG_KEXDH_INIT 30 /* 0x1e */
#define SSH2_MSG_KEXDH_REPLY 31 /* 0x1f */
#define SSH2_MSG_USERAUTH_REQUEST 50 /* 0x32 */
#define SSH2_MSG_USERAUTH_FAILURE 51 /* 0x33 */
#define SSH2_MSG_USERAUTH_SUCCESS 52 /* 0x34 */
#define SSH2_MSG_USERAUTH_BANNER 53 /* 0x35 */
#define SSH2_MSG_USERAUTH_PK_OK 60 /* 0x3c */
#define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 /* 0x3c */
#define SSH2_MSG_GLOBAL_REQUEST 80 /* 0x50 */
#define SSH2_MSG_REQUEST_SUCCESS 81 /* 0x51 */
#define SSH2_MSG_REQUEST_FAILURE 82 /* 0x52 */
#define SSH2_MSG_CHANNEL_OPEN 90 /* 0x5a */
#define SSH2_MSG_CHANNEL_OPEN_CONFIRMATION 91 /* 0x5b */
#define SSH2_MSG_CHANNEL_OPEN_FAILURE 92 /* 0x5c */
#define SSH2_MSG_CHANNEL_WINDOW_ADJUST 93 /* 0x5d */
#define SSH2_MSG_CHANNEL_DATA 94 /* 0x5e */
#define SSH2_MSG_CHANNEL_EXTENDED_DATA 95 /* 0x5f */
#define SSH2_MSG_CHANNEL_EOF 96 /* 0x60 */
#define SSH2_MSG_CHANNEL_CLOSE 97 /* 0x61 */
#define SSH2_MSG_CHANNEL_REQUEST 98 /* 0x62 */
#define SSH2_MSG_CHANNEL_SUCCESS 99 /* 0x63 */
#define SSH2_MSG_CHANNEL_FAILURE 100 /* 0x64 */
#define SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED 1 /* 0x1 */
#define SSH2_OPEN_CONNECT_FAILED 2 /* 0x2 */
#define SSH2_OPEN_UNKNOWN_CHANNEL_TYPE 3 /* 0x3 */
#define SSH2_OPEN_RESOURCE_SHORTAGE 4 /* 0x4 */
#define SSH2_EXTENDED_DATA_STDERR 1 /* 0x1 */
#define GET_32BIT(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
((unsigned long)(unsigned char)(cp)[1] << 16) | \
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
|
| ︙ | | | ︙ | |
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
static char *savedhost;
static int ssh_send_ok;
/*
* 2-3-4 tree storing channels.
*/
struct ssh_channel {
int remoteid, localid;
int type;
int closes;
union {
struct ssh_agent_channel {
unsigned char *message;
unsigned char msglen[4];
int lensofar, totallen;
} a;
} u;
};
static tree234 *ssh_channels; /* indexed by local id */
static int ssh_channelcmp(void *av, void *bv) {
struct ssh_channel *a = (struct ssh_channel *)av;
struct ssh_channel *b = (struct ssh_channel *)bv;
if (a->localid < b->localid) return -1;
if (a->localid > b->localid) return +1;
return 0;
}
static int ssh_channelfind(void *av, void *bv) {
int *a = (int *)av;
struct ssh_channel *b = (struct ssh_channel *)bv;
if (*a < b->localid) return -1;
if (*a > b->localid) return +1;
return 0;
}
static enum {
SSH_STATE_BEFORE_SIZE,
SSH_STATE_INTERMED,
SSH_STATE_SESSION,
SSH_STATE_CLOSED
} ssh_state = SSH_STATE_BEFORE_SIZE;
|
|
>
>
>
>
>
|
>
>
|
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
static char *savedhost;
static int ssh_send_ok;
/*
* 2-3-4 tree storing channels.
*/
struct ssh_channel {
unsigned remoteid, localid;
int type;
int closes;
union {
struct ssh_agent_channel {
unsigned char *message;
unsigned char msglen[4];
int lensofar, totallen;
} a;
struct ssh2_data_channel {
unsigned char *outbuffer;
unsigned outbuflen, outbufsize;
unsigned remwindow, remmaxpkt;
} v2;
} u;
};
static tree234 *ssh_channels; /* indexed by local id */
static int ssh_channelcmp(void *av, void *bv) {
struct ssh_channel *a = (struct ssh_channel *)av;
struct ssh_channel *b = (struct ssh_channel *)bv;
if (a->localid < b->localid) return -1;
if (a->localid > b->localid) return +1;
return 0;
}
static int ssh_channelfind(void *av, void *bv) {
unsigned *a = (unsigned *)av;
struct ssh_channel *b = (struct ssh_channel *)bv;
if (*a < b->localid) return -1;
if (*a > b->localid) return +1;
return 0;
}
static struct ssh_channel *mainchan; /* primary session channel */
static enum {
SSH_STATE_BEFORE_SIZE,
SSH_STATE_INTERMED,
SSH_STATE_SESSION,
SSH_STATE_CLOSED
} ssh_state = SSH_STATE_BEFORE_SIZE;
|
| ︙ | | | ︙ | |
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
|
c_write(pktin.body+4, len);
} else if (pktin.type == SSH1_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
} else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {
/* Remote side is trying to open a channel to talk to our
* agent. Give them back a local channel number. */
int i = 1;
struct ssh_channel *c;
enum234 e;
for (c = first234(ssh_channels, &e); c; c = next234(&e)) {
if (c->localid > i)
break; /* found a free number */
i = c->localid + 1;
}
c = malloc(sizeof(struct ssh_channel));
c->remoteid = GET_32BIT(pktin.body);
c->localid = i;
c->closes = 0;
c->type = SSH1_SMSG_AGENT_OPEN; /* identify channel type */
add234(ssh_channels, c);
send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
PKT_INT, c->remoteid, PKT_INT, c->localid,
PKT_END);
} else if (pktin.type == SSH1_MSG_CHANNEL_CLOSE ||
pktin.type == SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION) {
/* Remote side closes a channel. */
int i = GET_32BIT(pktin.body);
struct ssh_channel *c;
c = find234(ssh_channels, &i, ssh_channelfind);
if (c) {
int closetype;
closetype = (pktin.type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
send_packet(pktin.type, PKT_INT, c->remoteid, PKT_END);
c->closes |= closetype;
|
|
|
|
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
|
c_write(pktin.body+4, len);
} else if (pktin.type == SSH1_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
} else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {
/* Remote side is trying to open a channel to talk to our
* agent. Give them back a local channel number. */
unsigned i = 1;
struct ssh_channel *c;
enum234 e;
for (c = first234(ssh_channels, &e); c; c = next234(&e)) {
if (c->localid > i)
break; /* found a free number */
i = c->localid + 1;
}
c = malloc(sizeof(struct ssh_channel));
c->remoteid = GET_32BIT(pktin.body);
c->localid = i;
c->closes = 0;
c->type = SSH1_SMSG_AGENT_OPEN; /* identify channel type */
add234(ssh_channels, c);
send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
PKT_INT, c->remoteid, PKT_INT, c->localid,
PKT_END);
} else if (pktin.type == SSH1_MSG_CHANNEL_CLOSE ||
pktin.type == SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION) {
/* Remote side closes a channel. */
unsigned i = GET_32BIT(pktin.body);
struct ssh_channel *c;
c = find234(ssh_channels, &i, ssh_channelfind);
if (c) {
int closetype;
closetype = (pktin.type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);
send_packet(pktin.type, PKT_INT, c->remoteid, PKT_END);
c->closes |= closetype;
|
| ︙ | | | ︙ | |
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
|
crReturn(1);
} while (!(ispkt && pktin.type == SSH2_MSG_KEXINIT));
goto begin_key_exchange;
crFinish(1);
}
/*
* SSH2: remote identifier for the main session channel.
*/
static unsigned long ssh_remote_channel;
/*
* Handle the SSH2 userauth and connection layers.
*/
static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
{
static unsigned long remote_winsize;
static unsigned long remote_maxpkt;
|
<
<
<
<
<
|
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
|
crReturn(1);
} while (!(ispkt && pktin.type == SSH2_MSG_KEXINIT));
goto begin_key_exchange;
crFinish(1);
}
/*
* Handle the SSH2 userauth and connection layers.
*/
static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
{
static unsigned long remote_winsize;
static unsigned long remote_maxpkt;
|
| ︙ | | | ︙ | |
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
|
* connection protocol will automatically have started at this
* point; there's no need to send SERVICE_REQUEST.
*/
/*
* So now create a channel with a session in it.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring("session");
ssh2_pkt_adduint32(100); /* as good as any */
ssh2_pkt_adduint32(0x7FFFFFFFUL); /* very big window which we ignore */
ssh2_pkt_adduint32(0x7FFFFFFFUL); /* very big max pkt size */
ssh2_pkt_send();
crWaitUntilV(ispkt);
if (pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
fatalbox("Server refused to open a session");
/* FIXME: error data comes back in FAILURE packet */
}
if (ssh2_pkt_getuint32() != 100) {
fatalbox("Server's channel confirmation cited wrong channel");
}
ssh_remote_channel = ssh2_pkt_getuint32();
remote_winsize = ssh2_pkt_getuint32();
remote_maxpkt = ssh2_pkt_getuint32();
logevent("Opened channel for session");
/*
* Now allocate a pty for the session.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype);
ssh2_pkt_adduint32(cols);
ssh2_pkt_adduint32(rows);
ssh2_pkt_adduint32(0); /* pixel width */
ssh2_pkt_adduint32(0); /* pixel height */
|
>
>
|
|
|
|
|
|
|
>
>
|
|
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
|
* connection protocol will automatically have started at this
* point; there's no need to send SERVICE_REQUEST.
*/
/*
* So now create a channel with a session in it.
*/
mainchan = malloc(sizeof(struct ssh_channel));
mainchan->localid = 100; /* as good as any */
ssh2_pkt_init(SSH2_MSG_CHANNEL_OPEN);
ssh2_pkt_addstring("session");
ssh2_pkt_adduint32(mainchan->localid);
ssh2_pkt_adduint32(0x7FFFFFFFUL); /* our window size */
ssh2_pkt_adduint32(0x4000UL); /* our max pkt size */
ssh2_pkt_send();
crWaitUntilV(ispkt);
if (pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
fatalbox("Server refused to open a session");
/* FIXME: error data comes back in FAILURE packet */
}
if (ssh2_pkt_getuint32() != mainchan->localid) {
fatalbox("Server's channel confirmation cited wrong channel");
}
mainchan->remoteid = ssh2_pkt_getuint32();
mainchan->u.v2.remwindow = ssh2_pkt_getuint32();
mainchan->u.v2.remmaxpkt = ssh2_pkt_getuint32();
mainchan->u.v2.outbuffer = NULL;
mainchan->u.v2.outbuflen = mainchan->u.v2.outbufsize = 0;
logevent("Opened channel for session");
/*
* Now allocate a pty for the session.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype);
ssh2_pkt_adduint32(cols);
ssh2_pkt_adduint32(rows);
ssh2_pkt_adduint32(0); /* pixel width */
ssh2_pkt_adduint32(0); /* pixel height */
|
| ︙ | | | ︙ | |
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
|
logevent("Allocated pty");
}
/*
* Start a shell.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
ssh2_pkt_addstring("shell");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_send();
do { /* FIXME: pay attention to these */
crWaitUntilV(ispkt);
} while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
fatalbox("Server got confused by shell request");
}
fatalbox("Server refused to start a shell");
} else {
logevent("Started a shell");
}
/*
* Transfer data!
*/
ssh_send_ok = 1;
while (1) {
crReturnV;
if (ispkt) {
if (pktin.type == SSH2_MSG_CHANNEL_DATA ||
pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
char *data;
int length;
if (ssh2_pkt_getuint32() != 100)
continue; /* wrong channel */
if (pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
ssh2_pkt_getuint32() != SSH2_EXTENDED_DATA_STDERR)
continue; /* extended but not stderr */
ssh2_pkt_getstring(&data, &length);
if (data)
c_write(data, length);
} else if (pktin.type == SSH2_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
} else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
continue; /* exit status et al; ignore (FIXME?) */
} else if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
continue; /* ignore for now (FIXME!) */
} else {
fatalbox("Strange packet received: type %d", pktin.type);
}
} else {
/* FIXME: for now, ignore window size */
ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
ssh2_pkt_adduint32(ssh_remote_channel);
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data(in, inlen);
ssh2_pkt_send();
}
}
crFinishV;
}
/*
* Handle the top-level SSH2 protocol.
|
|
|
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>
>
>
>
|
>
|
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
|
logevent("Allocated pty");
}
/*
* Start a shell.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
ssh2_pkt_addstring("shell");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_send();
do {
crWaitUntilV(ispkt);
if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
/* FIXME: be able to handle other channels here */
if (ssh2_pkt_getuint32() != mainchan->localid)
continue; /* wrong channel */
mainchan->u.v2.remwindow += ssh2_pkt_getuint32();
}
} while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
fatalbox("Server got confused by shell request");
}
fatalbox("Server refused to start a shell");
} else {
logevent("Started a shell");
}
/*
* Transfer data!
*/
ssh_send_ok = 1;
while (1) {
static int try_send;
crReturnV;
try_send = FALSE;
if (ispkt) {
if (pktin.type == SSH2_MSG_CHANNEL_DATA ||
pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA) {
char *data;
int length;
/* FIXME: be able to handle other channels here */
if (ssh2_pkt_getuint32() != mainchan->localid)
continue; /* wrong channel */
if (pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA &&
ssh2_pkt_getuint32() != SSH2_EXTENDED_DATA_STDERR)
continue; /* extended but not stderr */
ssh2_pkt_getstring(&data, &length);
if (data) {
c_write(data, length);
/*
* Enlarge the window again at the remote side,
* just in case it ever runs down and they fail
* to send us any more data.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
ssh2_pkt_adduint32(mainchan->remoteid);
ssh2_pkt_adduint32(length);
ssh2_pkt_send();
}
} else if (pktin.type == SSH2_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect message");
} else if (pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
continue; /* exit status et al; ignore (FIXME?) */
} else if (pktin.type == SSH2_MSG_CHANNEL_EOF) {
continue; /* remote sends EOF; ignore */
} else if (pktin.type == SSH2_MSG_CHANNEL_CLOSE) {
/* FIXME: be able to handle other channels here */
if (ssh2_pkt_getuint32() != mainchan->localid)
continue; /* wrong channel */
ssh2_pkt_init(SSH2_MSG_CHANNEL_CLOSE);
ssh2_pkt_adduint32(mainchan->remoteid);
ssh2_pkt_send();
/* FIXME: mark the channel as closed */
if (1 /* FIXME: "all channels are closed" */) {
logevent("All channels closed. Disconnecting");
ssh2_pkt_init(SSH2_MSG_DISCONNECT);
ssh2_pkt_send();
}
continue; /* remote sends close; ignore (FIXME) */
} else if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
/* FIXME: be able to handle other channels here */
if (ssh2_pkt_getuint32() != mainchan->localid)
continue; /* wrong channel */
mainchan->u.v2.remwindow += ssh2_pkt_getuint32();
try_send = TRUE;
} else {
fatalbox("Strange packet received: type %d", pktin.type);
}
} else {
/*
* We have spare data. Add it to the channel buffer.
*/
if (mainchan->u.v2.outbufsize <
mainchan->u.v2.outbuflen + inlen) {
mainchan->u.v2.outbufsize =
mainchan->u.v2.outbuflen + inlen + 1024;
mainchan->u.v2.outbuffer = srealloc(mainchan->u.v2.outbuffer,
mainchan->u.v2.outbufsize);
}
memcpy(mainchan->u.v2.outbuffer + mainchan->u.v2.outbuflen,
in, inlen);
mainchan->u.v2.outbuflen += inlen;
try_send = TRUE;
}
if (try_send) {
/*
* Try to send data on the channel if we can. (FIXME:
* on _all_ channels.)
*/
while (mainchan->u.v2.remwindow > 0 &&
mainchan->u.v2.outbuflen > 0) {
unsigned len = mainchan->u.v2.remwindow;
if (len > mainchan->u.v2.outbuflen)
len = mainchan->u.v2.outbuflen;
if (len > mainchan->u.v2.remmaxpkt)
len = mainchan->u.v2.remmaxpkt;
ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
ssh2_pkt_adduint32(mainchan->remoteid);
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data(mainchan->u.v2.outbuffer, len);
ssh2_pkt_send();
mainchan->u.v2.outbuflen -= len;
memmove(mainchan->u.v2.outbuffer, mainchan->u.v2.outbuffer+len,
mainchan->u.v2.outbuflen);
mainchan->u.v2.remwindow -= len;
}
}
}
crFinishV;
}
/*
* Handle the top-level SSH2 protocol.
|
| ︙ | | | ︙ | |
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
|
*/
static void ssh_special (Telnet_Special code) {
if (code == TS_EOF) {
if (ssh_version = 1) {
send_packet(SSH1_CMSG_EOF, PKT_END);
} else {
ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
ssh2_pkt_adduint32(ssh_remote_channel);
ssh2_pkt_send();
}
} else {
/* do nothing */
}
}
|
|
|
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
|
*/
static void ssh_special (Telnet_Special code) {
if (code == TS_EOF) {
if (ssh_version = 1) {
send_packet(SSH1_CMSG_EOF, PKT_END);
} else {
ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
ssh2_pkt_adduint32(mainchan->remoteid);
ssh2_pkt_send();
}
} else {
/* do nothing */
}
}
|
| ︙ | | | ︙ | |