#include <u.h>
#include <libc.h>
#include <mp.h>
#include <auth.h>
#include <libsec.h>
enum /* internal debugging flags */
{
DBG= 1<<0,
DBG_CRYPTO= 1<<1,
DBG_PACKET= 1<<2,
DBG_AUTH= 1<<3,
DBG_PROC= 1<<4,
DBG_PROTO= 1<<5,
DBG_IO= 1<<6,
DBG_SCP= 1<<7,
};
enum /* protocol packet types */
{
/* 0 */
SSH_MSG_NONE=0,
SSH_MSG_DISCONNECT,
SSH_SMSG_PUBLIC_KEY,
SSH_CMSG_SESSION_KEY,
SSH_CMSG_USER,
SSH_CMSG_AUTH_RHOSTS,
SSH_CMSG_AUTH_RSA,
SSH_SMSG_AUTH_RSA_CHALLENGE,
SSH_CMSG_AUTH_RSA_RESPONSE,
SSH_CMSG_AUTH_PASSWORD,
/* 10 */
SSH_CMSG_REQUEST_PTY,
SSH_CMSG_WINDOW_SIZE,
SSH_CMSG_EXEC_SHELL,
SSH_CMSG_EXEC_CMD,
SSH_SMSG_SUCCESS,
SSH_SMSG_FAILURE,
SSH_CMSG_STDIN_DATA,
SSH_SMSG_STDOUT_DATA,
SSH_SMSG_STDERR_DATA,
SSH_CMSG_EOF,
/* 20 */
SSH_SMSG_EXITSTATUS,
SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
SSH_MSG_CHANNEL_OPEN_FAILURE,
SSH_MSG_CHANNEL_DATA,
SSH_MSG_CHANNEL_INPUT_EOF,
SSH_MSG_CHANNEL_OUTPUT_CLOSED,
SSH_MSG_UNIX_DOMAIN_X11_FORWARDING, /* obsolete */
SSH_SMSG_X11_OPEN,
SSH_CMSG_PORT_FORWARD_REQUEST,
SSH_MSG_PORT_OPEN,
/* 30 */
SSH_CMSG_AGENT_REQUEST_FORWARDING,
SSH_SMSG_AGENT_OPEN,
SSH_MSG_IGNORE,
SSH_CMSG_EXIT_CONFIRMATION,
SSH_CMSG_X11_REQUEST_FORWARDING,
SSH_CMSG_AUTH_RHOSTS_RSA,
SSH_MSG_DEBUG,
SSH_CMSG_REQUEST_COMPRESSION,
SSH_CMSG_MAX_PACKET_SIZE,
SSH_CMSG_AUTH_TIS,
/* 40 */
SSH_SMSG_AUTH_TIS_CHALLENGE,
SSH_CMSG_AUTH_TIS_RESPONSE,
SSH_CMSG_AUTH_KERBEROS,
SSH_SMSG_AUTH_KERBEROS_RESPONSE,
SSH_CMSG_HAVE_KERBEROS_TGT,
};
enum /* protocol flags */
{
SSH_PROTOFLAG_SCREEN_NUMBER=1<<0,
SSH_PROTOFLAG_HOST_IN_FWD_OPEN=1<<1,
};
enum /* agent protocol packet types */
{
SSH_AGENTC_NONE = 0,
SSH_AGENTC_REQUEST_RSA_IDENTITIES,
SSH_AGENT_RSA_IDENTITIES_ANSWER,
SSH_AGENTC_RSA_CHALLENGE,
SSH_AGENT_RSA_RESPONSE,
SSH_AGENT_FAILURE,
SSH_AGENT_SUCCESS,
SSH_AGENTC_ADD_RSA_IDENTITY,
SSH_AGENTC_REMOVE_RSA_IDENTITY,
};
enum /* protocol constants */
{
SSH_MAX_DATA = 256*1024,
SSH_MAX_MSG = SSH_MAX_DATA+4,
SESSKEYLEN = 32,
SESSIDLEN = 16,
COOKIELEN = 8,
};
enum /* crypto ids */
{
SSH_CIPHER_NONE = 0,
SSH_CIPHER_IDEA,
SSH_CIPHER_DES,
SSH_CIPHER_3DES,
SSH_CIPHER_TSS,
SSH_CIPHER_RC4,
SSH_CIPHER_BLOWFISH,
SSH_CIPHER_TWIDDLE, /* for debugging */
};
enum /* auth method ids */
{
SSH_AUTH_RHOSTS = 1,
SSH_AUTH_RSA = 2,
SSH_AUTH_PASSWORD = 3,
SSH_AUTH_RHOSTS_RSA = 4,
SSH_AUTH_TIS = 5,
SSH_AUTH_USER_RSA = 6,
};
typedef struct Auth Auth;
typedef struct Authsrv Authsrv;
typedef struct Cipher Cipher;
typedef struct CipherState CipherState;
typedef struct Conn Conn;
typedef struct Msg Msg;
#pragma incomplete CipherState
struct Auth
{
int id;
char *name;
int (*fn)(Conn*);
};
struct Authsrv
{
int id;
char *name;
int firstmsg;
AuthInfo *(*fn)(Conn*, Msg*);
};
struct Cipher
{
int id;
char *name;
CipherState *(*init)(Conn*, int isserver);
void (*encrypt)(CipherState*, uchar*, int);
void (*decrypt)(CipherState*, uchar*, int);
};
struct Conn
{
QLock;
int fd[2];
CipherState *cstate;
uchar cookie[COOKIELEN];
uchar sessid[SESSIDLEN];
uchar sesskey[SESSKEYLEN];
RSApub *serverkey;
RSApub *hostkey;
ulong flags;
ulong ciphermask;
Cipher *cipher; /* chosen cipher */
Cipher **okcipher; /* list of acceptable ciphers */
int nokcipher;
ulong authmask;
Auth **okauth;
int nokauth;
char *user;
char *host;
char *aliases;
int interactive;
Msg *unget;
RSApriv *serverpriv; /* server only */
RSApriv *hostpriv;
Authsrv **okauthsrv;
int nokauthsrv;
};
struct Msg
{
Conn *c;
uchar type;
ulong len; /* output: #bytes before pos, input: #bytes after pos */
uchar *bp; /* beginning of allocated space */
uchar *rp; /* read pointer */
uchar *wp; /* write pointer */
uchar *ep; /* end of allocated space */
Msg *link; /* for sshnet */
};
#define LONG(p) (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|((p)[3]))
#define PLONG(p, l) \
(((p)[0]=(l)>>24),((p)[1]=(l)>>16),\
((p)[2]=(l)>>8),((p)[3]=(l)))
#define SHORT(p) (((p)[0]<<8)|(p)[1])
#define PSHORT(p,l) \
(((p)[0]=(l)>>8),((p)[1]=(l)))
extern char Edecode[];
extern char Eencode[];
extern char Ememory[];
extern char Ehangup[];
extern int doabort;
extern int debuglevel;
extern Auth authpassword;
extern Auth authrsa;
extern Auth authtis;
extern Authsrv authsrvpassword;
extern Authsrv authsrvtis;
extern Cipher cipher3des;
extern Cipher cipherblowfish;
extern Cipher cipherdes;
extern Cipher cipherrc4;
extern Cipher ciphernone;
extern Cipher ciphertwiddle;
/* msg.c */
Msg* allocmsg(Conn*, int, int);
void badmsg(Msg*, int);
Msg* recvmsg(Conn*, int);
void unrecvmsg(Conn*, Msg*);
int sendmsg(Msg*);
uchar getbyte(Msg*);
ushort getshort(Msg*);
ulong getlong(Msg*);
char* getstring(Msg*);
void* getbytes(Msg*, int);
mpint* getmpint(Msg*);
RSApub* getRSApub(Msg*);
void putbyte(Msg*, uchar);
void putshort(Msg*, ushort);
void putlong(Msg*, ulong);
void putstring(Msg*, char*);
void putbytes(Msg*, void*, long);
void putmpint(Msg*, mpint*);
void putRSApub(Msg*, RSApub*);
mpint* rsapad(mpint*, int);
mpint* rsaunpad(mpint*);
void mptoberjust(mpint*, uchar*, int);
mpint* rsaencryptbuf(RSApub*, uchar*, int);
/* cmsg.c */
void sshclienthandshake(Conn*);
void requestpty(Conn*);
int readgeom(int*, int*, int*, int*);
void sendwindowsize(Conn*, int, int, int, int);
int rawhack;
/* smsg.c */
void sshserverhandshake(Conn*);
/* pubkey.c */
enum
{
KeyOk,
KeyWrong,
NoKey,
NoKeyFile,
};
int appendkey(char*, char*, RSApub*);
int findkey(char*, char*, RSApub*);
int replacekey(char*, char*, RSApub*);
/* agent.c */
int startagent(Conn*);
void handleagentmsg(Msg*);
void handleagentopen(Msg*);
void handleagentieof(Msg*);
void handleagentoclose(Msg*);
/* util.c */
void debug(int, char*, ...);
void* emalloc(long);
void* erealloc(void*, long);
void error(char*, ...);
RSApriv* readsecretkey(char*);
int readstrnl(int, char*, int);
void atexitkill(int);
void atexitkiller(void);
void calcsessid(Conn*);
void sshlog(char*, ...);
void setaliases(Conn*, char*);
void privatefactotum(void);
#pragma varargck argpos debug 2
#pragma varargck argpos error 1
#pragma varargck argpos sshlog 2
|