dropbear/session.h

353 lines
11 KiB
C
Raw Normal View History

/*
* 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. */
#ifndef DROPBEAR_SESSION_H_
#define DROPBEAR_SESSION_H_
#include "includes.h"
#include "buffer.h"
#include "signkey.h"
#include "kex.h"
#include "auth.h"
#include "channel.h"
#include "queue.h"
#include "listener.h"
#include "packet.h"
#include "tcpfwd.h"
#include "chansession.h"
#include "dbutil.h"
#include "netio.h"
2019-05-15 13:59:45 +00:00
#if DROPBEAR_PLUGIN
#include "pubkeyapi.h"
#endif
Add Chacha20-Poly1305, AES128-GCM and AES256-GCM support (#93) * Add Chacha20-Poly1305 authenticated encryption * Add general AEAD approach. * Add chacha20-poly1305@openssh.com algo using LibTomCrypt chacha and poly1305 routines. Chacha20-Poly1305 is generally faster than AES256 on CPU w/o dedicated AES instructions, having the same key size. Compiling in will add ~5,5kB to binary size on x86-64. function old new delta chacha_crypt - 1397 +1397 _poly1305_block - 608 +608 poly1305_done - 595 +595 dropbear_chachapoly_crypt - 457 +457 .rodata 26976 27392 +416 poly1305_process - 290 +290 poly1305_init - 221 +221 chacha_setup - 218 +218 encrypt_packet 1068 1270 +202 dropbear_chachapoly_getlength - 147 +147 decrypt_packet 756 897 +141 chacha_ivctr64 - 137 +137 read_packet 543 637 +94 dropbear_chachapoly_start - 94 +94 read_kex_algos 792 880 +88 chacha_keystream - 69 +69 dropbear_mode_chachapoly - 48 +48 sshciphers 280 320 +40 dropbear_mode_none 24 48 +24 dropbear_mode_ctr 24 48 +24 dropbear_mode_cbc 24 48 +24 dropbear_chachapoly_mac - 24 +24 dropbear_chachapoly - 24 +24 gen_new_keys 848 854 +6 ------------------------------------------------------------------------------ (add/remove: 14/0 grow/shrink: 10/0 up/down: 5388/0) Total: 5388 bytes * Add AES128-GCM and AES256-GCM authenticated encryption * Add general AES-GCM mode. * Add aes128-gcm@openssh.com and aes256-gcm@openssh.com algo using LibTomCrypt gcm routines. AES-GCM is combination of AES CTR mode and GHASH, slower than AES-CTR on CPU w/o dedicated AES/GHASH instructions therefore disabled by default. Compiling in will add ~6kB to binary size on x86-64. function old new delta gcm_process - 1060 +1060 .rodata 26976 27808 +832 gcm_gf_mult - 820 +820 gcm_add_aad - 660 +660 gcm_shift_table - 512 +512 gcm_done - 471 +471 gcm_add_iv - 384 +384 gcm_init - 347 +347 dropbear_gcm_crypt - 309 +309 encrypt_packet 1068 1270 +202 decrypt_packet 756 897 +141 gcm_reset - 118 +118 read_packet 543 637 +94 read_kex_algos 792 880 +88 sshciphers 280 360 +80 gcm_mult_h - 80 +80 dropbear_gcm_start - 62 +62 dropbear_mode_gcm - 48 +48 dropbear_mode_none 24 48 +24 dropbear_mode_ctr 24 48 +24 dropbear_mode_cbc 24 48 +24 dropbear_ghash - 24 +24 dropbear_gcm_getlength - 24 +24 gen_new_keys 848 854 +6 ------------------------------------------------------------------------------ (add/remove: 14/0 grow/shrink: 10/0 up/down: 6434/0) Total: 6434 bytes
2020-05-25 15:50:25 +00:00
#include "gcm.h"
#include "chachapoly.h"
void common_session_init(int sock_in, int sock_out);
2018-02-20 15:13:42 +00:00
void session_loop(void(*loophandler)(void)) ATTRIB_NORETURN;
2016-01-01 15:30:31 +00:00
void session_cleanup(void);
void send_session_identification(void);
void send_msg_ignore(void);
void ignore_recv_response(void);
2016-01-01 15:30:31 +00:00
void update_channel_prio(void);
2016-01-01 15:30:31 +00:00
const char* get_user_shell(void);
void fill_passwd(const char* username);
/* Server */
void svr_session(int sock, int childpipe) ATTRIB_NORETURN;
void svr_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN;
void svr_dropbear_log(int priority, const char* format, va_list param);
/* Client */
void cli_session(int sock_in, int sock_out, struct dropbear_progress_connection *progress, pid_t proxy_cmd_pid) ATTRIB_NORETURN;
void cli_connected(int result, int sock, void* userdata, const char *errstring);
void cli_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN;
void cli_dropbear_log(int priority, const char* format, va_list param);
void cleantext(char* dirtytext);
2016-01-01 15:30:31 +00:00
void kill_proxy_command(void);
/* crypto parameters that are stored individually for transmit and receive */
struct key_context_directional {
2013-03-20 15:13:45 +00:00
const struct dropbear_cipher *algo_crypt;
const struct dropbear_cipher_mode *crypt_mode;
2013-03-20 15:13:45 +00:00
const struct dropbear_hash *algo_mac;
int hash_index; /* lookup for libtomcrypt */
int algo_comp; /* compression */
#ifndef DISABLE_ZLIB
z_streamp zstream;
#endif
/* actual keys */
union {
#if DROPBEAR_ENABLE_CBC_MODE
symmetric_CBC cbc;
#endif
#if DROPBEAR_ENABLE_CTR_MODE
symmetric_CTR ctr;
Add Chacha20-Poly1305, AES128-GCM and AES256-GCM support (#93) * Add Chacha20-Poly1305 authenticated encryption * Add general AEAD approach. * Add chacha20-poly1305@openssh.com algo using LibTomCrypt chacha and poly1305 routines. Chacha20-Poly1305 is generally faster than AES256 on CPU w/o dedicated AES instructions, having the same key size. Compiling in will add ~5,5kB to binary size on x86-64. function old new delta chacha_crypt - 1397 +1397 _poly1305_block - 608 +608 poly1305_done - 595 +595 dropbear_chachapoly_crypt - 457 +457 .rodata 26976 27392 +416 poly1305_process - 290 +290 poly1305_init - 221 +221 chacha_setup - 218 +218 encrypt_packet 1068 1270 +202 dropbear_chachapoly_getlength - 147 +147 decrypt_packet 756 897 +141 chacha_ivctr64 - 137 +137 read_packet 543 637 +94 dropbear_chachapoly_start - 94 +94 read_kex_algos 792 880 +88 chacha_keystream - 69 +69 dropbear_mode_chachapoly - 48 +48 sshciphers 280 320 +40 dropbear_mode_none 24 48 +24 dropbear_mode_ctr 24 48 +24 dropbear_mode_cbc 24 48 +24 dropbear_chachapoly_mac - 24 +24 dropbear_chachapoly - 24 +24 gen_new_keys 848 854 +6 ------------------------------------------------------------------------------ (add/remove: 14/0 grow/shrink: 10/0 up/down: 5388/0) Total: 5388 bytes * Add AES128-GCM and AES256-GCM authenticated encryption * Add general AES-GCM mode. * Add aes128-gcm@openssh.com and aes256-gcm@openssh.com algo using LibTomCrypt gcm routines. AES-GCM is combination of AES CTR mode and GHASH, slower than AES-CTR on CPU w/o dedicated AES/GHASH instructions therefore disabled by default. Compiling in will add ~6kB to binary size on x86-64. function old new delta gcm_process - 1060 +1060 .rodata 26976 27808 +832 gcm_gf_mult - 820 +820 gcm_add_aad - 660 +660 gcm_shift_table - 512 +512 gcm_done - 471 +471 gcm_add_iv - 384 +384 gcm_init - 347 +347 dropbear_gcm_crypt - 309 +309 encrypt_packet 1068 1270 +202 decrypt_packet 756 897 +141 gcm_reset - 118 +118 read_packet 543 637 +94 read_kex_algos 792 880 +88 sshciphers 280 360 +80 gcm_mult_h - 80 +80 dropbear_gcm_start - 62 +62 dropbear_mode_gcm - 48 +48 dropbear_mode_none 24 48 +24 dropbear_mode_ctr 24 48 +24 dropbear_mode_cbc 24 48 +24 dropbear_ghash - 24 +24 dropbear_gcm_getlength - 24 +24 gen_new_keys 848 854 +6 ------------------------------------------------------------------------------ (add/remove: 14/0 grow/shrink: 10/0 up/down: 6434/0) Total: 6434 bytes
2020-05-25 15:50:25 +00:00
#endif
#if DROPBEAR_ENABLE_GCM_MODE
dropbear_gcm_state gcm;
#endif
#if DROPBEAR_CHACHA20POLY1305
dropbear_chachapoly_state chachapoly;
#endif
} cipher_state;
unsigned char mackey[MAX_MAC_LEN];
int valid;
};
struct key_context {
struct key_context_directional recv;
struct key_context_directional trans;
const struct dropbear_kex *algo_kex;
enum signkey_type algo_hostkey; /* server key type */
enum signature_type algo_signature; /* server signature type */
int allow_compress; /* whether compression has started (useful in
zlib@openssh.com delayed compression case) */
};
struct packetlist;
struct packetlist {
struct packetlist *next;
buffer * payload;
};
struct sshsession {
/* Is it a client or server? */
unsigned char isserver;
time_t connect_time; /* time the connection was established
(cleared after auth once we're not
respecting AUTH_TIMEOUT any more).
A monotonic time, not realworld */
int sock_in;
int sock_out;
/* remotehost will be initially NULL as we delay
* reading the remote version string. it will be set
* by the time any recv_() packet methods are called */
char *remoteident;
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 */
unsigned int writequeue_len; /* Number of bytes pending to send in writequeue */
buffer *readbuf; /* From the wire, decrypted in-place */
buffer *payload; /* Post-decompression, the actual SSH packet.
May have extra data at the beginning, will be
passed to packet processing functions positioned past
that, see payload_beginning */
unsigned int payload_beginning;
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 */
2014-01-23 14:25:52 +00:00
unsigned char requirenext; /* byte indicating what packets 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 */
int signal_pipe[2]; /* stores endpoints of a self-pipe used for
race-free signal handling */
int channel_signal_pending; /* Flag set when the signal pipe is triggered */
m_list conn_pending;
/* time of the last packet send/receive, for keepalive. Not real-world clock */
time_t last_packet_time_keepalive_sent;
time_t last_packet_time_keepalive_recv;
time_t last_packet_time_any_sent;
time_t last_packet_time_idle; /* time of the last packet transmission or receive, for
idle timeout purposes so ignores SSH_MSG_IGNORE
or responses to keepalives. Not real-world clock */
/* KEX/encryption related */
struct KEXState kexstate;
struct key_context *keys;
struct key_context *newkeys;
buffer *session_id; /* this is the hash from the first kex */
/* The below are used temporarily during kex, are freed after use */
mp_int * dh_K; /* SSH_MSG_KEXDH_REPLY and sending SSH_MSH_NEWKEYS */
buffer *hash; /* the session hash */
buffer* kexhashbuf; /* session hash buffer calculated from various packets*/
buffer* transkexinit; /* the kexinit packet we send should be kept so we
can add it to the hash when generating keys */
/* Enables/disables compression */
algo_type *compress_algos;
/* Other side allows SSH_MSG_EXT_INFO. Currently only set for server */
int allow_ext_info;
/* a list of queued replies that should be sent after a KEX has
concluded (ie, while dataallowed was unset)*/
struct packetlist *reply_queue_head, *reply_queue_tail;
2016-01-01 15:30:31 +00:00
void(*remoteclosed)(void); /* A callback to handle closure of the
remote connection */
2016-01-01 15:30:31 +00:00
void(*extra_session_cleanup)(void); /* client or server specific cleanup */
void(*send_kex_first_guess)(void);
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 priority level for the main "port 22" tcp socket */
enum dropbear_prio socket_prio;
/* 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;
/* this is set when we get SIGINT or SIGTERM, the handler is in main.c */
volatile int exitflag;
/* set once the ses structure (and cli_ses/svr_ses) have been populated to their initial state */
int init_done;
2019-05-15 13:59:45 +00:00
#if DROPBEAR_PLUGIN
struct PluginSession * plugin_session;
#endif
};
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;
/* The resolved remote address, used for lastlog etc */
char *remotehost;
#if DROPBEAR_VFORK
pid_t server_pid;
#endif
2019-05-15 13:59:45 +00:00
#if DROPBEAR_PLUGIN
/* The shared library handle */
void *plugin_handle;
/* The instance created by the plugin_new function */
struct PluginInstance *plugin_instance;
#endif
};
typedef enum {
KEX_NOTHING,
KEXINIT_RCVD,
KEXDH_INIT_SENT,
KEXDONE
} cli_kex_state;
typedef enum {
STATE_NOTHING,
USERAUTH_WAIT,
USERAUTH_REQ_SENT,
USERAUTH_FAIL_RCVD,
USERAUTH_SUCCESS_RCVD,
SESSION_RUNNING
} cli_state;
struct clientsession {
2013-11-14 14:03:30 +00:00
/* XXX - move these to kexstate? */
struct kex_dh_param *dh_param;
struct kex_ecdh_param *ecdh_param;
2013-11-08 15:11:43 +00:00
struct kex_curve25519_param *curve25519_param;
2013-05-21 04:09:35 +00:00
const struct dropbear_kex *param_kex_algo; /* KEX algorithm corresponding to current dh_e and dh_x */
cli_kex_state kex_state; /* Used for progressing KEX */
cli_state state; /* Used to progress auth/channelsession etc */
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;
/* for escape char handling */
int last_char;
volatile 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 */
int is_trivial_auth;
int ignore_next_auth_response;
#if DROPBEAR_CLI_INTERACT_AUTH
int auth_interact_failed; /* flag whether interactive auth can still
be used */
int interact_request_received; /* flag whether we've received an
info request from the server for
interactive auth.*/
#endif
sign_key *lastprivkey;
buffer *server_sig_algs;
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
2015-12-15 14:09:55 +00:00
pid_t proxy_cmd_pid;
};
/* Global structs storing the state */
extern struct sshsession ses;
#if DROPBEAR_SERVER
extern struct serversession svr_ses;
#endif /* DROPBEAR_SERVER */
#if DROPBEAR_CLIENT
extern struct clientsession cli_ses;
#endif /* DROPBEAR_CLIENT */
#endif /* DROPBEAR_SESSION_H_ */