mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
- markus@cvs.openbsd.org 2002/03/25 21:13:51
[channels.c channels.h compat.c compat.h nchan.c] don't send stderr data after EOF, accept this from older known (broken) sshd servers only, fixes http://bugzilla.mindrot.org/show_bug.cgi?id=179
This commit is contained in:
parent
4f054607f0
commit
cf15944c23
@ -39,6 +39,10 @@
|
|||||||
- markus@cvs.openbsd.org 2002/03/25 21:04:02
|
- markus@cvs.openbsd.org 2002/03/25 21:04:02
|
||||||
[ssh.c]
|
[ssh.c]
|
||||||
simplify num_identity_files handling
|
simplify num_identity_files handling
|
||||||
|
- markus@cvs.openbsd.org 2002/03/25 21:13:51
|
||||||
|
[channels.c channels.h compat.c compat.h nchan.c]
|
||||||
|
don't send stderr data after EOF, accept this from older known (broken)
|
||||||
|
sshd servers only, fixes http://bugzilla.mindrot.org/show_bug.cgi?id=179
|
||||||
|
|
||||||
20020324
|
20020324
|
||||||
- (stevesk) [session.c] disable LOGIN_NEEDS_TERM until we are sure
|
- (stevesk) [session.c] disable LOGIN_NEEDS_TERM until we are sure
|
||||||
@ -8053,4 +8057,4 @@
|
|||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.1989 2002/03/26 03:23:00 mouring Exp $
|
$Id: ChangeLog,v 1.1990 2002/03/26 03:26:24 mouring Exp $
|
||||||
|
28
channels.c
28
channels.c
@ -39,7 +39,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: channels.c,v 1.171 2002/03/04 19:37:58 markus Exp $");
|
RCSID("$OpenBSD: channels.c,v 1.172 2002/03/25 21:13:51 markus Exp $");
|
||||||
|
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
#include "ssh1.h"
|
#include "ssh1.h"
|
||||||
@ -706,7 +706,11 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
|
|||||||
if (buffer_len(&c->output) > 0) {
|
if (buffer_len(&c->output) > 0) {
|
||||||
FD_SET(c->wfd, writeset);
|
FD_SET(c->wfd, writeset);
|
||||||
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
|
} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
|
||||||
chan_obuf_empty(c);
|
if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
|
||||||
|
debug2("channel %d: obuf_empty delayed efd %d/(%d)",
|
||||||
|
c->self, c->efd, buffer_len(&c->extended));
|
||||||
|
else
|
||||||
|
chan_obuf_empty(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** XXX check close conditions, too */
|
/** XXX check close conditions, too */
|
||||||
@ -714,7 +718,8 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
|
|||||||
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
|
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
|
||||||
buffer_len(&c->extended) > 0)
|
buffer_len(&c->extended) > 0)
|
||||||
FD_SET(c->efd, writeset);
|
FD_SET(c->efd, writeset);
|
||||||
else if (c->extended_usage == CHAN_EXTENDED_READ &&
|
else if (!(c->flags & CHAN_EOF_SENT) &&
|
||||||
|
c->extended_usage == CHAN_EXTENDED_READ &&
|
||||||
buffer_len(&c->extended) < c->remote_window)
|
buffer_len(&c->extended) < c->remote_window)
|
||||||
FD_SET(c->efd, readset);
|
FD_SET(c->efd, readset);
|
||||||
}
|
}
|
||||||
@ -1632,12 +1637,18 @@ channel_output_poll(void)
|
|||||||
fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
|
fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
|
||||||
/*
|
/*
|
||||||
* input-buffer is empty and read-socket shutdown:
|
* input-buffer is empty and read-socket shutdown:
|
||||||
* tell peer, that we will not send more data: send IEOF
|
* tell peer, that we will not send more data: send IEOF.
|
||||||
|
* hack for extended data: delay EOF if EFD still in use.
|
||||||
*/
|
*/
|
||||||
chan_ibuf_empty(c);
|
if (CHANNEL_EFD_INPUT_ACTIVE(c))
|
||||||
|
debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
|
||||||
|
c->self, c->efd, buffer_len(&c->extended));
|
||||||
|
else
|
||||||
|
chan_ibuf_empty(c);
|
||||||
}
|
}
|
||||||
/* Send extended data, i.e. stderr */
|
/* Send extended data, i.e. stderr */
|
||||||
if (compat20 &&
|
if (compat20 &&
|
||||||
|
!(c->flags & CHAN_EOF_SENT) &&
|
||||||
c->remote_window > 0 &&
|
c->remote_window > 0 &&
|
||||||
(len = buffer_len(&c->extended)) > 0 &&
|
(len = buffer_len(&c->extended)) > 0 &&
|
||||||
c->extended_usage == CHAN_EXTENDED_READ) {
|
c->extended_usage == CHAN_EXTENDED_READ) {
|
||||||
@ -1726,6 +1737,13 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
|
|||||||
log("channel %d: ext data for non open", id);
|
log("channel %d: ext data for non open", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (c->flags & CHAN_EOF_RCVD) {
|
||||||
|
if (datafellows & SSH_BUG_EXTEOF)
|
||||||
|
debug("channel %d: accepting ext data after eof", id);
|
||||||
|
else
|
||||||
|
packet_disconnect("Received extended_data after EOF "
|
||||||
|
"on channel %d.", id);
|
||||||
|
}
|
||||||
tcode = packet_get_int();
|
tcode = packet_get_int();
|
||||||
if (c->efd == -1 ||
|
if (c->efd == -1 ||
|
||||||
c->extended_usage != CHAN_EXTENDED_WRITE ||
|
c->extended_usage != CHAN_EXTENDED_WRITE ||
|
||||||
|
14
channels.h
14
channels.h
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: channels.h,v 1.65 2002/03/04 17:27:39 stevesk Exp $ */
|
/* $OpenBSD: channels.h,v 1.66 2002/03/25 21:13:51 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -135,6 +135,18 @@ struct Channel {
|
|||||||
|
|
||||||
#define CHAN_CLOSE_SENT 0x01
|
#define CHAN_CLOSE_SENT 0x01
|
||||||
#define CHAN_CLOSE_RCVD 0x02
|
#define CHAN_CLOSE_RCVD 0x02
|
||||||
|
#define CHAN_EOF_SENT 0x04
|
||||||
|
#define CHAN_EOF_RCVD 0x08
|
||||||
|
|
||||||
|
/* check whether 'efd' is still in use */
|
||||||
|
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
|
||||||
|
(compat20 && c->extended_usage == CHAN_EXTENDED_READ && \
|
||||||
|
(c->efd != -1 || \
|
||||||
|
buffer_len(&c->extended) > 0))
|
||||||
|
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
|
||||||
|
(compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \
|
||||||
|
((c->efd != -1 && !(c->flags & CHAN_EOF_RCVD)) || \
|
||||||
|
buffer_len(&c->extended) > 0))
|
||||||
|
|
||||||
/* channel management */
|
/* channel management */
|
||||||
|
|
||||||
|
22
compat.c
22
compat.c
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: compat.c,v 1.61 2002/03/06 00:24:39 markus Exp $");
|
RCSID("$OpenBSD: compat.c,v 1.62 2002/03/25 21:13:51 markus Exp $");
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
@ -61,20 +61,26 @@ compat_datafellows(const char *version)
|
|||||||
"OpenSSH-2.1*,"
|
"OpenSSH-2.1*,"
|
||||||
"OpenSSH_2.1*,"
|
"OpenSSH_2.1*,"
|
||||||
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER|
|
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER|
|
||||||
SSH_OLD_DHGEX|SSH_BUG_NOREKEY },
|
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||||
|
SSH_BUG_EXTEOF},
|
||||||
{ "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
|
{ "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
|
||||||
SSH_OLD_DHGEX|SSH_BUG_NOREKEY},
|
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||||
|
SSH_BUG_EXTEOF},
|
||||||
{ "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
{ "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
||||||
SSH_BUG_NOREKEY},
|
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||||
{ "OpenSSH_2.5.0p1*,"
|
{ "OpenSSH_2.5.0p1*,"
|
||||||
"OpenSSH_2.5.1p1*",
|
"OpenSSH_2.5.1p1*",
|
||||||
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
||||||
SSH_BUG_NOREKEY },
|
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||||
{ "OpenSSH_2.5.0*,"
|
{ "OpenSSH_2.5.0*,"
|
||||||
"OpenSSH_2.5.1*,"
|
"OpenSSH_2.5.1*,"
|
||||||
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY },
|
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||||
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY },
|
SSH_BUG_EXTEOF},
|
||||||
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY },
|
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||||
|
{ "OpenSSH_2.*,"
|
||||||
|
"OpenSSH_3.0*,"
|
||||||
|
"OpenSSH_3.1*", SSH_BUG_EXTEOF},
|
||||||
|
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||||
{ "OpenSSH*", 0 },
|
{ "OpenSSH*", 0 },
|
||||||
{ "*MindTerm*", 0 },
|
{ "*MindTerm*", 0 },
|
||||||
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||||
|
3
compat.h
3
compat.h
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: compat.h,v 1.30 2002/03/04 17:27:39 stevesk Exp $ */
|
/* $OpenBSD: compat.h,v 1.31 2002/03/25 21:13:51 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
@ -52,6 +52,7 @@
|
|||||||
#define SSH_BUG_OPENFAILURE 0x00020000
|
#define SSH_BUG_OPENFAILURE 0x00020000
|
||||||
#define SSH_BUG_DERIVEKEY 0x00040000
|
#define SSH_BUG_DERIVEKEY 0x00040000
|
||||||
#define SSH_BUG_DUMMYCHAN 0x00100000
|
#define SSH_BUG_DUMMYCHAN 0x00100000
|
||||||
|
#define SSH_BUG_EXTEOF 0x00200000
|
||||||
|
|
||||||
void enable_compat13(void);
|
void enable_compat13(void);
|
||||||
void enable_compat20(void);
|
void enable_compat20(void);
|
||||||
|
60
nchan.c
60
nchan.c
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: nchan.c,v 1.44 2002/01/21 23:27:10 markus Exp $");
|
RCSID("$OpenBSD: nchan.c,v 1.45 2002/03/25 21:13:51 markus Exp $");
|
||||||
|
|
||||||
#include "ssh1.h"
|
#include "ssh1.h"
|
||||||
#include "ssh2.h"
|
#include "ssh2.h"
|
||||||
@ -302,6 +302,7 @@ static void
|
|||||||
chan_rcvd_eof2(Channel *c)
|
chan_rcvd_eof2(Channel *c)
|
||||||
{
|
{
|
||||||
debug("channel %d: rcvd eof", c->self);
|
debug("channel %d: rcvd eof", c->self);
|
||||||
|
c->flags |= CHAN_EOF_RCVD;
|
||||||
if (c->ostate == CHAN_OUTPUT_OPEN)
|
if (c->ostate == CHAN_OUTPUT_OPEN)
|
||||||
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
|
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
|
||||||
}
|
}
|
||||||
@ -330,6 +331,7 @@ chan_send_eof2(Channel *c)
|
|||||||
packet_start(SSH2_MSG_CHANNEL_EOF);
|
packet_start(SSH2_MSG_CHANNEL_EOF);
|
||||||
packet_put_int(c->remote_id);
|
packet_put_int(c->remote_id);
|
||||||
packet_send();
|
packet_send();
|
||||||
|
c->flags |= CHAN_EOF_SENT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("channel %d: cannot send eof for istate %d",
|
error("channel %d: cannot send eof for istate %d",
|
||||||
@ -365,7 +367,8 @@ chan_rcvd_ieof(Channel *c)
|
|||||||
else
|
else
|
||||||
chan_rcvd_ieof1(c);
|
chan_rcvd_ieof1(c);
|
||||||
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
|
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
|
||||||
buffer_len(&c->output) == 0)
|
buffer_len(&c->output) == 0 &&
|
||||||
|
!CHANNEL_EFD_OUTPUT_ACTIVE(c))
|
||||||
chan_obuf_empty(c);
|
chan_obuf_empty(c);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
@ -404,39 +407,30 @@ chan_is_dead(Channel *c, int send)
|
|||||||
debug("channel %d: is dead", c->self);
|
debug("channel %d: is dead", c->self);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
if ((datafellows & SSH_BUG_EXTEOF) &&
|
||||||
* we have to delay the close message if the efd (for stderr) is
|
c->extended_usage == CHAN_EXTENDED_WRITE &&
|
||||||
* still active
|
c->efd != -1 &&
|
||||||
*/
|
buffer_len(&c->extended) > 0) {
|
||||||
if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
|
debug2("channel %d: active efd: %d len %d",
|
||||||
buffer_len(&c->extended) > 0)
|
c->self, c->efd, buffer_len(&c->extended));
|
||||||
#if 0
|
return 0;
|
||||||
|| ((c->extended_usage == CHAN_EXTENDED_READ) &&
|
}
|
||||||
c->efd != -1)
|
if (!(c->flags & CHAN_CLOSE_SENT)) {
|
||||||
#endif
|
if (send) {
|
||||||
) {
|
chan_send_close2(c);
|
||||||
debug2("channel %d: active efd: %d len %d type %s",
|
} else {
|
||||||
c->self, c->efd, buffer_len(&c->extended),
|
/* channel would be dead if we sent a close */
|
||||||
c->extended_usage==CHAN_EXTENDED_READ ?
|
if (c->flags & CHAN_CLOSE_RCVD) {
|
||||||
"read": "write");
|
debug("channel %d: almost dead",
|
||||||
} else {
|
c->self);
|
||||||
if (!(c->flags & CHAN_CLOSE_SENT)) {
|
return 1;
|
||||||
if (send) {
|
|
||||||
chan_send_close2(c);
|
|
||||||
} else {
|
|
||||||
/* channel would be dead if we sent a close */
|
|
||||||
if (c->flags & CHAN_CLOSE_RCVD) {
|
|
||||||
debug("channel %d: almost dead",
|
|
||||||
c->self);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((c->flags & CHAN_CLOSE_SENT) &&
|
}
|
||||||
(c->flags & CHAN_CLOSE_RCVD)) {
|
if ((c->flags & CHAN_CLOSE_SENT) &&
|
||||||
debug("channel %d: is dead", c->self);
|
(c->flags & CHAN_CLOSE_RCVD)) {
|
||||||
return 1;
|
debug("channel %d: is dead", c->self);
|
||||||
}
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user