1 /* apps/srp.c */ 2 /* Written by Peter Sylvester (peter.sylvester@edelweb.fr) 3 * for the EdelKey project and contributed to the OpenSSL project 2004. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2004 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 #include <openssl/opensslconf.h> 59 60 #ifndef OPENSSL_NO_SRP 61 #include <stdio.h> 62 #include <stdlib.h> 63 #include <string.h> 64 #include <openssl/conf.h> 65 #include <openssl/bio.h> 66 #include <openssl/err.h> 67 #include <openssl/txt_db.h> 68 #include <openssl/buffer.h> 69 #include <openssl/srp.h> 70 71 #include "apps.h" 72 73 #undef PROG 74 #define PROG srp_main 75 76 #define BASE_SECTION "srp" 77 #define CONFIG_FILE "openssl.cnf" 78 79 #define ENV_RANDFILE "RANDFILE" 80 81 #define ENV_DATABASE "srpvfile" 82 #define ENV_DEFAULT_SRP "default_srp" 83 84 static char *srp_usage[]={ 85 "usage: srp [args] [user] \n", 86 "\n", 87 " -verbose Talk alot while doing things\n", 88 " -config file A config file\n", 89 " -name arg The particular srp definition to use\n", 90 " -srpvfile arg The srp verifier file name\n", 91 " -add add an user and srp verifier\n", 92 " -modify modify the srp verifier of an existing user\n", 93 " -delete delete user from verifier file\n", 94 " -list list user\n", 95 " -gn arg g and N values to be used for new verifier\n", 96 " -userinfo arg additional info to be set for user\n", 97 " -passin arg input file pass phrase source\n", 98 " -passout arg output file pass phrase source\n", 99 #ifndef OPENSSL_NO_ENGINE 100 " -engine e - use engine e, possibly a hardware device.\n", 101 #endif 102 NULL 103 }; 104 105 #ifdef EFENCE 106 extern int EF_PROTECT_FREE; 107 extern int EF_PROTECT_BELOW; 108 extern int EF_ALIGNMENT; 109 #endif 110 111 static CONF *conf=NULL; 112 static char *section=NULL; 113 114 #define VERBOSE if (verbose) 115 #define VVERBOSE if (verbose>1) 116 117 118 int MAIN(int, char **); 119 120 static int get_index(CA_DB *db, char* id, char type) 121 { 122 char ** pp; 123 int i; 124 if (id == NULL) return -1; 125 if (type == DB_SRP_INDEX) 126 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) 127 { 128 pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i); 129 if (pp[DB_srptype][0] == DB_SRP_INDEX && !strcmp(id, pp[DB_srpid])) 130 return i; 131 } 132 else for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) 133 { 134 pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i); 135 136 if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid])) 137 return i; 138 } 139 140 return -1 ; 141 } 142 143 static void print_entry(CA_DB *db, BIO *bio, int indx, int verbose, char *s) 144 { 145 if (indx >= 0 && verbose) 146 { 147 int j; 148 char **pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, indx); 149 BIO_printf(bio, "%s \"%s\"\n", s, pp[DB_srpid]); 150 for (j = 0; j < DB_NUMBER; j++) 151 { 152 BIO_printf(bio_err," %d = \"%s\"\n", j, pp[j]); 153 } 154 } 155 } 156 157 static void print_index(CA_DB *db, BIO *bio, int indexindex, int verbose) 158 { 159 print_entry(db, bio, indexindex, verbose, "g N entry") ; 160 } 161 162 static void print_user(CA_DB *db, BIO *bio, int userindex, int verbose) 163 { 164 if (verbose > 0) 165 { 166 char **pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex); 167 168 if (pp[DB_srptype][0] != 'I') 169 { 170 print_entry(db, bio, userindex, verbose, "User entry"); 171 print_entry(db, bio, get_index(db, pp[DB_srpgN], 'I'), verbose, "g N entry"); 172 } 173 174 } 175 } 176 177 static int update_index(CA_DB *db, BIO *bio, char **row) 178 { 179 char ** irow; 180 int i; 181 182 if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) 183 { 184 BIO_printf(bio_err,"Memory allocation failure\n"); 185 return 0; 186 } 187 188 for (i=0; i<DB_NUMBER; i++) 189 { 190 irow[i]=row[i]; 191 row[i]=NULL; 192 } 193 irow[DB_NUMBER]=NULL; 194 195 if (!TXT_DB_insert(db->db,irow)) 196 { 197 BIO_printf(bio,"failed to update srpvfile\n"); 198 BIO_printf(bio,"TXT_DB error number %ld\n",db->db->error); 199 OPENSSL_free(irow); 200 return 0; 201 } 202 return 1; 203 } 204 205 static void lookup_fail(const char *name, char *tag) 206 { 207 BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag); 208 } 209 210 211 static char *srp_verify_user(const char *user, const char *srp_verifier, 212 char *srp_usersalt, const char *g, const char *N, 213 const char *passin, BIO *bio, int verbose) 214 { 215 char password[1024]; 216 PW_CB_DATA cb_tmp; 217 char *verifier = NULL; 218 char *gNid = NULL; 219 220 cb_tmp.prompt_info = user; 221 cb_tmp.password = passin; 222 223 if (password_callback(password, 1024, 0, &cb_tmp) >0) 224 { 225 VERBOSE BIO_printf(bio,"Validating\n user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,srp_verifier,srp_usersalt, g, N); 226 BIO_printf(bio, "Pass %s\n", password); 227 228 if (!(gNid=SRP_create_verifier(user, password, &srp_usersalt, &verifier, N, g))) 229 { 230 BIO_printf(bio, "Internal error validating SRP verifier\n"); 231 } 232 else 233 { 234 if (strcmp(verifier, srp_verifier)) 235 gNid = NULL; 236 OPENSSL_free(verifier); 237 } 238 } 239 return gNid; 240 } 241 242 static char *srp_create_user(char *user, char **srp_verifier, 243 char **srp_usersalt, char *g, char *N, 244 char *passout, BIO *bio, int verbose) 245 { 246 char password[1024]; 247 PW_CB_DATA cb_tmp; 248 char *gNid = NULL; 249 char *salt = NULL; 250 cb_tmp.prompt_info = user; 251 cb_tmp.password = passout; 252 253 if (password_callback(password,1024,1,&cb_tmp) >0) 254 { 255 VERBOSE BIO_printf(bio,"Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,g,N); 256 if (!(gNid =SRP_create_verifier(user, password, &salt, srp_verifier, N, g))) 257 { 258 BIO_printf(bio,"Internal error creating SRP verifier\n"); 259 } 260 else 261 *srp_usersalt = salt; 262 VVERBOSE BIO_printf(bio,"gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,salt, *srp_verifier); 263 264 } 265 return gNid; 266 } 267 268 int MAIN(int argc, char **argv) 269 { 270 #ifndef OPENSSL_NO_ENGINE 271 ENGINE *e = NULL; 272 #endif 273 int add_user = 0; 274 int list_user= 0; 275 int delete_user= 0; 276 int modify_user= 0; 277 char * user = NULL; 278 279 char *passargin = NULL, *passargout = NULL; 280 char *passin = NULL, *passout = NULL; 281 char * gN = NULL; 282 int gNindex = -1; 283 char ** gNrow = NULL; 284 int maxgN = -1; 285 286 char * userinfo = NULL; 287 288 int badops=0; 289 int ret=1; 290 int errors=0; 291 int verbose=0; 292 int doupdatedb=0; 293 char *configfile=NULL; 294 char *dbfile=NULL; 295 CA_DB *db=NULL; 296 char **pp ; 297 int i; 298 long errorline = -1; 299 char *randfile=NULL; 300 #ifndef OPENSSL_NO_ENGINE 301 char *engine = NULL; 302 #endif 303 char *tofree=NULL; 304 DB_ATTR db_attr; 305 306 #ifdef EFENCE 307 EF_PROTECT_FREE=1; 308 EF_PROTECT_BELOW=1; 309 EF_ALIGNMENT=0; 310 #endif 311 312 apps_startup(); 313 314 conf = NULL; 315 section = NULL; 316 317 if (bio_err == NULL) 318 if ((bio_err=BIO_new(BIO_s_file())) != NULL) 319 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); 320 321 argc--; 322 argv++; 323 while (argc >= 1 && badops == 0) 324 { 325 if (strcmp(*argv,"-verbose") == 0) 326 verbose++; 327 else if (strcmp(*argv,"-config") == 0) 328 { 329 if (--argc < 1) goto bad; 330 configfile= *(++argv); 331 } 332 else if (strcmp(*argv,"-name") == 0) 333 { 334 if (--argc < 1) goto bad; 335 section= *(++argv); 336 } 337 else if (strcmp(*argv,"-srpvfile") == 0) 338 { 339 if (--argc < 1) goto bad; 340 dbfile= *(++argv); 341 } 342 else if (strcmp(*argv,"-add") == 0) 343 add_user=1; 344 else if (strcmp(*argv,"-delete") == 0) 345 delete_user=1; 346 else if (strcmp(*argv,"-modify") == 0) 347 modify_user=1; 348 else if (strcmp(*argv,"-list") == 0) 349 list_user=1; 350 else if (strcmp(*argv,"-gn") == 0) 351 { 352 if (--argc < 1) goto bad; 353 gN= *(++argv); 354 } 355 else if (strcmp(*argv,"-userinfo") == 0) 356 { 357 if (--argc < 1) goto bad; 358 userinfo= *(++argv); 359 } 360 else if (strcmp(*argv,"-passin") == 0) 361 { 362 if (--argc < 1) goto bad; 363 passargin= *(++argv); 364 } 365 else if (strcmp(*argv,"-passout") == 0) 366 { 367 if (--argc < 1) goto bad; 368 passargout= *(++argv); 369 } 370 #ifndef OPENSSL_NO_ENGINE 371 else if (strcmp(*argv,"-engine") == 0) 372 { 373 if (--argc < 1) goto bad; 374 engine= *(++argv); 375 } 376 #endif 377 378 else if (**argv == '-') 379 { 380 bad: 381 BIO_printf(bio_err,"unknown option %s\n",*argv); 382 badops=1; 383 break; 384 } 385 else 386 break; 387 388 argc--; 389 argv++; 390 } 391 392 if (dbfile && configfile) 393 { 394 BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n"); 395 badops = 1; 396 } 397 if (add_user+delete_user+modify_user+list_user != 1) 398 { 399 BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n"); 400 badops = 1; 401 } 402 if (delete_user+modify_user+delete_user== 1 && argc <= 0) 403 { 404 BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n"); 405 badops = 1; 406 } 407 if ((passin || passout) && argc != 1 ) 408 { 409 BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n"); 410 badops = 1; 411 } 412 413 if (badops) 414 { 415 for (pp=srp_usage; (*pp != NULL); pp++) 416 BIO_printf(bio_err,"%s",*pp); 417 418 BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 419 BIO_printf(bio_err," load the file (or the files in the directory) into\n"); 420 BIO_printf(bio_err," the random number generator\n"); 421 goto err; 422 } 423 424 ERR_load_crypto_strings(); 425 426 #ifndef OPENSSL_NO_ENGINE 427 e = setup_engine(bio_err, engine, 0); 428 #endif 429 430 if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) 431 { 432 BIO_printf(bio_err, "Error getting passwords\n"); 433 goto err; 434 } 435 436 if (!dbfile) 437 { 438 439 440 /*****************************************************************/ 441 tofree=NULL; 442 if (configfile == NULL) configfile = getenv("OPENSSL_CONF"); 443 if (configfile == NULL) configfile = getenv("SSLEAY_CONF"); 444 if (configfile == NULL) 445 { 446 const char *s=X509_get_default_cert_area(); 447 size_t len; 448 449 #ifdef OPENSSL_SYS_VMS 450 len = strlen(s)+sizeof(CONFIG_FILE); 451 tofree=OPENSSL_malloc(len); 452 strcpy(tofree,s); 453 #else 454 len = strlen(s)+sizeof(CONFIG_FILE)+1; 455 tofree=OPENSSL_malloc(len); 456 BUF_strlcpy(tofree,s,len); 457 BUF_strlcat(tofree,"/",len); 458 #endif 459 BUF_strlcat(tofree,CONFIG_FILE,len); 460 configfile=tofree; 461 } 462 463 VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile); 464 conf = NCONF_new(NULL); 465 if (NCONF_load(conf,configfile,&errorline) <= 0) 466 { 467 if (errorline <= 0) 468 BIO_printf(bio_err,"error loading the config file '%s'\n", 469 configfile); 470 else 471 BIO_printf(bio_err,"error on line %ld of config file '%s'\n" 472 ,errorline,configfile); 473 goto err; 474 } 475 if(tofree) 476 { 477 OPENSSL_free(tofree); 478 tofree = NULL; 479 } 480 481 if (!load_config(bio_err, conf)) 482 goto err; 483 484 /* Lets get the config section we are using */ 485 if (section == NULL) 486 { 487 VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n"); 488 489 section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP); 490 if (section == NULL) 491 { 492 lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP); 493 goto err; 494 } 495 } 496 497 if (randfile == NULL && conf) 498 randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); 499 500 501 VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section); 502 503 if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL) 504 { 505 lookup_fail(section,ENV_DATABASE); 506 goto err; 507 } 508 509 } 510 if (randfile == NULL) 511 ERR_clear_error(); 512 else 513 app_RAND_load_file(randfile, bio_err, 0); 514 515 VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile); 516 517 db = load_index(dbfile, &db_attr); 518 if (db == NULL) goto err; 519 520 /* Lets check some fields */ 521 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) 522 { 523 pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i); 524 525 if (pp[DB_srptype][0] == DB_SRP_INDEX) 526 { 527 maxgN = i; 528 if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid])) 529 gNindex = i; 530 531 print_index(db, bio_err, i, verbose > 1); 532 } 533 } 534 535 VERBOSE BIO_printf(bio_err, "Database initialised\n"); 536 537 if (gNindex >= 0) 538 { 539 gNrow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, gNindex); 540 print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N") ; 541 } 542 else if (maxgN > 0 && !SRP_get_default_gN(gN)) 543 { 544 BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN); 545 goto err; 546 } 547 else 548 { 549 VERBOSE BIO_printf(bio_err, "Database has no g N information.\n"); 550 gNrow = NULL; 551 } 552 553 554 VVERBOSE BIO_printf(bio_err,"Starting user processing\n"); 555 556 if (argc > 0) 557 user = *(argv++) ; 558 559 while (list_user || user) 560 { 561 int userindex = -1; 562 if (user) 563 VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user); 564 if ((userindex = get_index(db, user, 'U')) >= 0) 565 { 566 print_user(db, bio_err, userindex, (verbose > 0) || list_user); 567 } 568 569 if (list_user) 570 { 571 if (user == NULL) 572 { 573 BIO_printf(bio_err,"List all users\n"); 574 575 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) 576 { 577 print_user(db,bio_err, i, 1); 578 } 579 list_user = 0; 580 } 581 else if (userindex < 0) 582 { 583 BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n", 584 user); 585 errors++; 586 } 587 } 588 else if (add_user) 589 { 590 if (userindex >= 0) 591 { 592 /* reactivation of a new user */ 593 char **row = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex); 594 BIO_printf(bio_err, "user \"%s\" reactivated.\n", user); 595 row[DB_srptype][0] = 'V'; 596 597 doupdatedb = 1; 598 } 599 else 600 { 601 char *row[DB_NUMBER] ; char *gNid; 602 row[DB_srpverifier] = NULL; 603 row[DB_srpsalt] = NULL; 604 row[DB_srpinfo] = NULL; 605 if (!(gNid = srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:gN,gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose))) 606 { 607 BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned .\n", user); 608 errors++; 609 goto err; 610 } 611 row[DB_srpid] = BUF_strdup(user); 612 row[DB_srptype] = BUF_strdup("v"); 613 row[DB_srpgN] = BUF_strdup(gNid); 614 615 if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] || 616 (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) || 617 !update_index(db, bio_err, row)) 618 { 619 if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]); 620 if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]); 621 if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]); 622 if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]); 623 if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]); 624 if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]); 625 goto err; 626 } 627 doupdatedb = 1; 628 } 629 } 630 else if (modify_user) 631 { 632 if (userindex < 0) 633 { 634 BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user); 635 errors++; 636 } 637 else 638 { 639 640 char **row = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex); 641 char type = row[DB_srptype][0]; 642 if (type == 'v') 643 { 644 BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user); 645 errors++; 646 } 647 else 648 { 649 char *gNid; 650 651 if (row[DB_srptype][0] == 'V') 652 { 653 int user_gN; 654 char **irow = NULL; 655 VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user); 656 if ( (user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0) 657 irow = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex); 658 659 if (!srp_verify_user(user, row[DB_srpverifier], row[DB_srpsalt], irow ? irow[DB_srpsalt] : row[DB_srpgN], irow ? irow[DB_srpverifier] : NULL, passin, bio_err, verbose)) 660 { 661 BIO_printf(bio_err, "Invalid password for user \"%s\", operation abandoned.\n", user); 662 errors++; 663 goto err; 664 } 665 } 666 VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user); 667 668 if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose))) 669 { 670 BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user); 671 errors++; 672 goto err; 673 } 674 675 row[DB_srptype][0] = 'v'; 676 row[DB_srpgN] = BUF_strdup(gNid); 677 678 if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] || 679 (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo))))) 680 goto err; 681 682 doupdatedb = 1; 683 } 684 } 685 } 686 else if (delete_user) 687 { 688 if (userindex < 0) 689 { 690 BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user); 691 errors++; 692 } 693 else 694 { 695 char **xpp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, userindex); 696 BIO_printf(bio_err, "user \"%s\" revoked. t\n", user); 697 698 xpp[DB_srptype][0] = 'R'; 699 700 doupdatedb = 1; 701 } 702 } 703 if (--argc > 0) 704 user = *(argv++) ; 705 else 706 { 707 user = NULL; 708 list_user = 0; 709 } 710 } 711 712 VERBOSE BIO_printf(bio_err,"User procession done.\n"); 713 714 715 if (doupdatedb) 716 { 717 /* Lets check some fields */ 718 for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) 719 { 720 pp = (char **)sk_OPENSSL_PSTRING_value(db->db->data, i); 721 722 if (pp[DB_srptype][0] == 'v') 723 { 724 pp[DB_srptype][0] = 'V'; 725 print_user(db, bio_err, i, verbose); 726 } 727 } 728 729 VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n"); 730 if (!save_index(dbfile, "new", db)) goto err; 731 732 VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n"); 733 if (!rotate_index(dbfile, "new", "old")) goto err; 734 735 VERBOSE BIO_printf(bio_err, "srpvfile updated.\n"); 736 } 737 738 ret = (errors != 0); 739 err: 740 if (errors != 0) 741 VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors); 742 743 VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret); 744 if(tofree) 745 OPENSSL_free(tofree); 746 if (ret) ERR_print_errors(bio_err); 747 if (randfile) app_RAND_write_file(randfile, bio_err); 748 if (conf) NCONF_free(conf); 749 if (db) free_index(db); 750 751 OBJ_cleanup(); 752 apps_shutdown(); 753 OPENSSL_EXIT(ret); 754 } 755 756 757 758 #endif 759 760