#define _SESSION_H_
#include "includes.h"
+#include "options.h"
#include "buffer.h"
#include "signkey.h"
#include "kex.h"
#include "auth.h"
#include "channel.h"
#include "queue.h"
-#include "runopts.h"
+#include "listener.h"
+#include "packet.h"
+#include "tcpfwd.h"
+#include "chansession.h"
-extern int sessinitdone;
+extern int sessinitdone; /* Is set to 0 somewhere */
extern int exitflag;
-void session_cleanup();
-void child_session(int sock, runopts *opts, int childpipe,
- struct sockaddr *remoteaddr);
+void common_session_init(int sock, char* remotehost);
+void session_loop(void(*loophandler)());
+void common_session_cleanup();
+void session_identification();
+
+
+/* Server */
+void svr_session(int sock, int childpipe, char *remotehost, char *addrstring);
+void svr_dropbear_exit(int exitcode, const char* format, va_list param);
+void svr_dropbear_log(int priority, const char* format, va_list param);
+
+/* Client */
+void cli_session(int sock, char *remotehost);
+void cli_session_cleanup();
+void cleantext(unsigned char* dirtytext);
struct key_context {
struct sshsession {
- runopts * opts; /* runtime options, incl hostkey, banner etc */
+ /* Is it a client or server? */
+ unsigned char isserver;
+
+ long connecttimeout; /* time to disconnect if we have a timeout (for
+ userauth etc), or 0 for no timeout */
+
int sock;
- int childpipe; /* kept open until we successfully authenticate */
- long connecttime; /* time of initial connection */
- struct sockaddr *remoteaddr; /* the host and port of the client */
- unsigned char *addrstring; /* the text version of remoteaddr */
- unsigned char *hostname; /* the remote hostname */
+ unsigned char *remotehost; /* the peer hostname */
- int maxfd; /* the maximum file descriptor to check with select() */
unsigned char *remoteident;
- struct KEXState kexstate;
+ int maxfd; /* the maximum file descriptor to check with select() */
+
+
+ /* Packet buffers/values etc */
+ buffer *writepayload; /* Unencrypted payload to write - this is used
+ throughout the code, as handlers fill out this
+ buffer with the packet to send. */
+ struct Queue writequeue; /* A queue of encrypted packets to send */
+ buffer *readbuf; /* Encrypted */
+ buffer *decryptreadbuf; /* Post-decryption */
+ buffer *payload; /* Post-decompression, the actual SSH packet */
+ unsigned int transseq, recvseq; /* Sequence IDs */
+
+ /* Packet-handling flags */
+ const packettype * packettypes; /* Packet handler mappings for this
+ session, see process-packet.c */
- /* flags */
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,
+ used for kex_follows stuff */
+
+ unsigned char lastpacket; /* What the last received packet type was */
- /* unencrypted write payload */
- buffer *writepayload; /* this will actually refer to within clearwritebuf */
- unsigned int transseq; /* sequence number */
- /* encrypted write packet buffer queue */
- struct Queue writequeue;
-
- /* read packet buffer */
- buffer *readbuf;
- /* decrypted read buffer */
- buffer *decryptreadbuf;
- buffer *payload; /* this actually refers to within decryptreadbuf */
- unsigned int recvseq; /* sequence number */
+
+ /* KEX/encryption related */
+ struct KEXState kexstate;
struct key_context *keys;
struct key_context *newkeys;
-
- unsigned char *session_id; /*this is the hash from the first kex*/
-
- /* the following are for key exchange */
- unsigned char hash[SHA1_HASH_SIZE]; /* the hash*/
- /* these are used temorarily during kex, are freed after use */
+ unsigned char *session_id; /* this is the hash from the first kex */
+ /* The below are used temorarily during kex, are freed after use */
mp_int * dh_K; /* SSH_MSG_KEXDH_REPLY and sending SSH_MSH_NEWKEYS */
+ unsigned char hash[SHA1_HASH_SIZE]; /* the hash*/
buffer* kexhashbuf; /* session hash buffer calculated from various packets*/
- buffer* transkexinit; /* the kexinit payload we send */
+ buffer* transkexinit; /* the kexinit packet we send should be kept so we
+ can add it to the hash when generating keys */
- /* userauth */
- struct AuthState authstate;
+ algo_type*(*buf_match_algo)(buffer*buf, algo_type localalgos[],
+ int *goodguess); /* The function to use to choose which algorithm
+ to use from the ones presented by the remote
+ side. Is specific to the client/server mode,
+ hence the function-pointer callback.*/
- /* channels */
+ void(*remoteclosed)(); /* A callback to handle closure of the
+ remote connection */
+
+
+ struct AuthState authstate; /* Common amongst client and server, since most
+ struct elements are common */
+
+ /* Channel related */
struct Channel ** channels; /* these pointers may be null */
unsigned int chansize; /* the number of Channel*s allocated for channels */
+ unsigned int chancount; /* the number of Channel*s in use */
+ const struct ChanType **chantypes; /* The valid channel types */
+
+
+ /* TCP forwarding - where manage 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 */
+ int allowprivport;
+
+};
+
+struct serversession {
+
+ /* Server specific options */
+ int childpipe; /* kept open until we successfully authenticate */
+ /* userauth */
struct ChildPid * childpids; /* array of mappings childpid<->channel */
unsigned int childpidsize;
+ /* Used to avoid a race in the exit returncode handling - see
+ * svr-chansession.c for details */
+ struct exitinfo lastexit;
+
+ /* The numeric address they connected from, used for logging */
+ char * addrstring;
+
+};
+
+typedef enum {
+ KEX_NOTHING,
+ KEXINIT_RCVD,
+ KEXDH_INIT_SENT,
+ KEXDONE,
+
+} cli_kex_state;
+
+typedef enum {
+ STATE_NOTHING,
+ SERVICE_AUTH_REQ_SENT,
+ SERVICE_AUTH_ACCEPT_RCVD,
+ SERVICE_CONN_REQ_SENT,
+ SERVICE_CONN_ACCEPT_RCVD,
+ USERAUTH_REQ_SENT,
+ USERAUTH_FAIL_RCVD,
+ USERAUTH_SUCCESS_RCVD,
+ SESSION_RUNNING,
+
+} cli_state;
+
+struct clientsession {
+
+ mp_int *dh_e, *dh_x; /* Used during KEX */
+ cli_kex_state kex_state; /* Used for progressing KEX */
+ cli_state state; /* Used to progress auth/channelsession etc */
+ unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */
+
+ int tty_raw_mode; /* Whether we're in raw mode (and have to clean up) */
+ struct termios saved_tio;
+ int stdincopy;
+ int stdinflags;
+ int stdoutcopy;
+ int stdoutflags;
+ int stderrcopy;
+ int stderrflags;
+
+ int winchange; /* Set to 1 when a windowchange signal happens */
+
+ int lastauthtype; /* either AUTH_TYPE_PUBKEY or AUTH_TYPE_PASSWORD,
+ for the last type of auth we tried */
+ struct SignKeyList *lastprivkey;
+
+ int retval; /* What the command exit status was - we emulate it */
+#if 0
+ TODO
+ struct AgentkeyList *agentkeys; /* Keys to use for public-key auth */
+#endif
+
};
-/* global struct storing the state */
+/* Global structs storing the state */
extern struct sshsession ses;
+#ifdef DROPBEAR_SERVER
+extern struct serversession svr_ses;
+#endif /* DROPBEAR_SERVER */
+
+#ifdef DROPBEAR_CLIENT
+extern struct clientsession cli_ses;
+#endif /* DROPBEAR_CLIENT */
+
#endif /* _SESSION_H_ */