mirror of
https://github.com/clearml/dropbear
synced 2025-05-20 03:07:47 +00:00
merge of abac2150ee4f4031a98016241fbd136d24fed127
and ffa047425729e478a5b49b1ab0f8ec71c08a1421 --HG-- extra : convert_revision : e9b7d4eda64d70aff736f48cc8dea680b153139b
This commit is contained in:
commit
09b50641ff
@ -450,8 +450,8 @@ void recv_msg_kexinit() {
|
||||
/* the rest of ses.kexhashbuf will be done after DH exchange */
|
||||
|
||||
ses.kexstate.recvkexinit = 1;
|
||||
// ses.expecting = SSH_MSG_KEXDH_INIT;
|
||||
ses.expecting = 0;
|
||||
ses.requirenext = SSH_MSG_KEXDH_INIT;
|
||||
// ses.expecting = 0; // client matt
|
||||
|
||||
TRACE(("leave recv_msg_kexinit"));
|
||||
}
|
||||
|
@ -402,21 +402,6 @@ static buffer* buf_decompress(buffer* buf, unsigned int len) {
|
||||
|
||||
|
||||
|
||||
/* This must be called directly after receiving the unimplemented packet.
|
||||
* Isn't the most clean implementation, it relies on packet processing
|
||||
* occurring directly after decryption. This is reasonably valid, since
|
||||
* there is only a single decryption buffer */
|
||||
void recv_unimplemented() {
|
||||
|
||||
CHECKCLEARTOWRITE();
|
||||
|
||||
buf_putbyte(ses.writepayload, SSH_MSG_UNIMPLEMENTED);
|
||||
/* the decryption routine increments the sequence number, we must
|
||||
* decrement */
|
||||
buf_putint(ses.writepayload, ses.recvseq - 1);
|
||||
|
||||
encrypt_packet();
|
||||
}
|
||||
|
||||
/* encrypt the writepayload, putting into writebuf, ready for write_packet()
|
||||
* to put on the wire */
|
||||
|
@ -76,7 +76,7 @@ void common_session_init(int sock, runopts *opts) {
|
||||
ses.payload = NULL;
|
||||
ses.recvseq = 0;
|
||||
|
||||
ses.expecting = SSH_MSG_KEXINIT;
|
||||
ses.requirenext = SSH_MSG_KEXINIT;
|
||||
ses.dataallowed = 0; /* don't send data yet, we'll wait until after kex */
|
||||
ses.ignorenext = 0;
|
||||
|
||||
@ -106,8 +106,12 @@ void common_session_init(int sock, runopts *opts) {
|
||||
ses.dh_K = NULL;
|
||||
ses.remoteident = NULL;
|
||||
|
||||
ses.authdone = 0;
|
||||
|
||||
ses.chantypes = NULL;
|
||||
|
||||
ses.allowprivport = 0;
|
||||
|
||||
|
||||
TRACE(("leave session_init"));
|
||||
}
|
||||
|
2
debug.h
2
debug.h
@ -36,7 +36,7 @@
|
||||
/* Define this to print trace statements - very verbose */
|
||||
/* Caution: Don't use this in an unfriendly environment (ie unfirewalled),
|
||||
* since the printing does not sanitise strings etc */
|
||||
/*#define DEBUG_TRACE*/
|
||||
#define DEBUG_TRACE
|
||||
|
||||
/* All functions writing to the cleartext payload buffer call
|
||||
* CHECKCLEARTOWRITE() before writing. This is only really useful if you're
|
||||
|
8
packet.h
8
packet.h
@ -32,9 +32,13 @@ void write_packet();
|
||||
void read_packet();
|
||||
void decrypt_packet();
|
||||
void encrypt_packet();
|
||||
void recv_unimplemented();
|
||||
|
||||
void svr_process_packet();
|
||||
void process_packet();
|
||||
|
||||
typedef struct PacketType {
|
||||
unsigned char type; /* SSH_MSG_FOO */
|
||||
void (*handler)();
|
||||
} packettype;
|
||||
|
||||
#define PACKET_PADDING_OFF 4
|
||||
#define PACKET_PAYLOAD_OFF 5
|
||||
|
161
process-packet.c
Normal file
161
process-packet.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Dropbear - a SSH2 server
|
||||
*
|
||||
* Copyright (c) 2002-2004 Matt Johnston
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE. */
|
||||
|
||||
#include "includes.h"
|
||||
#include "packet.h"
|
||||
#include "session.h"
|
||||
#include "dbutil.h"
|
||||
#include "ssh.h"
|
||||
#include "algo.h"
|
||||
#include "buffer.h"
|
||||
#include "kex.h"
|
||||
#include "random.h"
|
||||
#include "service.h"
|
||||
#include "auth.h"
|
||||
#include "channel.h"
|
||||
|
||||
#define MAX_UNAUTH_PACKET_TYPE SSH_MSG_USERAUTH_PK_OK
|
||||
|
||||
static void recv_unimplemented();
|
||||
|
||||
/* process a decrypted packet, call the appropriate handler */
|
||||
void process_packet() {
|
||||
|
||||
unsigned char type;
|
||||
unsigned int i;
|
||||
|
||||
TRACE(("enter process_packet"));
|
||||
|
||||
type = buf_getbyte(ses.payload);
|
||||
TRACE(("process_packet: packet type = %d", type));
|
||||
|
||||
/* These packets we can receive at any time */
|
||||
switch(type) {
|
||||
|
||||
case SSH_MSG_IGNORE:
|
||||
case SSH_MSG_DEBUG:
|
||||
TRACE(("received SSH_MSG_IGNORE or SSH_MSG_DEBUG"));
|
||||
goto out;
|
||||
|
||||
case SSH_MSG_UNIMPLEMENTED:
|
||||
/* debugging XXX */
|
||||
TRACE(("SSH_MSG_UNIMPLEMENTED"));
|
||||
dropbear_exit("received SSH_MSG_UNIMPLEMENTED");
|
||||
|
||||
case SSH_MSG_DISCONNECT:
|
||||
/* TODO cleanup? */
|
||||
dropbear_close("Disconnect received");
|
||||
}
|
||||
|
||||
|
||||
/* This applies for KEX, where the spec says the next packet MUST be
|
||||
* NEWKEYS */
|
||||
if (ses.requirenext != 0) {
|
||||
if (ses.requirenext != type) {
|
||||
/* TODO send disconnect? */
|
||||
dropbear_exit("unexpected packet type %d, expected %d", type,
|
||||
ses.requirenext);
|
||||
} else {
|
||||
/* Got what we expected */
|
||||
ses.requirenext = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we should ignore this packet. Used currently only for
|
||||
* KEX code, with first_kex_packet_follows */
|
||||
if (ses.ignorenext) {
|
||||
TRACE(("Ignoring packet, type = %d", type));
|
||||
ses.ignorenext = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* XXX This code somewhere else perhaps? */
|
||||
#ifdef DROPBEAR_CLIENT
|
||||
if (IS_DROPBEAR_CLIENT) {
|
||||
|
||||
/* XXX - needs changing */
|
||||
/* In client mode, we REUSE ses.expecting to proceed to the
|
||||
* next phase when a packet was received.
|
||||
* If the "expecting" flag is set to a non-null value, it will
|
||||
* be reset when a packet of that type is received.
|
||||
* This is different from the server-mode behaviour, when
|
||||
* a packet type mismatch would have caused sudden death.
|
||||
*/
|
||||
|
||||
/* check that we aren't expecting a particular packet */
|
||||
if (cli_ses.expecting && cli_ses.expecting == type) {
|
||||
cli_ses.expecting = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Kindly the protocol authors gave all the preauth packets type values
|
||||
* less-than-or-equal-to 60 ( == MAX_UNAUTH_PACKET_TYPE ).
|
||||
* NOTE: if the protocol changes and new types are added, revisit this
|
||||
* assumption */
|
||||
if ( !ses.authdone && type > MAX_UNAUTH_PACKET_TYPE ) {
|
||||
dropbear_exit("received message %d before userauth", type);
|
||||
}
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
if (ses.packettypes[i].type == 0) {
|
||||
/* end of list */
|
||||
break;
|
||||
}
|
||||
|
||||
if (ses.packettypes[i].type == type) {
|
||||
ses.packettypes[i].handler();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TODO do something more here? */
|
||||
TRACE(("preauth unknown packet"));
|
||||
recv_unimplemented();
|
||||
|
||||
out:
|
||||
buf_free(ses.payload);
|
||||
ses.payload = NULL;
|
||||
|
||||
TRACE(("leave process_packet"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This must be called directly after receiving the unimplemented packet.
|
||||
* Isn't the most clean implementation, it relies on packet processing
|
||||
* occurring directly after decryption (direct use of ses.recvseq).
|
||||
* This is reasonably valid, since there is only a single decryption buffer */
|
||||
static void recv_unimplemented() {
|
||||
|
||||
CHECKCLEARTOWRITE();
|
||||
|
||||
buf_putbyte(ses.writepayload, SSH_MSG_UNIMPLEMENTED);
|
||||
/* the decryption routine increments the sequence number, we must
|
||||
* decrement */
|
||||
buf_putint(ses.writepayload, ses.recvseq - 1);
|
||||
|
||||
encrypt_packet();
|
||||
}
|
17
session.h
17
session.h
@ -34,6 +34,7 @@
|
||||
#include "queue.h"
|
||||
#include "runopts.h"
|
||||
#include "listener.h"
|
||||
#include "packet.h"
|
||||
|
||||
extern int sessinitdone; /* Is set to 0 somewhere */
|
||||
extern int exitflag;
|
||||
@ -106,10 +107,13 @@ struct sshsession {
|
||||
unsigned int transseq, recvseq; /* Sequence IDs */
|
||||
|
||||
/* Packet-handling flags */
|
||||
const packettype * packettypes; /* Packet handler mappings for this
|
||||
session, see process-packet.c */
|
||||
|
||||
unsigned dataallowed : 1; /* whether we can send data packets or we are in
|
||||
the middle of a KEX or something */
|
||||
|
||||
unsigned char expecting; /* byte indicating what packet we expect next,
|
||||
unsigned char requirenext; /* byte indicating what packet we require next,
|
||||
or 0x00 for any */
|
||||
|
||||
unsigned char ignorenext; /* whether to ignore the next packet,
|
||||
@ -130,6 +134,12 @@ struct sshsession {
|
||||
can add it to the hash when generating keys */
|
||||
|
||||
|
||||
unsigned char authdone; /* Indicates when authentication has been
|
||||
completed. This applies to both client and
|
||||
server - in the server it gets set to 1 when
|
||||
authentication is successful, in the client it
|
||||
is set when the server has told us that auth
|
||||
succeeded */
|
||||
|
||||
/* Channel related */
|
||||
struct Channel ** channels; /* these pointers may be null */
|
||||
@ -138,10 +148,13 @@ struct sshsession {
|
||||
|
||||
|
||||
/* TCP forwarding - where manage listeners */
|
||||
#ifndef DISABLE_REMOTETCPFWD
|
||||
#ifdef USING_LISTENERS
|
||||
struct Listener ** listeners;
|
||||
unsigned int listensize;
|
||||
/* Whether to allow binding to privileged ports (<1024). This doesn't
|
||||
* really belong here, but nowhere else fits nicely */
|
||||
#endif
|
||||
int allowprivport;
|
||||
|
||||
};
|
||||
|
||||
|
3
ssh.h
3
ssh.h
@ -44,6 +44,9 @@
|
||||
#define SSH_MSG_USERAUTH_BANNER 53
|
||||
#define SSH_MSG_USERAUTH_PK_OK 60
|
||||
|
||||
/* If adding numbers here, check MAX_UNAUTH_PACKET_TYPE in process-packet.c
|
||||
* is still valid */
|
||||
|
||||
/* connect message numbers */
|
||||
#define SSH_MSG_GLOBAL_REQUEST 80
|
||||
#define SSH_MSG_REQUEST_SUCCESS 81
|
||||
|
10
svr-auth.c
10
svr-auth.c
@ -52,7 +52,7 @@ void authinitialise() {
|
||||
* on initialisation */
|
||||
static void authclear() {
|
||||
|
||||
svr_ses.authstate.authdone = 0;
|
||||
ses.authdone = 0;
|
||||
svr_ses.authstate.pw = NULL;
|
||||
svr_ses.authstate.username = NULL;
|
||||
svr_ses.authstate.printableuser = NULL;
|
||||
@ -102,7 +102,7 @@ void recv_msg_userauth_request() {
|
||||
TRACE(("enter recv_msg_userauth_request"));
|
||||
|
||||
/* ignore packets if auth is already done */
|
||||
if (svr_ses.authstate.authdone == 1) {
|
||||
if (ses.authdone == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -339,7 +339,11 @@ void send_msg_userauth_success() {
|
||||
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_SUCCESS);
|
||||
encrypt_packet();
|
||||
|
||||
svr_ses.authstate.authdone = 1;
|
||||
ses.authdone = 1;
|
||||
|
||||
if (svr_ses.authstate.pw->pw_uid == 0) {
|
||||
ses.allowprivport = 1;
|
||||
}
|
||||
|
||||
/* Remove from the list of pre-auth sockets. Should be m_close(), since if
|
||||
* we fail, we might end up leaking connection slots, and disallow new
|
||||
|
@ -57,7 +57,7 @@ void recv_msg_kexdh_init() {
|
||||
mp_clear(&dh_e);
|
||||
|
||||
send_msg_newkeys();
|
||||
ses.expecting = SSH_MSG_NEWKEYS;
|
||||
ses.requirenext = SSH_MSG_NEWKEYS;
|
||||
TRACE(("leave recv_msg_kexdh_init"));
|
||||
}
|
||||
|
||||
|
196
svr-packet.c
196
svr-packet.c
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Dropbear - a SSH2 server
|
||||
*
|
||||
* Copyright (c) 2002,2003 Matt Johnston
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE. */
|
||||
|
||||
#include "includes.h"
|
||||
#include "packet.h"
|
||||
#include "session.h"
|
||||
#include "dbutil.h"
|
||||
#include "ssh.h"
|
||||
#include "algo.h"
|
||||
#include "buffer.h"
|
||||
#include "kex.h"
|
||||
#include "random.h"
|
||||
#include "service.h"
|
||||
#include "auth.h"
|
||||
#include "channel.h"
|
||||
|
||||
static void svr_process_postauth_packet(unsigned int type);
|
||||
|
||||
/* process a decrypted packet, call the appropriate handler */
|
||||
void svr_process_packet() {
|
||||
|
||||
unsigned char type;
|
||||
|
||||
TRACE(("enter process_packet"));
|
||||
|
||||
type = buf_getbyte(ses.payload);
|
||||
TRACE(("process_packet: packet type = %d", type));
|
||||
|
||||
/* these packets we can receive at any time, regardless of expecting
|
||||
* other packets: */
|
||||
switch(type) {
|
||||
|
||||
case SSH_MSG_IGNORE:
|
||||
case SSH_MSG_DEBUG:
|
||||
TRACE(("received SSH_MSG_IGNORE or SSH_MSG_DEBUG"));
|
||||
goto out;
|
||||
|
||||
case SSH_MSG_UNIMPLEMENTED:
|
||||
/* debugging XXX */
|
||||
TRACE(("SSH_MSG_UNIMPLEMENTED"));
|
||||
dropbear_exit("received SSH_MSG_UNIMPLEMENTED");
|
||||
|
||||
case SSH_MSG_DISCONNECT:
|
||||
/* TODO cleanup? */
|
||||
dropbear_close("Disconnect received");
|
||||
}
|
||||
|
||||
/* Check if we should ignore this packet. Used currently only for
|
||||
* KEX code, with first_kex_packet_follows */
|
||||
if (ses.ignorenext) {
|
||||
TRACE(("Ignoring packet, type = %d", type));
|
||||
ses.ignorenext = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check that we aren't expecting a particular packet */
|
||||
if (ses.expecting && ses.expecting != type) {
|
||||
/* TODO send disconnect? */
|
||||
dropbear_exit("unexpected packet type %d, expected %d", type,
|
||||
ses.expecting);
|
||||
}
|
||||
|
||||
/* handle the packet depending on type */
|
||||
ses.expecting = 0;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case SSH_MSG_SERVICE_REQUEST:
|
||||
recv_msg_service_request();
|
||||
break;
|
||||
|
||||
case SSH_MSG_USERAUTH_REQUEST:
|
||||
recv_msg_userauth_request();
|
||||
break;
|
||||
|
||||
case SSH_MSG_KEXINIT:
|
||||
recv_msg_kexinit();
|
||||
break;
|
||||
|
||||
case SSH_MSG_KEXDH_INIT:
|
||||
recv_msg_kexdh_init();
|
||||
break;
|
||||
|
||||
case SSH_MSG_NEWKEYS:
|
||||
recv_msg_newkeys();
|
||||
break;
|
||||
|
||||
/* this is ugly, need to make a cleaner way to do it */
|
||||
case SSH_MSG_CHANNEL_DATA:
|
||||
case SSH_MSG_CHANNEL_WINDOW_ADJUST:
|
||||
case SSH_MSG_CHANNEL_REQUEST:
|
||||
case SSH_MSG_CHANNEL_OPEN:
|
||||
case SSH_MSG_CHANNEL_EOF:
|
||||
case SSH_MSG_CHANNEL_CLOSE:
|
||||
case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
|
||||
case SSH_MSG_CHANNEL_OPEN_FAILURE:
|
||||
case SSH_MSG_GLOBAL_REQUEST:
|
||||
/* these should be checked for authdone below */
|
||||
svr_process_postauth_packet(type);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* TODO this possibly should be handled */
|
||||
TRACE(("preauth unknown packet"));
|
||||
recv_unimplemented();
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
buf_free(ses.payload);
|
||||
ses.payload = NULL;
|
||||
|
||||
TRACE(("leave process_packet"));
|
||||
}
|
||||
|
||||
/* process a packet, and also check that auth has been done */
|
||||
static void svr_process_postauth_packet(unsigned int type) {
|
||||
|
||||
/* messages following here require userauth before use */
|
||||
|
||||
/* IF YOU ADD MORE PACKET TYPES, MAKE SURE THEY'RE ALSO ADDED TO THE LIST
|
||||
* IN process_packet() XXX XXX XXX */
|
||||
if (!svr_ses.authstate.authdone) {
|
||||
dropbear_exit("received message %d before userauth", type);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
||||
case SSH_MSG_CHANNEL_DATA:
|
||||
recv_msg_channel_data();
|
||||
break;
|
||||
|
||||
case SSH_MSG_CHANNEL_WINDOW_ADJUST:
|
||||
recv_msg_channel_window_adjust();
|
||||
break;
|
||||
|
||||
#ifndef DISABLE_REMOTETCPFWD
|
||||
case SSH_MSG_GLOBAL_REQUEST:
|
||||
/* currently only used for remote tcp, so we cheat a little */
|
||||
recv_msg_global_request_remotetcp();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSH_MSG_CHANNEL_REQUEST:
|
||||
recv_msg_channel_request();
|
||||
break;
|
||||
|
||||
case SSH_MSG_CHANNEL_OPEN:
|
||||
recv_msg_channel_open();
|
||||
break;
|
||||
|
||||
case SSH_MSG_CHANNEL_EOF:
|
||||
recv_msg_channel_eof();
|
||||
break;
|
||||
|
||||
case SSH_MSG_CHANNEL_CLOSE:
|
||||
recv_msg_channel_close();
|
||||
break;
|
||||
|
||||
#ifdef USING_LISTENERS /* for x11, tcp fwd etc */
|
||||
case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
|
||||
recv_msg_channel_open_confirmation();
|
||||
break;
|
||||
|
||||
case SSH_MSG_CHANNEL_OPEN_FAILURE:
|
||||
recv_msg_channel_open_failure();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
TRACE(("unknown packet()"));
|
||||
recv_unimplemented();
|
||||
break;
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@ void recv_msg_service_request() {
|
||||
/* ssh-connection */
|
||||
if (len == SSH_SERVICE_CONNECTION_LEN &&
|
||||
(strncmp(SSH_SERVICE_CONNECTION, name, len) == 0)) {
|
||||
if (svr_ses.authstate.authdone != 1) {
|
||||
if (ses.authdone != 1) {
|
||||
dropbear_exit("request for connection before auth");
|
||||
}
|
||||
|
||||
|
@ -36,18 +36,39 @@
|
||||
#include "chansession.h"
|
||||
#include "atomicio.h"
|
||||
#include "tcpfwd-direct.h"
|
||||
#include "service.h"
|
||||
#include "auth.h"
|
||||
#include "tcpfwd-remote.h"
|
||||
|
||||
static void svr_remoteclosed();
|
||||
|
||||
struct serversession svr_ses;
|
||||
|
||||
const struct ChanType *chantypes[] = {
|
||||
static const packettype svr_packettypes[] = {
|
||||
/* TYPE, AUTHREQUIRED, FUNCTION */
|
||||
{SSH_MSG_SERVICE_REQUEST, recv_msg_service_request}, // server
|
||||
{SSH_MSG_USERAUTH_REQUEST, recv_msg_userauth_request}, //server
|
||||
{SSH_MSG_KEXINIT, recv_msg_kexinit},
|
||||
{SSH_MSG_KEXDH_INIT, recv_msg_kexdh_init},
|
||||
{SSH_MSG_NEWKEYS, recv_msg_newkeys},
|
||||
{SSH_MSG_CHANNEL_DATA, recv_msg_channel_data},
|
||||
{SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust},
|
||||
{SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp},
|
||||
{SSH_MSG_CHANNEL_REQUEST, recv_msg_channel_request},
|
||||
{SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open},
|
||||
{SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof},
|
||||
{SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close},
|
||||
{SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation},
|
||||
{SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
|
||||
{0, 0} /* End */
|
||||
};
|
||||
|
||||
static const struct ChanType *svr_chantypes[] = {
|
||||
&svrchansess,
|
||||
&chan_tcpdirect,
|
||||
NULL /* Null termination is mandatory. */
|
||||
};
|
||||
|
||||
|
||||
void svr_session(int sock, runopts *opts, int childpipe,
|
||||
struct sockaddr* remoteaddr) {
|
||||
|
||||
@ -64,7 +85,7 @@ void svr_session(int sock, runopts *opts, int childpipe,
|
||||
/* Initialise server specific parts of the session */
|
||||
svr_ses.childpipe = childpipe;
|
||||
authinitialise();
|
||||
chaninitialise(chantypes);
|
||||
chaninitialise(svr_chantypes);
|
||||
svr_chansessinitialise();
|
||||
|
||||
if (gettimeofday(&timeout, 0) < 0) {
|
||||
@ -76,6 +97,9 @@ void svr_session(int sock, runopts *opts, int childpipe,
|
||||
/* set up messages etc */
|
||||
session_remoteclosed = svr_remoteclosed;
|
||||
|
||||
/* packet handlers */
|
||||
ses.packettypes = svr_packettypes;
|
||||
|
||||
/* We're ready to go now */
|
||||
sessinitdone = 1;
|
||||
|
||||
@ -145,7 +169,7 @@ void svr_session(int sock, runopts *opts, int childpipe,
|
||||
/* Process the decrypted packet. After this, the read buffer
|
||||
* will be ready for a new packet */
|
||||
if (ses.payload != NULL) {
|
||||
svr_process_packet();
|
||||
process_packet();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,13 +208,10 @@ static int remotetcpreq() {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* XXX matt - server change
|
||||
if (ses.authstate.pw->pw_uid != 0
|
||||
&& port < IPPORT_RESERVED) {
|
||||
if (!ses.allowprivport && port < IPPORT_RESERVED) {
|
||||
TRACE(("can't assign port < 1024 for non-root"));
|
||||
goto out;
|
||||
}
|
||||
*/
|
||||
|
||||
ret = listen_tcpfwd(bindaddr, port);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user