Mercurial > dropbear
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 } |