#include #include #include extern const char *__progname; #include "cmdline.h" const char *host = 0; const char *port = 0; const char *remuser = 0; int showoffer = 0; ALGLIST *algs_kex = 0; ALGLIST *algs_hk = 0; ALGLIST *algs_enc_c2s = 0; ALGLIST *algs_enc_s2c = 0; ALGLIST *algs_mac_c2s = 0; ALGLIST *algs_mac_s2c = 0; ALGLIST *algs_comp_c2s = 0; ALGLIST *algs_comp_s2c = 0; const char *lang_c2s = 0; const char *lang_s2c = 0; static char *local_user_name(void) { char *s; s = getenv("USER"); if (s == 0) { fprintf(stderr,"%s: no $USER and no remote username specified\n",__progname); exit(1); } return(strdup(s)); } static int algset(ALGLIST **listp, void *(*find)(const char *), const char *name, const char *what) { void *alg; ALGLIST *l; ALGLIST **lp; alg = (*find)(name); if (alg == 0) { if (what) fprintf(stderr,"%s: %s: unknown %s algorithm name\n",__progname,name,what); return(1); } for (lp=listp;(l=*lp);) { if (l->alg == alg) { *lp = l->link; l->link = *listp; *listp = l; return(0); } } l = malloc(sizeof(ALGLIST)); l->alg = alg; l->link = *listp; *listp = l; return(0); } /* XXX does not belong here */ static void enc_test(void) { void *r_state; void *w_state; ENCALG *a; unsigned char blk1[8]; unsigned char blk2[8]; unsigned char blk3[8]; static void saveblk(void *to, const void *data, int len) { bcopy(data,to,len); } static void readblk(void *from, void *data, int len) { bcopy(from,data,len); } a = encalg_vfind_c("blowfish-cbc"); r_state = encalg_init(a, "\xb5\xbc\x3a\x62\x34\x20\x58\x45\xfe\xbe\xd4\x39\x27\x49\xef\x43", "\1\1\1\1\1\1\1\1",'r'); w_state = encalg_init(a, "\xb5\xbc\x3a\x62\x34\x20\x58\x45\xfe\xbe\xd4\x39\x27\x49\xef\x43", "\1\1\1\1\1\1\1\1",'w'); bcopy("tertiary",&blk1[0],8); bzero(&blk2[0],8); bzero(&blk3[0],8); printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", blk1[0], blk1[1], blk1[2], blk1[3], blk1[4], blk1[5], blk1[6], blk1[7] ); fflush(0); encalg_w(a,w_state,saveblk,&blk2[0],&blk1[0],8); printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", blk2[0], blk2[1], blk2[2], blk2[3], blk2[4], blk2[5], blk2[6], blk2[7] ); fflush(0); encalg_r(a,r_state,readblk,&blk2[0],&blk3[0],8); printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", blk3[0], blk3[1], blk3[2], blk3[3], blk3[4], blk3[5], blk3[6], blk3[7] ); exit(0); } static ALGLIST *default_algs(void *(*enumfn)(int)) { ALGLIST *l; ALGLIST **lp; ALGLIST *a; int i; void *alg; lp = &l; for (i=0;(alg=(*enumfn)(i));i++) { a = malloc(sizeof(ALGLIST)); a->alg = alg; *lp = a; lp = &a->link; } *lp =0; return(l); } void handleargs(int ac, char **av) { int skip; int errs; skip = 0; errs = 0; for (ac--,av++;ac;ac--,av++) { if (skip > 0) { skip --; continue; } if (**av != '-') { if (! host) { host = *av; } else { fprintf(stderr,"%s: extra argument `%s'\n",__progname,*av); errs ++; } continue; } if (0) { needarg:; fprintf(stderr,"%s: %s needs a following argument\n",__progname,*av); errs ++; continue; } #define WANTARG() do { if (++skip >= ac) goto needarg; } while (0) if (!strcmp(*av,"-host")) { WANTARG(); if (host) fprintf(stderr,"%s: %s %s: warning: host already specified, using later value\n",__progname,av[0],av[skip]); host = av[skip]; continue; } if (!strcmp(*av,"-port")) { WANTARG(); if (port) fprintf(stderr,"%s: %s %s: warning: port already specified, using later value\n",__progname,av[0],av[skip]); port = av[skip]; continue; } if (!strcmp(*av,"-kex")) { WANTARG(); errs += algset(&algs_kex,&kexalg_vfind_c,av[skip],"key exchange"); continue; } if (!strcmp(*av,"-hk")) { WANTARG(); errs += algset(&algs_hk,&hkalg_vfind_c,av[skip],"host key verification"); continue; } if (!strcmp(*av,"-enc")) { WANTARG(); errs += algset(&algs_enc_c2s,&encalg_vfind_c,av[skip],"encryption"); errs += algset(&algs_enc_s2c,&encalg_vfind_c,av[skip],0); continue; } if (!strcmp(*av,"-enc-c2s")) { WANTARG(); errs += algset(&algs_enc_c2s,&encalg_vfind_c,av[skip],"encryption"); continue; } if (!strcmp(*av,"-enc-s2c")) { WANTARG(); errs += algset(&algs_enc_s2c,&encalg_vfind_c,av[skip],"encryption"); continue; } if (!strcmp(*av,"-mac")) { WANTARG(); errs += algset(&algs_mac_c2s,&macalg_vfind_c,av[skip],"MAC"); errs += algset(&algs_mac_s2c,&macalg_vfind_c,av[skip],0); continue; } if (!strcmp(*av,"-mac-c2s")) { WANTARG(); errs += algset(&algs_mac_c2s,&macalg_vfind_c,av[skip],"MAC"); continue; } if (!strcmp(*av,"-mac-s2c")) { WANTARG(); errs += algset(&algs_mac_s2c,&macalg_vfind_c,av[skip],"MAC"); continue; } if (!strcmp(*av,"-comp")) { WANTARG(); errs += algset(&algs_comp_c2s,&compalg_vfind_c,av[skip],"compression"); errs += algset(&algs_comp_s2c,&compalg_vfind_c,av[skip],0); continue; } if (!strcmp(*av,"-comp-c2s")) { WANTARG(); errs += algset(&algs_comp_c2s,&compalg_vfind_c,av[skip],"compression"); continue; } if (!strcmp(*av,"-comp-s2c")) { WANTARG(); errs += algset(&algs_comp_s2c,&compalg_vfind_c,av[skip],"compression"); continue; } if (!strcmp(*av,"-lang-c2s")) { WANTARG(); if (lang_c2s) fprintf(stderr,"%s: %s %s: warning: c2s language already specified, using later value\n",__progname,av[0],av[skip]); lang_c2s = av[skip]; continue; } if (!strcmp(*av,"-lang-s2c")) { WANTARG(); if (lang_s2c) fprintf(stderr,"%s: %s %s: warning: s2c language already specified, using later value\n",__progname,av[0],av[skip]); lang_s2c = av[skip]; continue; } if (!strcmp(*av,"-l") || !strcmp(*av,"-remuser")) { WANTARG(); if (remuser) fprintf(stderr,"%s: %s %s: warning: remote user already specified, using later value\n",__progname,av[0],av[skip]); remuser = av[skip]; continue; } if (!strcmp(*av,"-showoffer")) { showoffer = 1; continue; } if (!strcmp(*av,"-enctest")) { enc_test(); exit(0); } #undef WANTARG fprintf(stderr,"%s: unrecognized option `%s'\n",__progname,*av); errs ++; } if (errs) exit(1); if (! algs_kex) algs_kex = default_algs(kexalg_enum); if (! algs_hk) algs_hk = default_algs(hkalg_enum); if (! algs_enc_c2s) algs_enc_c2s = default_algs(encalg_enum); if (! algs_enc_s2c) algs_enc_s2c = default_algs(encalg_enum); if (! algs_mac_c2s) algs_mac_c2s = default_algs(macalg_enum); if (! algs_mac_s2c) algs_mac_s2c = default_algs(macalg_enum); if (! algs_comp_c2s) algs_comp_c2s = default_algs(compalg_enum); if (! algs_comp_s2c) algs_comp_s2c = default_algs(compalg_enum); if (! remuser) remuser = local_user_name(); }