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