Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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 *);