#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_CLOSE, SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, 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 /* 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; 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{ 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; 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);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); /* 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*); /* util.c */void debug(int, char*, ...);void* emalloc(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 error 1#pragma varargck argpos sshlog 2
#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_CLOSE,
SSH_MSG_CHANNEL_CLOSE_CONFIRMATION,
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 /* 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;
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
{
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;
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);
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);
/* 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*);
/* util.c */
void debug(int, char*, ...);
void* emalloc(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 error 1
#pragma varargck argpos sshlog 2