xref: /plan9/sys/src/cmd/ssh2/netssh.h (revision 63afb9a5d3f910047231762bcce0ee49fed3d07c)
1 #include <bio.h>
2 #include "ssh2.h"		/* ugh */
3 
4 #define MYID "SSH-2.0-Plan9"
5 
6 #pragma varargck type "M" mpint*
7 
8 enum {
9 	Server =	0,
10 	Client,
11 
12 	Maxpktpay =	35000,
13 
14 	/* qid.path components: level (2), type (4), conn (7), chan (7) */
15 	Connshift =	7,
16 	MAXCONN =	1 << Connshift,		/* also Maxchan */
17 	Chanmask =	MAXCONN - 1,
18 	Connmask =	Chanmask,
19 
20 	Qtypeshift =	2 * Connshift,		/* conn + chan */
21 
22 	Qroot =		0,
23 	Qclone =	1 << Qtypeshift,
24 	Qctl =		2 << Qtypeshift,
25 	Qdata =		3 << Qtypeshift,
26 	Qlisten =	4 << Qtypeshift,
27 	Qlocal =	5 << Qtypeshift,
28 	Qreqrem =	6 << Qtypeshift,	/* request or remote */
29 	Qstatus =	7 << Qtypeshift,
30 	Qtcp =		8 << Qtypeshift,
31 	Qtypemask =	017 << Qtypeshift,
32 
33 	Levshift =	Qtypeshift + 4,
34 
35 	/* levels of /net/ssh hierarchy */
36 	Top =		0,
37 	Connection,
38 	Subchannel,
39 };
40 
41 /*
42  * The stylistic anomaly with these names of unbounded length
43  * is a result of following the RFCs in using the same names for
44  * these constants.  I did that to make it easier to search and
45  * cross-reference between the code and the RFCs.
46  */
47 enum {					/* SSH2 Protocol Packet Types */
48 	SSH_MSG_DISCONNECT =		1,
49 	SSH_MSG_IGNORE =		2,
50 	SSH_MSG_UNIMPLEMENTED,
51 	SSH_MSG_DEBUG,
52 	SSH_MSG_SERVICE_REQUEST,
53 	SSH_MSG_SERVICE_ACCEPT,
54 
55 	SSH_MSG_KEXINIT =		20,
56 	SSH_MSG_NEWKEYS,
57 
58 	SSH_MSG_KEXDH_INIT =		30,
59 	SSH_MSG_KEXDH_REPLY,
60 
61 	SSH_MSG_USERAUTH_REQUEST =	50,
62 	SSH_MSG_USERAUTH_FAILURE,
63 	SSH_MSG_USERAUTH_SUCCESS,
64 	SSH_MSG_USERAUTH_BANNER,
65 
66 	SSH_MSG_USERAUTH_PK_OK =	60,
67 	SSH_MSG_USERAUTH_PASSWD_CHANGEREQ = 60,
68 
69 	SSH_MSG_GLOBAL_REQUEST =	80,
70 	SSH_MSG_REQUEST_SUCCESS,
71 	SSH_MSG_REQUEST_FAILURE,
72 
73 	SSH_MSG_CHANNEL_OPEN =		90,
74 	SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
75 	SSH_MSG_CHANNEL_OPEN_FAILURE,
76 	SSH_MSG_CHANNEL_WINDOW_ADJUST,
77 	SSH_MSG_CHANNEL_DATA,
78 	SSH_MSG_CHANNEL_EXTENDED_DATA,
79 	SSH_MSG_CHANNEL_EOF,
80 	SSH_MSG_CHANNEL_CLOSE,
81 	SSH_MSG_CHANNEL_REQUEST,
82 	SSH_MSG_CHANNEL_SUCCESS,
83 	SSH_MSG_CHANNEL_FAILURE,
84 };
85 
86 enum {				/* SSH2 reason codes */
87 	SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
88 	SSH_DISCONNECT_PROTOCOL_ERROR,
89 	SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
90 	SSH_DISCONNECT_RESERVED,
91 	SSH_DISCONNECT_MAC_ERROR,
92 	SSH_DISCONNECT_COMPRESSION_ERROR,
93 	SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
94 	SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
95 	SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
96 	SSH_DISCONNECT_CONNECTION_LOST,
97 	SSH_DISCONNECT_BY_APPLICATION,
98 	SSH_DISCONNECT_TOO_MANY_CONNECTIONS,
99 	SSH_DISCONNECT_AUTH_CANCELLED_BY_USER,
100 	SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
101 	SSH_DISCONNECT_ILLEGAL_USR_NAME,
102 
103 	SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1,
104 	SSH_OPEN_CONNECT_FAILED,
105 	SSH_OPEN_UNKNOWN_CHANNEL_TYPE,
106 	SSH_OPEN_RESOURCE_SHORTAGE,
107 };
108 
109 enum {				/* SSH2 type code */
110 	SSH_EXTENDED_DATA_STDERR = 1,
111 };
112 
113 enum {				/* connection and channel states */
114 	Empty = 0,
115 	Allocated,
116 	Initting,
117 	Listening,
118 	Opening,
119 	Negotiating,
120 	Authing,
121 	Established,
122 	Eof,
123 	Closing,
124 	Closed,
125 };
126 
127 enum {
128 	NoKeyFile,
129 	NoKey,
130 	KeyWrong,
131 	KeyOk,
132 };
133 
134 typedef struct Cipher Cipher;
135 typedef struct CipherState CipherState;
136 typedef struct Conn Conn;
137 typedef struct Kex Kex;
138 typedef struct MBox MBox;
139 typedef struct PKA PKA;
140 typedef struct Packet Packet;
141 typedef struct Plist Plist;
142 typedef struct SSHChan SSHChan;
143 
144 #pragma incomplete CipherState
145 
146 struct Plist {
147 	Packet	*pack;
148 	uchar	*st;
149 	int	rem;
150 	Plist	*next;
151 };
152 
153 struct SSHChan {
154 	Rendez	r;			/* awaiting input? */
155 	int	id;
156 	int	otherid;
157 	int	state;
158 	int	waker;
159 	int	conn;
160 	ulong	rwindow;
161 	ulong	twindow;
162 	ulong	sent;
163 	ulong	inrqueue;
164 	char	*ann;
165 	Req	*lreq;
166 
167 	/* File* for each Qid type */
168 	File	*dir;
169 	File	*ctl;
170 	File	*data;
171 	File	*listen;
172 	File	*request;
173 	File	*status;
174 	File	*tcp;
175 
176 	Plist	*dataq;
177 	Plist	*datatl;
178 	Plist	*reqq;
179 	Plist	*reqtl;
180 
181 	Channel	*inchan;
182 	Channel	*reqchan;
183 	QLock	xmtlock;
184 	Rendez	xmtrendez;
185 };
186 
187 struct Conn {
188 	QLock	l;
189 	Rendez	r;			/* awaiting input? */
190 
191 	Ioproc	*dio;
192 	Ioproc	*cio;
193 	Ioproc	*rio;
194 
195 	int	state;
196 	int	role;
197 	int	id;
198 
199 	char	*remote;
200 	char	*user;
201 	char	*password;
202 
203 	char	*service;
204 	char	*cap;
205 	char	*authkey;
206 	int	nchan;
207 
208 	/* underlying tcp connection */
209 	int	datafd;
210 	int	ctlfd;
211 	int	stifle;		/* flag: no i/o between listen and sshsession */
212 	int	poisoned;
213 	int	tcpconn;
214 
215 	int	rpid;
216 
217 	int	inseq;
218 	int	outseq;
219 	int	kexalg;
220 	int	pkalg;
221 
222 	int	cscrypt;
223 	int	ncscrypt;
224 	int	sccrypt;
225 	int	nsccrypt;
226 
227 	int	csmac;
228 	int	ncsmac;
229 	int	scmac;
230 	int	nscmac;
231 
232 	int	encrypt;
233 	int	decrypt;
234 
235 	int	outmac;
236 	int	inmac;
237 
238 	/* File* for each Qid type */
239 	File	*dir;
240 	File	*clonefile;
241 	File	*ctlfile;
242 	File	*datafile;
243 	File	*listenfile;
244 	File	*localfile;
245 	File	*remotefile;
246 	File	*statusfile;
247 	File	*tcpfile;
248 
249 	Packet	*skexinit;
250 	Packet	*rkexinit;
251 	mpint	*x;
252 	mpint	*e;
253 	int	got_sessid;
254 	uchar	sessid[SHA1dlen];
255 
256 	uchar	c2siv[SHA1dlen*2];
257 	uchar	nc2siv[SHA1dlen*2];
258 	uchar	s2civ[SHA1dlen*2];
259 	uchar	ns2civ[SHA1dlen*2];
260 
261 	uchar	c2sek[SHA1dlen*2];
262 	uchar	nc2sek[SHA1dlen*2];
263 	uchar	s2cek[SHA1dlen*2];
264 	uchar	ns2cek[SHA1dlen*2];
265 
266 	uchar	c2sik[SHA1dlen*2];
267 	uchar	nc2sik[SHA1dlen*2];
268 	uchar	s2cik[SHA1dlen*2];
269 	uchar	ns2cik[SHA1dlen*2];
270 
271 	char	*otherid;
272 	uchar	*inik;
273 	uchar	*outik;
274 	CipherState *s2ccs;
275 	CipherState *c2scs;
276 	CipherState *enccs;
277 	CipherState *deccs;
278 	SSHChan	*chans[MAXCONN];
279 
280 	char	idstring[256];		/* max allowed by SSH spec */
281 };
282 
283 struct Packet {
284 	Conn	*c;
285 	ulong	rlength;
286 	ulong	tlength;
287 	uchar	nlength[4];
288 	uchar	pad_len;
289 	uchar	payload[Maxpktpay];
290 };
291 
292 struct Cipher {
293 	char	*name;
294 	int	blklen;
295 	CipherState *(*init)(Conn*, int);
296 	void	(*encrypt)(CipherState*, uchar*, int);
297 	void	(*decrypt)(CipherState*, uchar*, int);
298 };
299 
300 struct Kex {
301 	char	*name;
302 	int	(*serverkex)(Conn *, Packet *);
303 	int	(*clientkex1)(Conn *, Packet *);
304 	int	(*clientkex2)(Conn *, Packet *);
305 };
306 
307 struct PKA {
308 	char	*name;
309 	Packet	*(*ks)(Conn *);
310 	Packet	*(*sign)(Conn *, uchar *, int);
311 	int	(*verify)(Conn *, uchar *, int, char *, char *, int);
312 };
313 
314 struct MBox {
315 	Channel	*mchan;
316 	char	*msg;
317 	int	state;
318 };
319 
320 extern Cipher cipheraes128, cipheraes192, cipheraes256;
321 extern Cipher cipherblowfish, cipher3des, cipherrc4;
322 extern int debug;
323 extern int sshkeychan[];
324 extern Kex dh1sha1, dh14sha1;
325 extern MBox keymbox;
326 extern PKA rsa_pka, dss_pka, *pkas[];
327 
328 /* pubkey.c */
329 int appendkey(char *, char *, RSApub *);
330 int findkey(char *, char *, RSApub *);
331 RSApub *readpublickey(Biobuf *, char **);
332 int replacekey(char *, char *, RSApub *);
333 
334 /* dh.c */
335 void dh_init(PKA *[]);
336 
337 /* transport.c */
338 void	add_block(Packet *, void *, int);
339 void	add_byte(Packet *, char);
340 void	add_mp(Packet *, mpint *);
341 int	add_packet(Packet *, void *, int);
342 void	add_string(Packet *, char *);
343 void	add_uint32(Packet *, ulong);
344 void	dump_packet(Packet *);
345 int	finish_packet(Packet *);
346 mpint	*get_mp(uchar *q);
347 uchar	*get_string(Packet *, uchar *, char *, int, int *);
348 ulong	get_uint32(Packet *, uchar **);
349 void	init_packet(Packet *);
350 Packet	*new_packet(Conn *);
351 int	undo_packet(Packet *);
352