Plan 9 from Bell Labs’s /usr/web/sources/contrib/blstuart/ssh/sshtun.h

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <bio.h>
#define MYID "SSH-2.0-Plan9"

#pragma varargck type "M" mpint*

enum {
	CONNSHIFT = 7,
	MAXCONN = 1 << CONNSHIFT,
	LEVSHIFT = 2 * CONNSHIFT + 3,

	RootFile = 0,
	CloneFile = 1 << (2 * CONNSHIFT),
	CtlFile = 2 << (2 * CONNSHIFT),
	DataFile = 3 << (2 * CONNSHIFT),
	ListenFile = 4 << (2 * CONNSHIFT),
	LocalFile = 5 << (2 * CONNSHIFT),
	ReqRemFile = 6 << (2 * CONNSHIFT),
	StatusFile = 7 << (2* CONNSHIFT),
	FileMask = 7 << (2 * CONNSHIFT),
	ConnMask = (1 << CONNSHIFT) - 1,

	Server = 0,
	Client,
};

/*
 * The stylistic anomaly with these names of unbounded length
 * is a result of following the RFCs in using the same names for
 * these constants.  I did that to make it easier to search and
 * cross-reference between the code and the RFCs.
 */
enum		/* SSH2 Protocol Packet Types */
{
	SSH_MSG_DISCONNECT = 1,
	SSH_MSG_IGNORE = 2,
	SSH_MSG_UNIMPLEMENTED,
	SSH_MSG_DEBUG,
	SSH_MSG_SERVICE_REQUEST,
	SSH_MSG_SERVICE_ACCEPT,

	SSH_MSG_KEXINIT = 20,
	SSH_MSG_NEWKEYS,

	SSH_MSG_KEXDH_INIT = 30,
	SSH_MSG_KEXDH_REPLY,

	SSH_MSG_USERAUTH_REQUEST = 50,
	SSH_MSG_USERAUTH_FAILURE,
	SSH_MSG_USERAUTH_SUCCESS,
	SSH_MSG_USERAUTH_BANNER,

	SSH_MSG_USERAUTH_PK_OK = 60,
	SSH_MSG_USERAUTH_PASSWD_CHANGEREQ = 60,

	SSH_MSG_GLOBAL_REQUEST = 80,
	SSH_MSG_REQUEST_SUCCESS,
	SSH_MSG_REQUEST_FAILURE,

	SSH_MSG_CHANNEL_OPEN = 90,
	SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
	SSH_MSG_CHANNEL_OPEN_FAILURE,
	SSH_MSG_CHANNEL_WINDOW_ADJUST,
	SSH_MSG_CHANNEL_DATA,
	SSH_MSG_CHANNEL_EXTENDED_DATA,
	SSH_MSG_CHANNEL_EOF,
	SSH_MSG_CHANNEL_CLOSE,
	SSH_MSG_CHANNEL_REQUEST,
	SSH_MSG_CHANNEL_SUCCESS,
	SSH_MSG_CHANNEL_FAILURE,
};

enum		/* SSH2 reason codes */
{
	SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1,
	SSH_DISCONNECT_PROTOCOL_ERROR,
	SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
	SSH_DISCONNECT_RESERVED,
	SSH_DISCONNECT_MAC_ERROR,
	SSH_DISCONNECT_COMPRESSION_ERROR,
	SSH_DISCONNECT_SERVICE_NOT_AVAILABLE,
	SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
	SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
	SSH_DISCONNECT_CONNECTION_LOST,
	SSH_DISCONNECT_BY_APPLICATION,
	SSH_DISCONNECT_TOO_MANY_CONNECTIONS,
	SSH_DISCONNECT_AUTH_CANCELLED_BY_USER,
	SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE,
	SSH_DISCONNECT_ILLEGAL_USR_NAME,

	SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1,
	SSH_OPEN_CONNECT_FAILED,
	SSH_OPEN_UNKNOWN_CHANNEL_TYPE,
	SSH_OPEN_RESOURCE_SHORTAGE,
};

enum		/* SSH2 type code */
{
	SSH_EXTENDED_DATA_STDERR = 1,
};

enum		/* connection and channel states */
{
	Empty = 0,
	Allocated,
	Initting,
	Listening,
	Opening,
	Negotiating,
	Authing,
	Established,
	Eof,
	Closing,
	Closed,
};

enum {
	NoKeyFile,
	NoKey,
	KeyWrong,
	KeyOk,
};

typedef struct Plist Plist;
typedef struct SSHChan SSHChan;
typedef struct Conn Conn;
typedef struct Packet Packet;
typedef struct Cipher Cipher;
typedef struct CipherState CipherState;
typedef struct Kex Kex;
typedef struct PKA PKA;
typedef struct MBox MBox;

#pragma incomplete CipherState

struct Plist {
	Packet *pack;
	uchar *st;
	int rem;
	Plist *next;
};

struct SSHChan {
	Rendez r;
	int id, otherid, state;
	int waker;
	int conn;
	ulong rwindow, twindow;
	ulong sent, inrqueue;
	char *ann;
	Req *lreq;
	File *dir, *ctl, *data, *listen, *request, *status;
	Plist *dataq, *datatl, *reqq, *reqtl;
	Channel *inchan, *reqchan;
	QLock xmtlock;
	Rendez xmtrendez;
};

struct Conn {
	QLock l;
	Rendez r;
	Ioproc *dio, *cio, *rio;
	int state;
	int role;
	int id;
	char *remote;
	char *user, *password, *service;
	char *cap;
	char *authkey;
	int nchan;
	int datafd, ctlfd;
	int rpid;
	int inseq, outseq;
	int kexalg, pkalg;
	int cscrypt, ncscrypt, sccrypt, nsccrypt, csmac, ncsmac, scmac, nscmac;
	int encrypt, decrypt, outmac, inmac;
	File *dir, *clonefile, *ctlfile, *datafile, *listenfile, *localfile, *remotefile, *statusfile;
	Packet *skexinit, *rkexinit;
	mpint *x, *e;
	int got_sessid;
	uchar sessid[SHA1dlen];
	uchar c2siv[SHA1dlen*2], nc2siv[SHA1dlen*2], s2civ[SHA1dlen*2], ns2civ[SHA1dlen*2];
	uchar c2sek[SHA1dlen*2], nc2sek[SHA1dlen*2], s2cek[SHA1dlen*2], ns2cek[SHA1dlen*2];
	uchar c2sik[SHA1dlen*2], nc2sik[SHA1dlen*2], s2cik[SHA1dlen*2], ns2cik[SHA1dlen*2];
	char *otherid;
	uchar *inik, *outik;
	CipherState *s2ccs, *c2scs;
	CipherState *enccs, *deccs;
	SSHChan *chans[MAXCONN];
};

struct Packet {
	Conn *c;
	ulong rlength, tlength;
	uchar nlength[4];
	uchar pad_len;
	uchar payload[35000];
};

struct Cipher
{
	char *name;
	int blklen;
	CipherState *(*init)(Conn*, int);
	void (*encrypt)(CipherState*, uchar*, int);
	void (*decrypt)(CipherState*, uchar*, int);
};

struct Kex
{
	char *name;
	int (*serverkex)(Conn *, Packet *);
	int (*clientkex1)(Conn *, Packet *);
	int (*clientkex2)(Conn *, Packet *);
};

struct PKA
{
	char *name;
	Packet *(*ks)(Conn *);
	Packet *(*sign)(Conn *, uchar *, int);
	int (*verify)(Conn *, uchar *, int, char *, char *, int);
};

struct MBox
{
	Channel *mchan;
	char *msg;
	int state;
};

extern int debug;
extern Cipher cipherblowfish, cipher3des, cipherrc4;
extern Cipher cipheraes128, cipheraes192, cipheraes256;
extern Kex dh1sha1, dh14sha1;
extern PKA rsa_pka, dss_pka, *pkas[];
extern sshkeychan[];
extern MBox keymbox;

/* pubkey.c */
RSApub *readpublickey(Biobuf *, char **);
int findkey(char *, char *, RSApub *);
int replacekey(char *, char *, RSApub *);
int appendkey(char *, char *, RSApub *);

/* dh.c */
void dh_init(PKA *[]);

/* transport.c */
Packet 	*new_packet(Conn *);
void		init_packet(Packet *);
void		add_byte(Packet *, char);
void		add_uint32(Packet *, ulong);
ulong	get_uint32(Packet *, uchar **);
int		add_packet(Packet *, void *, int);
void		add_block(Packet *, void *, int);
void		add_string(Packet *, char *);
uchar	*get_string(Packet *, uchar *, char *, int, int *);
void		add_mp(Packet *, mpint *);
mpint	*get_mp(uchar *q);
int		finish_packet(Packet *);
int		undo_packet(Packet *);
void		dump_packet(Packet *);

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.