1 /* 2 * Dropbear - a SSH2 server 3 * 4 * Copyright (c) 2002,2003 Matt Johnston 5 * All rights reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. */ 24 25 #ifndef DROPBEAR_SESSION_H_ 26 #define DROPBEAR_SESSION_H_ 27 28 #include "includes.h" 29 #include "buffer.h" 30 #include "signkey.h" 31 #include "kex.h" 32 #include "auth.h" 33 #include "channel.h" 34 #include "queue.h" 35 #include "listener.h" 36 #include "packet.h" 37 #include "tcpfwd.h" 38 #include "chansession.h" 39 #include "dbutil.h" 40 #include "netio.h" 41 #if DROPBEAR_PLUGIN 42 #include "pubkeyapi.h" 43 #endif 44 #include "gcm.h" 45 #include "chachapoly.h" 46 47 void common_session_init(int sock_in, int sock_out); 48 void session_loop(void(*loophandler)(void)) ATTRIB_NORETURN; 49 void session_cleanup(void); 50 void send_session_identification(void); 51 void send_msg_ignore(void); 52 void ignore_recv_response(void); 53 54 void update_channel_prio(void); 55 56 const char* get_user_shell(void); 57 void fill_passwd(const char* username); 58 59 /* Server */ 60 void svr_session(int sock, int childpipe) ATTRIB_NORETURN; 61 void svr_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN; 62 void svr_dropbear_log(int priority, const char* format, va_list param); 63 64 /* Client */ 65 void cli_session(int sock_in, int sock_out, struct dropbear_progress_connection *progress, pid_t proxy_cmd_pid) ATTRIB_NORETURN; 66 void cli_connected(int result, int sock, void* userdata, const char *errstring); 67 void cli_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN; 68 void cli_dropbear_log(int priority, const char* format, va_list param); 69 void cleantext(char* dirtytext); 70 void kill_proxy_command(void); 71 72 /* crypto parameters that are stored individually for transmit and receive */ 73 struct key_context_directional { 74 const struct dropbear_cipher *algo_crypt; 75 const struct dropbear_cipher_mode *crypt_mode; 76 const struct dropbear_hash *algo_mac; 77 int hash_index; /* lookup for libtomcrypt */ 78 int algo_comp; /* compression */ 79 #ifndef DISABLE_ZLIB 80 z_streamp zstream; 81 #endif 82 /* actual keys */ 83 union { 84 #if DROPBEAR_ENABLE_CBC_MODE 85 symmetric_CBC cbc; 86 #endif 87 #if DROPBEAR_ENABLE_CTR_MODE 88 symmetric_CTR ctr; 89 #endif 90 #if DROPBEAR_ENABLE_GCM_MODE 91 dropbear_gcm_state gcm; 92 #endif 93 #if DROPBEAR_CHACHA20POLY1305 94 dropbear_chachapoly_state chachapoly; 95 #endif 96 } cipher_state; 97 unsigned char mackey[MAX_MAC_LEN]; 98 int valid; 99 }; 100 101 struct key_context { 102 103 struct key_context_directional recv; 104 struct key_context_directional trans; 105 106 const struct dropbear_kex *algo_kex; 107 enum signkey_type algo_hostkey; /* server key type */ 108 enum signature_type algo_signature; /* server signature type */ 109 110 int allow_compress; /* whether compression has started (useful in 111 zlib@openssh.com delayed compression case) */ 112 }; 113 114 struct packetlist; 115 struct packetlist { 116 struct packetlist *next; 117 buffer * payload; 118 }; 119 120 struct sshsession { 121 122 /* Is it a client or server? */ 123 unsigned char isserver; 124 125 time_t connect_time; /* time the connection was established 126 (cleared after auth once we're not 127 respecting AUTH_TIMEOUT any more). 128 A monotonic time, not realworld */ 129 130 int sock_in; 131 int sock_out; 132 133 /* remotehost will be initially NULL as we delay 134 * reading the remote version string. it will be set 135 * by the time any recv_() packet methods are called */ 136 char *remoteident; 137 138 int maxfd; /* the maximum file descriptor to check with select() */ 139 140 141 /* Packet buffers/values etc */ 142 buffer *writepayload; /* Unencrypted payload to write - this is used 143 throughout the code, as handlers fill out this 144 buffer with the packet to send. */ 145 struct Queue writequeue; /* A queue of encrypted packets to send */ 146 unsigned int writequeue_len; /* Number of bytes pending to send in writequeue */ 147 buffer *readbuf; /* From the wire, decrypted in-place */ 148 buffer *payload; /* Post-decompression, the actual SSH packet. 149 May have extra data at the beginning, will be 150 passed to packet processing functions positioned past 151 that, see payload_beginning */ 152 unsigned int payload_beginning; 153 unsigned int transseq, recvseq; /* Sequence IDs */ 154 155 /* Packet-handling flags */ 156 const packettype * packettypes; /* Packet handler mappings for this 157 session, see process-packet.c */ 158 159 unsigned dataallowed : 1; /* whether we can send data packets or we are in 160 the middle of a KEX or something */ 161 162 unsigned char requirenext; /* byte indicating what packets we require next, 163 or 0x00 for any. */ 164 165 unsigned char ignorenext; /* whether to ignore the next packet, 166 used for kex_follows stuff */ 167 168 unsigned char lastpacket; /* What the last received packet type was */ 169 170 int signal_pipe[2]; /* stores endpoints of a self-pipe used for 171 race-free signal handling */ 172 int channel_signal_pending; /* Flag set when the signal pipe is triggered */ 173 174 m_list conn_pending; 175 176 /* time of the last packet send/receive, for keepalive. Not real-world clock */ 177 time_t last_packet_time_keepalive_sent; 178 time_t last_packet_time_keepalive_recv; 179 time_t last_packet_time_any_sent; 180 181 time_t last_packet_time_idle; /* time of the last packet transmission or receive, for 182 idle timeout purposes so ignores SSH_MSG_IGNORE 183 or responses to keepalives. Not real-world clock */ 184 185 186 /* KEX/encryption related */ 187 struct KEXState kexstate; 188 struct key_context *keys; 189 struct key_context *newkeys; 190 buffer *session_id; /* this is the hash from the first kex */ 191 /* The below are used temporarily during kex, are freed after use */ 192 mp_int * dh_K; /* SSH_MSG_KEXDH_REPLY and sending SSH_MSH_NEWKEYS */ 193 buffer *hash; /* the session hash */ 194 buffer* kexhashbuf; /* session hash buffer calculated from various packets*/ 195 buffer* transkexinit; /* the kexinit packet we send should be kept so we 196 can add it to the hash when generating keys */ 197 198 /* Enables/disables compression */ 199 algo_type *compress_algos; 200 201 /* Other side allows SSH_MSG_EXT_INFO. Currently only set for server */ 202 int allow_ext_info; 203 204 /* a list of queued replies that should be sent after a KEX has 205 concluded (ie, while dataallowed was unset)*/ 206 struct packetlist *reply_queue_head, *reply_queue_tail; 207 208 void(*remoteclosed)(void); /* A callback to handle closure of the 209 remote connection */ 210 211 void(*extra_session_cleanup)(void); /* client or server specific cleanup */ 212 void(*send_kex_first_guess)(void); 213 214 struct AuthState authstate; /* Common amongst client and server, since most 215 struct elements are common */ 216 217 /* Channel related */ 218 struct Channel ** channels; /* these pointers may be null */ 219 unsigned int chansize; /* the number of Channel*s allocated for channels */ 220 unsigned int chancount; /* the number of Channel*s in use */ 221 const struct ChanType **chantypes; /* The valid channel types */ 222 223 /* TCP priority level for the main "port 22" tcp socket */ 224 enum dropbear_prio socket_prio; 225 226 /* TCP forwarding - where manage listeners */ 227 struct Listener ** listeners; 228 unsigned int listensize; 229 230 /* Whether to allow binding to privileged ports (<1024). This doesn't 231 * really belong here, but nowhere else fits nicely */ 232 int allowprivport; 233 234 /* this is set when we get SIGINT or SIGTERM, the handler is in main.c */ 235 volatile int exitflag; 236 /* set once the ses structure (and cli_ses/svr_ses) have been populated to their initial state */ 237 int init_done; 238 239 #if DROPBEAR_PLUGIN 240 struct PluginSession * plugin_session; 241 #endif 242 }; 243 244 struct serversession { 245 246 /* Server specific options */ 247 int childpipe; /* kept open until we successfully authenticate */ 248 /* userauth */ 249 250 struct ChildPid * childpids; /* array of mappings childpid<->channel */ 251 unsigned int childpidsize; 252 253 /* Used to avoid a race in the exit returncode handling - see 254 * svr-chansession.c for details */ 255 struct exitinfo lastexit; 256 257 /* The numeric address they connected from, used for logging */ 258 char * addrstring; 259 260 /* The resolved remote address, used for lastlog etc */ 261 char *remotehost; 262 263 #if DROPBEAR_VFORK 264 pid_t server_pid; 265 #endif 266 267 #if DROPBEAR_PLUGIN 268 /* The shared library handle */ 269 void *plugin_handle; 270 271 /* The instance created by the plugin_new function */ 272 struct PluginInstance *plugin_instance; 273 #endif 274 }; 275 276 typedef enum { 277 KEX_NOTHING, 278 KEXINIT_RCVD, 279 KEXDH_INIT_SENT, 280 KEXDONE 281 } cli_kex_state; 282 283 typedef enum { 284 STATE_NOTHING, 285 USERAUTH_WAIT, 286 USERAUTH_REQ_SENT, 287 USERAUTH_FAIL_RCVD, 288 USERAUTH_SUCCESS_RCVD, 289 SESSION_RUNNING 290 } cli_state; 291 292 struct clientsession { 293 294 /* XXX - move these to kexstate? */ 295 struct kex_dh_param *dh_param; 296 struct kex_ecdh_param *ecdh_param; 297 struct kex_curve25519_param *curve25519_param; 298 const struct dropbear_kex *param_kex_algo; /* KEX algorithm corresponding to current dh_e and dh_x */ 299 300 cli_kex_state kex_state; /* Used for progressing KEX */ 301 cli_state state; /* Used to progress auth/channelsession etc */ 302 303 int tty_raw_mode; /* Whether we're in raw mode (and have to clean up) */ 304 struct termios saved_tio; 305 int stdincopy; 306 int stdinflags; 307 int stdoutcopy; 308 int stdoutflags; 309 int stderrcopy; 310 int stderrflags; 311 312 /* for escape char handling */ 313 int last_char; 314 315 volatile int winchange; /* Set to 1 when a windowchange signal happens */ 316 317 int lastauthtype; /* either AUTH_TYPE_PUBKEY or AUTH_TYPE_PASSWORD, 318 for the last type of auth we tried */ 319 int ignore_next_auth_response; 320 #if DROPBEAR_CLI_INTERACT_AUTH 321 int auth_interact_failed; /* flag whether interactive auth can still 322 be used */ 323 int interact_request_received; /* flag whether we've received an 324 info request from the server for 325 interactive auth.*/ 326 #endif 327 sign_key *lastprivkey; 328 329 buffer *server_sig_algs; 330 331 int retval; /* What the command exit status was - we emulate it */ 332 #if 0 333 TODO 334 struct AgentkeyList *agentkeys; /* Keys to use for public-key auth */ 335 #endif 336 337 pid_t proxy_cmd_pid; 338 }; 339 340 /* Global structs storing the state */ 341 extern struct sshsession ses; 342 343 #if DROPBEAR_SERVER 344 extern struct serversession svr_ses; 345 #endif /* DROPBEAR_SERVER */ 346 347 #if DROPBEAR_CLIENT 348 extern struct clientsession cli_ses; 349 #endif /* DROPBEAR_CLIENT */ 350 351 #endif /* DROPBEAR_SESSION_H_ */ 352