diff options
Diffstat (limited to 'src/otputil.c')
| -rw-r--r-- | src/otputil.c | 140 |
1 files changed, 114 insertions, 26 deletions
diff --git a/src/otputil.c b/src/otputil.c index 6c32b50..9524b63 100644 --- a/src/otputil.c +++ b/src/otputil.c | |||
| @@ -116,7 +116,7 @@ otputil_widget_lookup( | |||
| 116 | //--------------------------// | 116 | //--------------------------// |
| 117 | #pragma mark widgets prototypes | 117 | #pragma mark widgets prototypes |
| 118 | 118 | ||
| 119 | static int | 119 | extern int |
| 120 | otputil_widget_debug( | 120 | otputil_widget_debug( |
| 121 | otputil_config_t * cnf ); | 121 | otputil_config_t * cnf ); |
| 122 | 122 | ||
| @@ -146,7 +146,7 @@ static otputil_widget_t otputil_widget_map[] = | |||
| 146 | { .name = "debug", | 146 | { .name = "debug", |
| 147 | .desc = NULL, | 147 | .desc = NULL, |
| 148 | .usage = NULL, | 148 | .usage = NULL, |
| 149 | .short_opt = "0123456789abc:d:efghijk:lm:nopqrst:uvwx:yzABCDEFGHIJKLMNOPQRST:UVWXYZ", | 149 | .short_opt = "0123456789abc:d:efghijk:lm:nopqrs:t:uvwx:yzABCDEFGHIJKLMNOP:QRST:UVWXYZ", |
| 150 | .arg_min = 0, | 150 | .arg_min = 0, |
| 151 | .arg_max = 4096, | 151 | .arg_max = 4096, |
| 152 | .aliases = NULL, | 152 | .aliases = NULL, |
| @@ -165,17 +165,67 @@ static otputil_widget_t otputil_widget_map[] = | |||
| 165 | { .name = "hotp", | 165 | { .name = "hotp", |
| 166 | .desc = "hotp tools (RFC 4226)", | 166 | .desc = "hotp tools (RFC 4226)", |
| 167 | .usage = " [ code ]", | 167 | .usage = " [ code ]", |
| 168 | .short_opt = (TOTP_SHORT_OPT "c:d:k:m:p"), | 168 | .short_opt = (TOTP_SHORT_OPT "c:d:k:m:o"), |
| 169 | .arg_min = 0, | 169 | .arg_min = 0, |
| 170 | .arg_max = 1, | 170 | .arg_max = 1, |
| 171 | .aliases = NULL, | 171 | .aliases = NULL, |
| 172 | .func_exec = &otputil_widget_hotp, | 172 | .func_exec = &otputil_widget_hotp, |
| 173 | .func_usage = NULL, | 173 | .func_usage = NULL, |
| 174 | }, | 174 | }, |
| 175 | { .name = "otp", | ||
| 176 | .desc = "otp tools (RFC 2289)", | ||
| 177 | .usage = " [ sequence ] seed ]", | ||
| 178 | .short_opt = (TOTP_SHORT_OPT "c:m:oP:ps:"), | ||
| 179 | .arg_min = 0, | ||
| 180 | .arg_max = 2, | ||
| 181 | .aliases = NULL, | ||
| 182 | .func_exec = &otputil_widget_otp, | ||
| 183 | .func_usage = &otputil_widget_otp_usage, | ||
| 184 | }, | ||
| 185 | { .name = "otp-md4", | ||
| 186 | .desc = "otp alias for MD4", | ||
| 187 | .usage = " [ sequence ] seed ]", | ||
| 188 | .short_opt = (TOTP_SHORT_OPT "c:oP:ps:"), | ||
| 189 | .arg_min = 0, | ||
| 190 | .arg_max = 2, | ||
| 191 | .aliases = NULL, | ||
| 192 | .func_exec = &otputil_widget_otp_md4, | ||
| 193 | .func_usage = NULL, | ||
| 194 | }, | ||
| 195 | { .name = "otp-md5", | ||
| 196 | .desc = "otp alias for MD5", | ||
| 197 | .usage = " [ sequence ] seed ]", | ||
| 198 | .short_opt = (TOTP_SHORT_OPT "c:oP:ps:"), | ||
| 199 | .arg_min = 0, | ||
| 200 | .arg_max = 2, | ||
| 201 | .aliases = NULL, | ||
| 202 | .func_exec = &otputil_widget_otp_md5, | ||
| 203 | .func_usage = NULL, | ||
| 204 | }, | ||
| 205 | { .name = "otp-sha1", | ||
| 206 | .desc = "otp alias for SHA1", | ||
| 207 | .usage = " [ sequence ] seed ]", | ||
| 208 | .short_opt = (TOTP_SHORT_OPT "c:oP:ps:"), | ||
| 209 | .arg_min = 0, | ||
| 210 | .arg_max = 2, | ||
| 211 | .aliases = NULL, | ||
| 212 | .func_exec = &otputil_widget_otp_sha1, | ||
| 213 | .func_usage = NULL, | ||
| 214 | }, | ||
| 215 | { .name = "skey", | ||
| 216 | .desc = "s/key tools (RFC 1760)", | ||
| 217 | .usage = " [ sequence ]", | ||
| 218 | .short_opt = (TOTP_SHORT_OPT "c:m:oP:p"), | ||
| 219 | .arg_min = 0, | ||
| 220 | .arg_max = 1, | ||
| 221 | .aliases = NULL, | ||
| 222 | .func_exec = &otputil_widget_skey, | ||
| 223 | .func_usage = &otputil_widget_skey_usage, | ||
| 224 | }, | ||
| 175 | { .name = "totp", | 225 | { .name = "totp", |
| 176 | .desc = "totp tools (RFC 6238)", | 226 | .desc = "totp tools (RFC 6238)", |
| 177 | .usage = " [ code ]", | 227 | .usage = " [ code ]", |
| 178 | .short_opt = (TOTP_SHORT_OPT "d:k:m:pT:t:x:"), | 228 | .short_opt = (TOTP_SHORT_OPT "d:k:m:oT:t:x:"), |
| 179 | .arg_min = 0, | 229 | .arg_min = 0, |
| 180 | .arg_max = 1, | 230 | .arg_max = 1, |
| 181 | .aliases = NULL, | 231 | .aliases = NULL, |
| @@ -234,6 +284,7 @@ main( | |||
| 234 | cnf->prog_name = &cnf->prog_name[1]; | 284 | cnf->prog_name = &cnf->prog_name[1]; |
| 235 | if (!(cnf->prog_name)) | 285 | if (!(cnf->prog_name)) |
| 236 | cnf->prog_name = argv[0]; | 286 | cnf->prog_name = argv[0]; |
| 287 | otputil_set_param(NULL, OTPUTIL_OPT_DESC, cnf->prog_name); | ||
| 237 | 288 | ||
| 238 | 289 | ||
| 239 | // skip argument processing if called via alias | 290 | // skip argument processing if called via alias |
| @@ -288,6 +339,7 @@ otputil_arguments( | |||
| 288 | char * endptr; | 339 | char * endptr; |
| 289 | int rc; | 340 | int rc; |
| 290 | int i; | 341 | int i; |
| 342 | const char * str; | ||
| 291 | 343 | ||
| 292 | // getopt options | 344 | // getopt options |
| 293 | static const char * short_opt = "+" TOTP_SHORT_OPT; | 345 | static const char * short_opt = "+" TOTP_SHORT_OPT; |
| @@ -317,17 +369,16 @@ otputil_arguments( | |||
| 317 | 369 | ||
| 318 | case 'c': | 370 | case 'c': |
| 319 | uval = strtoull(optarg, &endptr, 0); | 371 | uval = strtoull(optarg, &endptr, 0); |
| 372 | i = (int)uval; | ||
| 320 | if ((optarg == endptr) || (endptr[0] != '\0')) | 373 | if ((optarg == endptr) || (endptr[0] != '\0')) |
| 321 | { | 374 | { |
| 322 | fprintf(stderr, "%s: invalid value for `-c'\n", PROGRAM_NAME); | 375 | fprintf(stderr, "%s: invalid value for `-c'\n", PROGRAM_NAME); |
| 323 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); | 376 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); |
| 324 | return(1); | 377 | return(1); |
| 325 | }; | 378 | }; |
| 326 | if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_HOTP_C, &uval)) != OTPUTIL_SUCCESS) | 379 | otputil_set_param(NULL, OTPUTIL_OPT_HOTP_C, &uval); |
| 327 | { | 380 | otputil_set_param(NULL, OTPUTIL_OPT_OTP_SEQ, &i); |
| 328 | fprintf(stderr, "%s: otputil_set_param(OTPUTIL_OPT_HOTP_C): %s\n", PROGRAM_NAME, otputil_err2string(rc)); | 381 | otputil_set_param(NULL, OTPUTIL_OPT_SKEY_SEQ, &i); |
| 329 | return(1); | ||
| 330 | }; | ||
| 331 | break; | 382 | break; |
| 332 | 383 | ||
| 333 | case 'd': | 384 | case 'd': |
| @@ -370,31 +421,29 @@ otputil_arguments( | |||
| 370 | break; | 421 | break; |
| 371 | 422 | ||
| 372 | case 'm': | 423 | case 'm': |
| 373 | if ((i = otputil_str2md(optarg)) == -1) | 424 | str = (!(strncasecmp("otp-", optarg, 4))) ? &optarg[4] : optarg; |
| 425 | if ((i = otputil_str2md(str)) == -1) | ||
| 374 | { | 426 | { |
| 375 | fprintf(stderr, "%s: message digest for `-m'\n", PROGRAM_NAME); | 427 | fprintf(stderr, "%s: %s: unknown message digest for `-m'\n", PROGRAM_NAME, str); |
| 376 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); | 428 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); |
| 377 | return(1); | 429 | return(1); |
| 378 | }; | 430 | }; |
| 379 | if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_HMAC, &i)) != OTPUTIL_SUCCESS) | 431 | otputil_set_param(NULL, OTPUTIL_OPT_HOTP_HMAC, &i); |
| 380 | { | 432 | otputil_set_param(NULL, OTPUTIL_OPT_OTP_HASH, &i); |
| 381 | fprintf(stderr, "%s: otputil_set_param(OTPUTIL_OPT_HMAC): %s\n", PROGRAM_NAME, otputil_err2string(rc)); | 433 | otputil_set_param(NULL, OTPUTIL_OPT_SKEY_HASH, &i); |
| 382 | return(1); | 434 | otputil_set_param(NULL, OTPUTIL_OPT_TOTP_HMAC, &i); |
| 383 | }; | ||
| 384 | break; | 435 | break; |
| 385 | 436 | ||
| 386 | case 's': | 437 | case 'o': |
| 387 | cnf->quiet = 1; | 438 | cnf->prompt_otp_pass = 1; |
| 388 | if ((cnf->verbose)) | 439 | break; |
| 389 | { | 440 | |
| 390 | fprintf(stderr, "%s: incompatible options\n", PROGRAM_NAME); | 441 | case 'P': |
| 391 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); | 442 | cnf->user_pass = optarg; |
| 392 | return(1); | ||
| 393 | }; | ||
| 394 | break; | 443 | break; |
| 395 | 444 | ||
| 396 | case 'p': | 445 | case 'p': |
| 397 | cnf->otp_pass = otputil_getpass("Enter OTP password or code: ", NULL, 0); | 446 | cnf->prompt_user_pass = 1; |
| 398 | break; | 447 | break; |
| 399 | 448 | ||
| 400 | case 'q': | 449 | case 'q': |
| @@ -407,6 +456,14 @@ otputil_arguments( | |||
| 407 | }; | 456 | }; |
| 408 | break; | 457 | break; |
| 409 | 458 | ||
| 459 | case 's': | ||
| 460 | if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_OTP_SEED, optarg)) != OTPUTIL_SUCCESS) | ||
| 461 | { | ||
| 462 | fprintf(stderr, "%s: otputil_set_param(OTPUTIL_OPT_OTP_SEED): %s\n", PROGRAM_NAME, otputil_err2string(rc)); | ||
| 463 | return(1); | ||
| 464 | }; | ||
| 465 | break; | ||
| 466 | |||
| 410 | case 'T': | 467 | case 'T': |
| 411 | uval = strtoull(optarg, &endptr, 0); | 468 | uval = strtoull(optarg, &endptr, 0); |
| 412 | if ((optarg == endptr) || (endptr[0] != '\0')) | 469 | if ((optarg == endptr) || (endptr[0] != '\0')) |
| @@ -493,6 +550,33 @@ otputil_arguments( | |||
| 493 | return(1); | 550 | return(1); |
| 494 | }; | 551 | }; |
| 495 | 552 | ||
| 553 | // process user password | ||
| 554 | if ( ((cnf->user_pass)) && ((cnf->prompt_user_pass)) ) | ||
| 555 | { | ||
| 556 | fprintf(stderr, "%s: incompatible options `-P' and `-p'\n", PROGRAM_NAME); | ||
| 557 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); | ||
| 558 | return(1); | ||
| 559 | }; | ||
| 560 | if ((cnf->prompt_user_pass)) | ||
| 561 | cnf->user_pass = otputil_getpass("Enter user's password: ", NULL, 0); | ||
| 562 | if ((cnf->user_pass)) | ||
| 563 | { | ||
| 564 | if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_SKEY_PASS, cnf->user_pass)) != OTPUTIL_SUCCESS) | ||
| 565 | { | ||
| 566 | fprintf(stderr, "%s: otputil_set_param(OTPUTIL_OPT_SKEY_PASS): %s\n", PROGRAM_NAME, otputil_err2string(rc)); | ||
| 567 | return(1); | ||
| 568 | }; | ||
| 569 | if ((rc = otputil_set_param(NULL, OTPUTIL_OPT_OTP_PASS, cnf->user_pass)) != OTPUTIL_SUCCESS) | ||
| 570 | { | ||
| 571 | fprintf(stderr, "%s: otputil_set_param(OTPUTIL_OPT_OTP_PASS): %s\n", PROGRAM_NAME, otputil_err2string(rc)); | ||
| 572 | return(1); | ||
| 573 | }; | ||
| 574 | }; | ||
| 575 | |||
| 576 | // process OTP password | ||
| 577 | if ((cnf->prompt_otp_pass)) | ||
| 578 | cnf->otp_pass = otputil_getpass("Enter OTP password or code: ", NULL, 0); | ||
| 579 | |||
| 496 | return(0); | 580 | return(0); |
| 497 | } | 581 | } |
| 498 | 582 | ||
| @@ -615,12 +699,16 @@ otputil_widget_usage( | |||
| 615 | printf(" %s-%s [OPTIONS]%s\n", PROGRAM_NAME, widget_name, widget_help); | 699 | printf(" %s-%s [OPTIONS]%s\n", PROGRAM_NAME, widget_name, widget_help); |
| 616 | printf(" %s%s [OPTIONS]%s\n", PROGRAM_NAME, widget_name, widget_help); | 700 | printf(" %s%s [OPTIONS]%s\n", PROGRAM_NAME, widget_name, widget_help); |
| 617 | printf("OPTIONS:\n"); | 701 | printf("OPTIONS:\n"); |
| 618 | if ((strchr(short_opt, 'c'))) printf(" -c num counter value\n"); | 702 | if ((strchr(short_opt, 'c'))) printf(" -c num counter/sequence value\n"); |
| 619 | if ((strchr(short_opt, 'd'))) printf(" -d num number of digits in code\n"); | 703 | if ((strchr(short_opt, 'd'))) printf(" -d num number of digits in code\n"); |
| 620 | if ((strchr(short_opt, 'k'))) printf(" -k string shared user key\n"); | 704 | if ((strchr(short_opt, 'k'))) printf(" -k string shared user key\n"); |
| 621 | if ((strchr(short_opt, 'h'))) printf(" -h, --help print this help and exit\n"); | 705 | if ((strchr(short_opt, 'h'))) printf(" -h, --help print this help and exit\n"); |
| 622 | if ((strchr(short_opt, 'm'))) printf(" -m hash use message digest hash\n"); | 706 | if ((strchr(short_opt, 'm'))) printf(" -m hash use message digest hash\n"); |
| 707 | if ((strchr(short_opt, 'o'))) printf(" -o prompt for OTP password/code to verify\n"); | ||
| 708 | if ((strchr(short_opt, 'P'))) printf(" -P str user password\n"); | ||
| 709 | if ((strchr(short_opt, 'p'))) printf(" -p prompt for user password\n"); | ||
| 623 | if ((strchr(short_opt, 'q'))) printf(" -q, --quiet, --silent do not print messages\n"); | 710 | if ((strchr(short_opt, 'q'))) printf(" -q, --quiet, --silent do not print messages\n"); |
| 711 | if ((strchr(short_opt, 's'))) printf(" -s seed OTP seed\n"); | ||
| 624 | if ((strchr(short_opt, 'T'))) printf(" -T seconds current Unix time\n"); | 712 | if ((strchr(short_opt, 'T'))) printf(" -T seconds current Unix time\n"); |
| 625 | if ((strchr(short_opt, 't'))) printf(" -t seconds Unix time start of time steps\n"); | 713 | if ((strchr(short_opt, 't'))) printf(" -t seconds Unix time start of time steps\n"); |
| 626 | if ((strchr(short_opt, 'V'))) printf(" -V, --version print version number and exit\n"); | 714 | if ((strchr(short_opt, 'V'))) printf(" -V, --version print version number and exit\n"); |
