6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
|
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
|
+
|
del234(ssh->channels, c);
sfree(c);
} else if (ssh->pktin.type == SSH2_MSG_CHANNEL_REQUEST) {
unsigned localid;
char *type;
int typelen, want_reply;
int reply = SSH2_MSG_CHANNEL_FAILURE; /* default */
struct ssh_channel *c;
localid = ssh_pkt_getuint32(ssh);
ssh_pkt_getstring(ssh, &type, &typelen);
want_reply = ssh2_pkt_getbool(ssh);
/*
|
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
|
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
|
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
-
-
-
+
+
+
+
-
|
}
/*
* Having got the channel number, we now look at
* the request type string to see if it's something
* we recognise.
*/
if (typelen == 11 && !memcmp(type, "exit-status", 11) &&
c == ssh->mainchan) {
/* We recognise "exit-status" on the primary channel. */
char buf[100];
ssh->exitcode = ssh_pkt_getuint32(ssh);
sprintf(buf, "Server sent command exit status %d",
ssh->exitcode);
logevent(buf);
if (want_reply) {
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_SUCCESS);
ssh2_pkt_adduint32(ssh, c->remoteid);
if (c == ssh->mainchan) {
/*
* We recognise "exit-status" and "exit-signal" on
* the primary channel.
*/
if (typelen == 11 &&
!memcmp(type, "exit-status", 11)) {
ssh->exitcode = ssh_pkt_getuint32(ssh);
logeventf(ssh, "Server sent command exit status %d",
ssh->exitcode);
reply = SSH2_MSG_CHANNEL_SUCCESS;
} else if (typelen == 11 &&
!memcmp(type, "exit-signal", 11)) {
int is_plausible = TRUE, is_int = FALSE;
char *fmt_sig = "", *fmt_msg = "";
char *msg;
int msglen = 0, core = FALSE;
/* ICK: older versions of OpenSSH (e.g. 3.4p1)
* provide an `int' for the signal, despite its
* having been a `string' in the drafts since at
* least 2001. (Fixed in session.c 1.147.) Try to
* infer which we can safely parse it as. */
{
unsigned char *p = ssh->pktin.body +
ssh->pktin.savedpos;
long len = ssh->pktin.length - ssh->pktin.savedpos;
unsigned long num = GET_32BIT(p); /* what is it? */
/* If it's 0, it hardly matters; assume string */
if (num == 0) {
is_int = FALSE;
} else {
int maybe_int = FALSE, maybe_str = FALSE;
#define CHECK_HYPOTHESIS(offset, result) \
do { \
long q = offset; \
if (q+4 <= len) { \
q = q + 4 + GET_32BIT(p+q); \
if (q+4 <= len && (q = q + 4 + GET_32BIT(p+q)) && q == len) \
result = TRUE; \
} \
} while(0)
CHECK_HYPOTHESIS(4+1, maybe_int);
CHECK_HYPOTHESIS(4+num+1, maybe_str);
#undef CHECK_HYPOTHESIS
if (maybe_int && !maybe_str)
is_int = TRUE;
else if (!maybe_int && maybe_str)
is_int = FALSE;
else
/* Crikey. Either or neither. Panic. */
is_plausible = FALSE;
}
}
if (is_plausible) {
if (is_int) {
/* Old non-standard OpenSSH. */
int signum = ssh_pkt_getuint32(ssh);
fmt_sig = dupprintf(" %d", signum);
} else {
/* As per the drafts. */
char *sig;
int siglen;
ssh_pkt_getstring(ssh, &sig, &siglen);
/* Signal name isn't supposed to be blank, but
* let's cope gracefully if it is. */
if (siglen) {
fmt_sig = dupprintf(" \"%.*s\"",
siglen, sig);
}
}
core = ssh2_pkt_getbool(ssh);
ssh_pkt_getstring(ssh, &msg, &msglen);
if (msglen) {
fmt_msg = dupprintf(" (\"%.*s\")", msglen, msg);
}
/* ignore lang tag */
} /* else don't attempt to parse */
logeventf(ssh, "Server exited on signal%s%s%s",
fmt_sig, core ? " (core dumped)" : "",
fmt_msg);
if (*fmt_sig) sfree(fmt_sig);
if (*fmt_msg) sfree(fmt_msg);
reply = SSH2_MSG_CHANNEL_SUCCESS;
ssh2_pkt_send(ssh);
}
} else {
/*
* This is a channel request we don't know
* about, so we now either ignore the request
* or respond with CHANNEL_FAILURE, depending
* on want_reply.
*/
reply = SSH2_MSG_CHANNEL_FAILURE;
}
if (want_reply) {
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_FAILURE);
ssh2_pkt_adduint32(ssh, c->remoteid);
ssh2_pkt_send(ssh);
if (want_reply) {
ssh2_pkt_init(ssh, reply);
ssh2_pkt_adduint32(ssh, c->remoteid);
ssh2_pkt_send(ssh);
}
}
} else if (ssh->pktin.type == SSH2_MSG_GLOBAL_REQUEST) {
char *type;
int typelen, want_reply;
ssh_pkt_getstring(ssh, &type, &typelen);
want_reply = ssh2_pkt_getbool(ssh);
|