comparison svr-runopts.c @ 795:7f604f9b3756 ecc

ecdsa is working
author Matt Johnston <matt@ucc.asn.au>
date Fri, 03 May 2013 23:07:48 +0800
parents af4ef98b8591
children 4029d3432a4f
comparison
equal deleted inserted replaced
794:d386defb5376 795:7f604f9b3756
26 #include "runopts.h" 26 #include "runopts.h"
27 #include "signkey.h" 27 #include "signkey.h"
28 #include "buffer.h" 28 #include "buffer.h"
29 #include "dbutil.h" 29 #include "dbutil.h"
30 #include "algo.h" 30 #include "algo.h"
31 #include "ecdsa.h"
31 32
32 svr_runopts svr_opts; /* GLOBAL */ 33 svr_runopts svr_opts; /* GLOBAL */
33 34
34 static void printhelp(const char * progname); 35 static void printhelp(const char * progname);
35 static void addportandaddress(char* spec); 36 static void addportandaddress(char* spec);
37 static void loadhostkey(const char *keyfile, int fatal_duplicate);
38 static void addhostkey(const char *keyfile);
36 39
37 static void printhelp(const char * progname) { 40 static void printhelp(const char * progname) {
38 41
39 fprintf(stderr, "Dropbear server v%s https://matt.ucc.asn.au/dropbear/dropbear.html\n" 42 fprintf(stderr, "Dropbear server v%s https://matt.ucc.asn.au/dropbear/dropbear.html\n"
40 "Usage: %s [options]\n" 43 "Usage: %s [options]\n"
103 char ** next = 0; 106 char ** next = 0;
104 int nextisport = 0; 107 int nextisport = 0;
105 char* recv_window_arg = NULL; 108 char* recv_window_arg = NULL;
106 char* keepalive_arg = NULL; 109 char* keepalive_arg = NULL;
107 char* idle_timeout_arg = NULL; 110 char* idle_timeout_arg = NULL;
111 char* keyfile = NULL;
112
108 113
109 /* see printhelp() for options */ 114 /* see printhelp() for options */
110 svr_opts.rsakeyfile = NULL;
111 svr_opts.dsskeyfile = NULL;
112 svr_opts.bannerfile = NULL; 115 svr_opts.bannerfile = NULL;
113 svr_opts.banner = NULL; 116 svr_opts.banner = NULL;
114 svr_opts.forkbg = 1; 117 svr_opts.forkbg = 1;
115 svr_opts.norootlogin = 0; 118 svr_opts.norootlogin = 0;
116 svr_opts.noauthpass = 0; 119 svr_opts.noauthpass = 0;
158 *next = argv[i]; 161 *next = argv[i];
159 if (*next == NULL) { 162 if (*next == NULL) {
160 dropbear_exit("Invalid null argument"); 163 dropbear_exit("Invalid null argument");
161 } 164 }
162 next = 0x00; 165 next = 0x00;
166
167 if (keyfile) {
168 addhostkey(keyfile);
169 keyfile = NULL;
170 }
163 continue; 171 continue;
164 } 172 }
165 173
166 if (argv[i][0] == '-') { 174 if (argv[i][0] == '-') {
167 switch (argv[i][1]) { 175 switch (argv[i][1]) {
168 case 'b': 176 case 'b':
169 next = &svr_opts.bannerfile; 177 next = &svr_opts.bannerfile;
170 break; 178 break;
171 #ifdef DROPBEAR_DSS
172 case 'd': 179 case 'd':
173 next = &svr_opts.dsskeyfile;
174 break;
175 #endif
176 #ifdef DROPBEAR_RSA
177 case 'r': 180 case 'r':
178 next = &svr_opts.rsakeyfile; 181 next = &keyfile;
179 break; 182 break;
180 #endif
181 case 'F': 183 case 'F':
182 svr_opts.forkbg = 0; 184 svr_opts.forkbg = 0;
183 break; 185 break;
184 #ifndef DISABLE_SYSLOG 186 #ifndef DISABLE_SYSLOG
185 case 'E': 187 case 'E':
265 svr_opts.ports[0] = m_strdup(DROPBEAR_DEFPORT); 267 svr_opts.ports[0] = m_strdup(DROPBEAR_DEFPORT);
266 svr_opts.addresses[0] = m_strdup(DROPBEAR_DEFADDRESS); 268 svr_opts.addresses[0] = m_strdup(DROPBEAR_DEFADDRESS);
267 svr_opts.portcount = 1; 269 svr_opts.portcount = 1;
268 } 270 }
269 271
270 if (svr_opts.dsskeyfile == NULL) {
271 svr_opts.dsskeyfile = DSS_PRIV_FILENAME;
272 }
273 if (svr_opts.rsakeyfile == NULL) {
274 svr_opts.rsakeyfile = RSA_PRIV_FILENAME;
275 }
276
277 if (svr_opts.bannerfile) { 272 if (svr_opts.bannerfile) {
278 struct stat buf; 273 struct stat buf;
279 if (stat(svr_opts.bannerfile, &buf) != 0) { 274 if (stat(svr_opts.bannerfile, &buf) != 0) {
280 dropbear_exit("Error opening banner file '%s'", 275 dropbear_exit("Error opening banner file '%s'",
281 svr_opts.bannerfile); 276 svr_opts.bannerfile);
290 if (buf_readfile(svr_opts.banner, svr_opts.bannerfile)!=DROPBEAR_SUCCESS) { 285 if (buf_readfile(svr_opts.banner, svr_opts.bannerfile)!=DROPBEAR_SUCCESS) {
291 dropbear_exit("Error reading banner file '%s'", 286 dropbear_exit("Error reading banner file '%s'",
292 svr_opts.bannerfile); 287 svr_opts.bannerfile);
293 } 288 }
294 buf_setpos(svr_opts.banner, 0); 289 buf_setpos(svr_opts.banner, 0);
295
296 } 290 }
297 291
298 if (recv_window_arg) { 292 if (recv_window_arg) {
299 opts.recv_window = atol(recv_window_arg); 293 opts.recv_window = atol(recv_window_arg);
300 if (opts.recv_window == 0 || opts.recv_window > MAX_RECV_WINDOW) { 294 if (opts.recv_window == 0 || opts.recv_window > MAX_RECV_WINDOW) {
368 362
369 svr_opts.portcount++; 363 svr_opts.portcount++;
370 } 364 }
371 } 365 }
372 366
373 static void disablekey(int type, const char* filename) { 367 static void disablekey(int type) {
374
375 int i; 368 int i;
376
377 for (i = 0; sshhostkey[i].name != NULL; i++) { 369 for (i = 0; sshhostkey[i].name != NULL; i++) {
378 if (sshhostkey[i].val == type) { 370 if (sshhostkey[i].val == type) {
379 sshhostkey[i].usable = 0; 371 sshhostkey[i].usable = 1;
380 break; 372 break;
381 } 373 }
382 } 374 }
383 dropbear_log(LOG_WARNING, "Failed reading '%s', disabling %s", filename,
384 type == DROPBEAR_SIGNKEY_DSS ? "DSS" : "RSA");
385 } 375 }
386 376
387 /* Must be called after syslog/etc is working */ 377 /* Must be called after syslog/etc is working */
388 void loadhostkeys() { 378 static void loadhostkey(const char *keyfile, int fatal_duplicate) {
389 379 sign_key * read_key = new_sign_key();
390 int ret; 380 int type = DROPBEAR_SIGNKEY_ANY;
391 int type; 381 if (readhostkey(keyfile, read_key, &type) == DROPBEAR_FAILURE) {
392 382 dropbear_log(LOG_WARNING, "Failed loading %s", keyfile);
393 TRACE(("enter loadhostkeys")) 383 }
384
385 #ifdef DROPBEAR_RSA
386 if (type == DROPBEAR_SIGNKEY_RSA) {
387 if (svr_opts.hostkey->rsakey) {
388 if (fatal_duplicate) {
389 dropbear_exit("Only one RSA key can be specified");
390 }
391 } else {
392 svr_opts.hostkey->rsakey = read_key->rsakey;
393 read_key->rsakey = NULL;
394 }
395 }
396 #endif
397
398 #ifdef DROPBEAR_DSS
399 if (type == DROPBEAR_SIGNKEY_DSS) {
400 if (svr_opts.hostkey->dsskey) {
401 if (fatal_duplicate) {
402 dropbear_exit("Only one DSS key can be specified");
403 }
404 } else {
405 svr_opts.hostkey->dsskey = read_key->dsskey;
406 read_key->dsskey = NULL;
407 }
408 }
409 #endif
410
411 #ifdef DROPBEAR_ECDSA
412 if (IS_ECDSA_KEY(type)) {
413 if (svr_opts.hostkey->ecckey) {
414 if (fatal_duplicate) {
415 dropbear_exit("Only one ECDSA key can be specified");
416 }
417 } else {
418 svr_opts.hostkey->ecckey = read_key->ecckey;
419 read_key->ecckey = NULL;
420 }
421 }
422 #endif
423 sign_key_free(read_key);
424 TRACE(("leave loadhostkey"))
425 }
426
427 static void addhostkey(const char *keyfile) {
428 if (svr_opts.num_hostkey_files >= MAX_HOSTKEYS) {
429 dropbear_exit("Too many hostkeys");
430 }
431 svr_opts.hostkey_files[svr_opts.num_hostkey_files] = m_strdup(keyfile);
432 svr_opts.num_hostkey_files++;
433 }
434
435 void load_all_hostkeys() {
436 int i;
394 437
395 svr_opts.hostkey = new_sign_key(); 438 svr_opts.hostkey = new_sign_key();
396 439
440 for (i = 0; i < svr_opts.num_hostkey_files; i++) {
441 char *hostkey_file = svr_opts.hostkey_files[i];
442 loadhostkey(hostkey_file, 1);
443 m_free(hostkey_file);
444 }
445
397 #ifdef DROPBEAR_RSA 446 #ifdef DROPBEAR_RSA
398 type = DROPBEAR_SIGNKEY_RSA; 447 loadhostkey(RSA_PRIV_FILENAME, 0);
399 ret = readhostkey(svr_opts.rsakeyfile, svr_opts.hostkey, &type); 448 #endif
400 if (ret == DROPBEAR_FAILURE) { 449
401 disablekey(DROPBEAR_SIGNKEY_RSA, svr_opts.rsakeyfile);
402 }
403 #endif
404 #ifdef DROPBEAR_DSS 450 #ifdef DROPBEAR_DSS
405 type = DROPBEAR_SIGNKEY_DSS; 451 loadhostkey(DSS_PRIV_FILENAME, 0);
406 ret = readhostkey(svr_opts.dsskeyfile, svr_opts.hostkey, &type); 452 #endif
407 if (ret == DROPBEAR_FAILURE) { 453
408 disablekey(DROPBEAR_SIGNKEY_DSS, svr_opts.dsskeyfile); 454 #ifdef DROPBEAR_ECDSA
409 } 455 loadhostkey(ECDSA_PRIV_FILENAME, 0);
410 #endif 456 #endif
411 457
412 if ( 1 458 #ifdef DROPBEAR_RSA
459 if (!svr_opts.hostkey->rsakey) {
460 disablekey(DROPBEAR_SIGNKEY_RSA);
461 }
462 #endif
413 #ifdef DROPBEAR_DSS 463 #ifdef DROPBEAR_DSS
414 && svr_opts.hostkey->dsskey == NULL 464 if (!svr_opts.hostkey->dsskey) {
415 #endif 465 disablekey(DROPBEAR_SIGNKEY_RSA);
416 #ifdef DROPBEAR_RSA 466 }
417 && svr_opts.hostkey->rsakey == NULL 467 #endif
418 #endif 468 #ifdef DROPBEAR_ECDSA
419 ) { 469 #ifdef DROPBEAR_ECC_256
420 dropbear_exit("No hostkeys available"); 470 if (!svr_opts.hostkey->ecckey
421 } 471 || ecdsa_signkey_type(svr_opts.hostkey->ecckey) != DROPBEAR_SIGNKEY_ECDSA_NISTP256) {
422 472 disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP256);
423 TRACE(("leave loadhostkeys")) 473 }
424 } 474 #endif
475 #ifdef DROPBEAR_ECC_384
476 if (!svr_opts.hostkey->ecckey
477 || ecdsa_signkey_type(svr_opts.hostkey->ecckey) != DROPBEAR_SIGNKEY_ECDSA_NISTP384) {
478 disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP384);
479 }
480 #endif
481 #ifdef DROPBEAR_ECC_521
482 if (!svr_opts.hostkey->ecckey
483 || ecdsa_signkey_type(svr_opts.hostkey->ecckey) != DROPBEAR_SIGNKEY_ECDSA_NISTP521) {
484 disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP521);
485 }
486 #endif
487 #endif
488 }