xref: /plan9/sys/src/cmd/ssh1/ssh.h (revision 63afb9a5d3f910047231762bcce0ee49fed3d07c)
1*63afb9a5SDavid du Colombier #include <u.h>
2*63afb9a5SDavid du Colombier #include <libc.h>
3*63afb9a5SDavid du Colombier #include <mp.h>
4*63afb9a5SDavid du Colombier #include <auth.h>
5*63afb9a5SDavid du Colombier #include <libsec.h>
6*63afb9a5SDavid du Colombier 
7*63afb9a5SDavid du Colombier enum		/* internal debugging flags */
8*63afb9a5SDavid du Colombier {
9*63afb9a5SDavid du Colombier 	DBG=			1<<0,
10*63afb9a5SDavid du Colombier 	DBG_CRYPTO=		1<<1,
11*63afb9a5SDavid du Colombier 	DBG_PACKET=		1<<2,
12*63afb9a5SDavid du Colombier 	DBG_AUTH=		1<<3,
13*63afb9a5SDavid du Colombier 	DBG_PROC=		1<<4,
14*63afb9a5SDavid du Colombier 	DBG_PROTO=		1<<5,
15*63afb9a5SDavid du Colombier 	DBG_IO=			1<<6,
16*63afb9a5SDavid du Colombier 	DBG_SCP=		1<<7,
17*63afb9a5SDavid du Colombier };
18*63afb9a5SDavid du Colombier 
19*63afb9a5SDavid du Colombier enum		/* protocol packet types */
20*63afb9a5SDavid du Colombier {
21*63afb9a5SDavid du Colombier /* 0 */
22*63afb9a5SDavid du Colombier 	SSH_MSG_NONE=0,
23*63afb9a5SDavid du Colombier 	SSH_MSG_DISCONNECT,
24*63afb9a5SDavid du Colombier 	SSH_SMSG_PUBLIC_KEY,
25*63afb9a5SDavid du Colombier 	SSH_CMSG_SESSION_KEY,
26*63afb9a5SDavid du Colombier 	SSH_CMSG_USER,
27*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_RHOSTS,
28*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_RSA,
29*63afb9a5SDavid du Colombier 	SSH_SMSG_AUTH_RSA_CHALLENGE,
30*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_RSA_RESPONSE,
31*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_PASSWORD,
32*63afb9a5SDavid du Colombier 
33*63afb9a5SDavid du Colombier /* 10 */
34*63afb9a5SDavid du Colombier 	SSH_CMSG_REQUEST_PTY,
35*63afb9a5SDavid du Colombier 	SSH_CMSG_WINDOW_SIZE,
36*63afb9a5SDavid du Colombier 	SSH_CMSG_EXEC_SHELL,
37*63afb9a5SDavid du Colombier 	SSH_CMSG_EXEC_CMD,
38*63afb9a5SDavid du Colombier 	SSH_SMSG_SUCCESS,
39*63afb9a5SDavid du Colombier 	SSH_SMSG_FAILURE,
40*63afb9a5SDavid du Colombier 	SSH_CMSG_STDIN_DATA,
41*63afb9a5SDavid du Colombier 	SSH_SMSG_STDOUT_DATA,
42*63afb9a5SDavid du Colombier 	SSH_SMSG_STDERR_DATA,
43*63afb9a5SDavid du Colombier 	SSH_CMSG_EOF,
44*63afb9a5SDavid du Colombier 
45*63afb9a5SDavid du Colombier /* 20 */
46*63afb9a5SDavid du Colombier 	SSH_SMSG_EXITSTATUS,
47*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
48*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OPEN_FAILURE,
49*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_DATA,
50*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_INPUT_EOF,
51*63afb9a5SDavid du Colombier 	SSH_MSG_CHANNEL_OUTPUT_CLOSED,
52*63afb9a5SDavid du Colombier 	SSH_MSG_UNIX_DOMAIN_X11_FORWARDING,	/* obsolete */
53*63afb9a5SDavid du Colombier 	SSH_SMSG_X11_OPEN,
54*63afb9a5SDavid du Colombier 	SSH_CMSG_PORT_FORWARD_REQUEST,
55*63afb9a5SDavid du Colombier 	SSH_MSG_PORT_OPEN,
56*63afb9a5SDavid du Colombier 
57*63afb9a5SDavid du Colombier /* 30 */
58*63afb9a5SDavid du Colombier 	SSH_CMSG_AGENT_REQUEST_FORWARDING,
59*63afb9a5SDavid du Colombier 	SSH_SMSG_AGENT_OPEN,
60*63afb9a5SDavid du Colombier 	SSH_MSG_IGNORE,
61*63afb9a5SDavid du Colombier 	SSH_CMSG_EXIT_CONFIRMATION,
62*63afb9a5SDavid du Colombier 	SSH_CMSG_X11_REQUEST_FORWARDING,
63*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_RHOSTS_RSA,
64*63afb9a5SDavid du Colombier 	SSH_MSG_DEBUG,
65*63afb9a5SDavid du Colombier 	SSH_CMSG_REQUEST_COMPRESSION,
66*63afb9a5SDavid du Colombier 	SSH_CMSG_MAX_PACKET_SIZE,
67*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_TIS,
68*63afb9a5SDavid du Colombier 
69*63afb9a5SDavid du Colombier /* 40 */
70*63afb9a5SDavid du Colombier 	SSH_SMSG_AUTH_TIS_CHALLENGE,
71*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_TIS_RESPONSE,
72*63afb9a5SDavid du Colombier 	SSH_CMSG_AUTH_KERBEROS,
73*63afb9a5SDavid du Colombier 	SSH_SMSG_AUTH_KERBEROS_RESPONSE,
74*63afb9a5SDavid du Colombier 	SSH_CMSG_HAVE_KERBEROS_TGT,
75*63afb9a5SDavid du Colombier };
76*63afb9a5SDavid du Colombier 
77*63afb9a5SDavid du Colombier enum		/* protocol flags */
78*63afb9a5SDavid du Colombier {
79*63afb9a5SDavid du Colombier 	SSH_PROTOFLAG_SCREEN_NUMBER=1<<0,
80*63afb9a5SDavid du Colombier 	SSH_PROTOFLAG_HOST_IN_FWD_OPEN=1<<1,
81*63afb9a5SDavid du Colombier };
82*63afb9a5SDavid du Colombier 
83*63afb9a5SDavid du Colombier enum		/* agent protocol packet types */
84*63afb9a5SDavid du Colombier {
85*63afb9a5SDavid du Colombier 	SSH_AGENTC_NONE = 0,
86*63afb9a5SDavid du Colombier 	SSH_AGENTC_REQUEST_RSA_IDENTITIES,
87*63afb9a5SDavid du Colombier 	SSH_AGENT_RSA_IDENTITIES_ANSWER,
88*63afb9a5SDavid du Colombier 	SSH_AGENTC_RSA_CHALLENGE,
89*63afb9a5SDavid du Colombier 	SSH_AGENT_RSA_RESPONSE,
90*63afb9a5SDavid du Colombier 	SSH_AGENT_FAILURE,
91*63afb9a5SDavid du Colombier 	SSH_AGENT_SUCCESS,
92*63afb9a5SDavid du Colombier 	SSH_AGENTC_ADD_RSA_IDENTITY,
93*63afb9a5SDavid du Colombier 	SSH_AGENTC_REMOVE_RSA_IDENTITY,
94*63afb9a5SDavid du Colombier };
95*63afb9a5SDavid du Colombier 
96*63afb9a5SDavid du Colombier enum		/* protocol constants */
97*63afb9a5SDavid du Colombier {
98*63afb9a5SDavid du Colombier 	SSH_MAX_DATA = 256*1024,
99*63afb9a5SDavid du Colombier 	SSH_MAX_MSG = SSH_MAX_DATA+4,
100*63afb9a5SDavid du Colombier 
101*63afb9a5SDavid du Colombier 	SESSKEYLEN = 32,
102*63afb9a5SDavid du Colombier 	SESSIDLEN = 16,
103*63afb9a5SDavid du Colombier 
104*63afb9a5SDavid du Colombier 	COOKIELEN = 8,
105*63afb9a5SDavid du Colombier };
106*63afb9a5SDavid du Colombier 
107*63afb9a5SDavid du Colombier enum		/* crypto ids */
108*63afb9a5SDavid du Colombier {
109*63afb9a5SDavid du Colombier 	SSH_CIPHER_NONE = 0,
110*63afb9a5SDavid du Colombier 	SSH_CIPHER_IDEA,
111*63afb9a5SDavid du Colombier 	SSH_CIPHER_DES,
112*63afb9a5SDavid du Colombier 	SSH_CIPHER_3DES,
113*63afb9a5SDavid du Colombier 	SSH_CIPHER_TSS,
114*63afb9a5SDavid du Colombier 	SSH_CIPHER_RC4,
115*63afb9a5SDavid du Colombier 	SSH_CIPHER_BLOWFISH,
116*63afb9a5SDavid du Colombier 	SSH_CIPHER_TWIDDLE,		/* for debugging */
117*63afb9a5SDavid du Colombier };
118*63afb9a5SDavid du Colombier 
119*63afb9a5SDavid du Colombier enum		/* auth method ids */
120*63afb9a5SDavid du Colombier {
121*63afb9a5SDavid du Colombier 	SSH_AUTH_RHOSTS = 1,
122*63afb9a5SDavid du Colombier 	SSH_AUTH_RSA = 2,
123*63afb9a5SDavid du Colombier 	SSH_AUTH_PASSWORD = 3,
124*63afb9a5SDavid du Colombier 	SSH_AUTH_RHOSTS_RSA = 4,
125*63afb9a5SDavid du Colombier 	SSH_AUTH_TIS = 5,
126*63afb9a5SDavid du Colombier 	SSH_AUTH_USER_RSA = 6,
127*63afb9a5SDavid du Colombier };
128*63afb9a5SDavid du Colombier 
129*63afb9a5SDavid du Colombier typedef struct Auth Auth;
130*63afb9a5SDavid du Colombier typedef struct Authsrv Authsrv;
131*63afb9a5SDavid du Colombier typedef struct Cipher Cipher;
132*63afb9a5SDavid du Colombier typedef struct CipherState CipherState;
133*63afb9a5SDavid du Colombier typedef struct Conn Conn;
134*63afb9a5SDavid du Colombier typedef struct Msg Msg;
135*63afb9a5SDavid du Colombier 
136*63afb9a5SDavid du Colombier #pragma incomplete CipherState
137*63afb9a5SDavid du Colombier 
138*63afb9a5SDavid du Colombier struct Auth
139*63afb9a5SDavid du Colombier {
140*63afb9a5SDavid du Colombier 	int id;
141*63afb9a5SDavid du Colombier 	char *name;
142*63afb9a5SDavid du Colombier 	int (*fn)(Conn*);
143*63afb9a5SDavid du Colombier };
144*63afb9a5SDavid du Colombier 
145*63afb9a5SDavid du Colombier struct Authsrv
146*63afb9a5SDavid du Colombier {
147*63afb9a5SDavid du Colombier 	int id;
148*63afb9a5SDavid du Colombier 	char *name;
149*63afb9a5SDavid du Colombier 	int firstmsg;
150*63afb9a5SDavid du Colombier 	AuthInfo *(*fn)(Conn*, Msg*);
151*63afb9a5SDavid du Colombier };
152*63afb9a5SDavid du Colombier 
153*63afb9a5SDavid du Colombier struct Cipher
154*63afb9a5SDavid du Colombier {
155*63afb9a5SDavid du Colombier 	int id;
156*63afb9a5SDavid du Colombier 	char *name;
157*63afb9a5SDavid du Colombier 	CipherState *(*init)(Conn*, int isserver);
158*63afb9a5SDavid du Colombier 	void (*encrypt)(CipherState*, uchar*, int);
159*63afb9a5SDavid du Colombier 	void (*decrypt)(CipherState*, uchar*, int);
160*63afb9a5SDavid du Colombier };
161*63afb9a5SDavid du Colombier 
162*63afb9a5SDavid du Colombier struct Conn
163*63afb9a5SDavid du Colombier {
164*63afb9a5SDavid du Colombier 	QLock;
165*63afb9a5SDavid du Colombier 	int fd[2];
166*63afb9a5SDavid du Colombier 	CipherState *cstate;
167*63afb9a5SDavid du Colombier 	uchar cookie[COOKIELEN];
168*63afb9a5SDavid du Colombier 	uchar sessid[SESSIDLEN];
169*63afb9a5SDavid du Colombier 	uchar sesskey[SESSKEYLEN];
170*63afb9a5SDavid du Colombier 	RSApub *serverkey;
171*63afb9a5SDavid du Colombier 	RSApub *hostkey;
172*63afb9a5SDavid du Colombier 	ulong flags;
173*63afb9a5SDavid du Colombier 	ulong ciphermask;
174*63afb9a5SDavid du Colombier 	Cipher *cipher;		/* chosen cipher */
175*63afb9a5SDavid du Colombier 	Cipher **okcipher;	/* list of acceptable ciphers */
176*63afb9a5SDavid du Colombier 	int nokcipher;
177*63afb9a5SDavid du Colombier 	ulong authmask;
178*63afb9a5SDavid du Colombier 	Auth **okauth;
179*63afb9a5SDavid du Colombier 	int nokauth;
180*63afb9a5SDavid du Colombier 	char *user;
181*63afb9a5SDavid du Colombier 	char *host;
182*63afb9a5SDavid du Colombier 	char *aliases;
183*63afb9a5SDavid du Colombier 	int interactive;
184*63afb9a5SDavid du Colombier 	Msg *unget;
185*63afb9a5SDavid du Colombier 
186*63afb9a5SDavid du Colombier 	RSApriv *serverpriv;		/* server only */
187*63afb9a5SDavid du Colombier 	RSApriv *hostpriv;
188*63afb9a5SDavid du Colombier 	Authsrv **okauthsrv;
189*63afb9a5SDavid du Colombier 	int nokauthsrv;
190*63afb9a5SDavid du Colombier };
191*63afb9a5SDavid du Colombier 
192*63afb9a5SDavid du Colombier struct Msg
193*63afb9a5SDavid du Colombier {
194*63afb9a5SDavid du Colombier 	Conn *c;
195*63afb9a5SDavid du Colombier 	uchar type;
196*63afb9a5SDavid du Colombier 	ulong len;		/* output: #bytes before pos, input: #bytes after pos */
197*63afb9a5SDavid du Colombier 	uchar *bp;	/* beginning of allocated space */
198*63afb9a5SDavid du Colombier 	uchar *rp;		/* read pointer */
199*63afb9a5SDavid du Colombier 	uchar *wp;	/* write pointer */
200*63afb9a5SDavid du Colombier 	uchar *ep;	/* end of allocated space */
201*63afb9a5SDavid du Colombier 	Msg *link;		/* for sshnet */
202*63afb9a5SDavid du Colombier };
203*63afb9a5SDavid du Colombier 
204*63afb9a5SDavid du Colombier #define LONG(p)	(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|((p)[3]))
205*63afb9a5SDavid du Colombier #define PLONG(p, l) \
206*63afb9a5SDavid du Colombier 	(((p)[0]=(l)>>24),((p)[1]=(l)>>16),\
207*63afb9a5SDavid du Colombier 	 ((p)[2]=(l)>>8),((p)[3]=(l)))
208*63afb9a5SDavid du Colombier #define SHORT(p) (((p)[0]<<8)|(p)[1])
209*63afb9a5SDavid du Colombier #define PSHORT(p,l) \
210*63afb9a5SDavid du Colombier 	(((p)[0]=(l)>>8),((p)[1]=(l)))
211*63afb9a5SDavid du Colombier 
212*63afb9a5SDavid du Colombier extern char Edecode[];
213*63afb9a5SDavid du Colombier extern char Eencode[];
214*63afb9a5SDavid du Colombier extern char Ememory[];
215*63afb9a5SDavid du Colombier extern char Ehangup[];
216*63afb9a5SDavid du Colombier extern int doabort;
217*63afb9a5SDavid du Colombier extern int debuglevel;
218*63afb9a5SDavid du Colombier 
219*63afb9a5SDavid du Colombier extern Auth authpassword;
220*63afb9a5SDavid du Colombier extern Auth authrsa;
221*63afb9a5SDavid du Colombier extern Auth authtis;
222*63afb9a5SDavid du Colombier 
223*63afb9a5SDavid du Colombier extern Authsrv authsrvpassword;
224*63afb9a5SDavid du Colombier extern Authsrv authsrvtis;
225*63afb9a5SDavid du Colombier 
226*63afb9a5SDavid du Colombier extern Cipher cipher3des;
227*63afb9a5SDavid du Colombier extern Cipher cipherblowfish;
228*63afb9a5SDavid du Colombier extern Cipher cipherdes;
229*63afb9a5SDavid du Colombier extern Cipher cipherrc4;
230*63afb9a5SDavid du Colombier extern Cipher ciphernone;
231*63afb9a5SDavid du Colombier extern Cipher ciphertwiddle;
232*63afb9a5SDavid du Colombier 
233*63afb9a5SDavid du Colombier /* msg.c */
234*63afb9a5SDavid du Colombier Msg*	allocmsg(Conn*, int, int);
235*63afb9a5SDavid du Colombier void		badmsg(Msg*, int);
236*63afb9a5SDavid du Colombier Msg*	recvmsg(Conn*, int);
237*63afb9a5SDavid du Colombier void		unrecvmsg(Conn*, Msg*);
238*63afb9a5SDavid du Colombier int		sendmsg(Msg*);
239*63afb9a5SDavid du Colombier uchar	getbyte(Msg*);
240*63afb9a5SDavid du Colombier ushort	getshort(Msg*);
241*63afb9a5SDavid du Colombier ulong	getlong(Msg*);
242*63afb9a5SDavid du Colombier char*	getstring(Msg*);
243*63afb9a5SDavid du Colombier void*	getbytes(Msg*, int);
244*63afb9a5SDavid du Colombier mpint*	getmpint(Msg*);
245*63afb9a5SDavid du Colombier RSApub*	getRSApub(Msg*);
246*63afb9a5SDavid du Colombier void		putbyte(Msg*, uchar);
247*63afb9a5SDavid du Colombier void		putshort(Msg*, ushort);
248*63afb9a5SDavid du Colombier void		putlong(Msg*, ulong);
249*63afb9a5SDavid du Colombier void		putstring(Msg*, char*);
250*63afb9a5SDavid du Colombier void		putbytes(Msg*, void*, long);
251*63afb9a5SDavid du Colombier void		putmpint(Msg*, mpint*);
252*63afb9a5SDavid du Colombier void		putRSApub(Msg*, RSApub*);
253*63afb9a5SDavid du Colombier mpint*	rsapad(mpint*, int);
254*63afb9a5SDavid du Colombier mpint*	rsaunpad(mpint*);
255*63afb9a5SDavid du Colombier void		mptoberjust(mpint*, uchar*, int);
256*63afb9a5SDavid du Colombier mpint*	rsaencryptbuf(RSApub*, uchar*, int);
257*63afb9a5SDavid du Colombier 
258*63afb9a5SDavid du Colombier /* cmsg.c */
259*63afb9a5SDavid du Colombier void		sshclienthandshake(Conn*);
260*63afb9a5SDavid du Colombier void		requestpty(Conn*);
261*63afb9a5SDavid du Colombier int		readgeom(int*, int*, int*, int*);
262*63afb9a5SDavid du Colombier void		sendwindowsize(Conn*, int, int, int, int);
263*63afb9a5SDavid du Colombier int		rawhack;
264*63afb9a5SDavid du Colombier 
265*63afb9a5SDavid du Colombier /* smsg.c */
266*63afb9a5SDavid du Colombier void		sshserverhandshake(Conn*);
267*63afb9a5SDavid du Colombier 
268*63afb9a5SDavid du Colombier /* pubkey.c */
269*63afb9a5SDavid du Colombier enum
270*63afb9a5SDavid du Colombier {
271*63afb9a5SDavid du Colombier 	KeyOk,
272*63afb9a5SDavid du Colombier 	KeyWrong,
273*63afb9a5SDavid du Colombier 	NoKey,
274*63afb9a5SDavid du Colombier 	NoKeyFile,
275*63afb9a5SDavid du Colombier };
276*63afb9a5SDavid du Colombier int		appendkey(char*, char*, RSApub*);
277*63afb9a5SDavid du Colombier int		findkey(char*, char*, RSApub*);
278*63afb9a5SDavid du Colombier int		replacekey(char*, char*, RSApub*);
279*63afb9a5SDavid du Colombier 
280*63afb9a5SDavid du Colombier /* agent.c */
281*63afb9a5SDavid du Colombier int		startagent(Conn*);
282*63afb9a5SDavid du Colombier void		handleagentmsg(Msg*);
283*63afb9a5SDavid du Colombier void		handleagentopen(Msg*);
284*63afb9a5SDavid du Colombier void		handleagentieof(Msg*);
285*63afb9a5SDavid du Colombier void		handleagentoclose(Msg*);
286*63afb9a5SDavid du Colombier 
287*63afb9a5SDavid du Colombier /* util.c */
288*63afb9a5SDavid du Colombier void		debug(int, char*, ...);
289*63afb9a5SDavid du Colombier void*	emalloc(long);
290*63afb9a5SDavid du Colombier void*	erealloc(void*, long);
291*63afb9a5SDavid du Colombier void		error(char*, ...);
292*63afb9a5SDavid du Colombier RSApriv*	readsecretkey(char*);
293*63afb9a5SDavid du Colombier int		readstrnl(int, char*, int);
294*63afb9a5SDavid du Colombier void		atexitkill(int);
295*63afb9a5SDavid du Colombier void		atexitkiller(void);
296*63afb9a5SDavid du Colombier void		calcsessid(Conn*);
297*63afb9a5SDavid du Colombier void		sshlog(char*, ...);
298*63afb9a5SDavid du Colombier void		setaliases(Conn*, char*);
299*63afb9a5SDavid du Colombier void		privatefactotum(void);
300*63afb9a5SDavid du Colombier 
301*63afb9a5SDavid du Colombier #pragma varargck argpos debug 2
302*63afb9a5SDavid du Colombier #pragma varargck argpos error 1
303*63afb9a5SDavid du Colombier #pragma varargck argpos sshlog 2
304