int main(int argc, char *argv[]) { FUNCTION f, *fp; LHASH_OF(FUNCTION) *prog = NULL; char **copied_argv = NULL; char *p, *pname; char buf[1024]; const char *prompt; ARGS arg; int first, n, i, ret = 0; arg.argv = NULL; arg.size = 0; /* Set up some of the environment. */ default_config_file = make_config_name(); bio_in = dup_bio_in(FORMAT_TEXT); bio_out = dup_bio_out(FORMAT_TEXT); bio_err = dup_bio_err(FORMAT_TEXT); #if defined(OPENSSL_SYS_VMS) && defined(__DECC) copied_argv = argv = copy_argv(&argc, argv); #endif p = getenv("OPENSSL_DEBUG_MEMORY"); if (p != NULL && strcmp(p, "on") == 0) CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); if (getenv("OPENSSL_FIPS")) { #ifdef OPENSSL_FIPS if (!FIPS_mode_set(1)) { ERR_print_errors(bio_err); return 1; } #else BIO_printf(bio_err, "FIPS mode not supported.\n"); return 1; #endif } if (!apps_startup()) goto end; prog = prog_init(); pname = opt_progname(argv[0]); /* first check the program name */ f.name = pname; fp = lh_FUNCTION_retrieve(prog, &f); if (fp != NULL) { argv[0] = pname; ret = fp->func(argc, argv); goto end; } /* If there is stuff on the command line, run with that. */ if (argc != 1) { argc--; argv++; ret = do_cmd(prog, argc, argv); if (ret < 0) ret = 0; goto end; } /* ok, lets enter interactive mode */ for (;;) { ret = 0; /* Read a line, continue reading if line ends with \ */ for (p = buf, n = sizeof buf, i = 0, first = 1; n > 0; first = 0) { prompt = first ? "OpenSSL> " : "> "; p[0] = '\0'; #ifndef READLINE fputs(prompt, stdout); fflush(stdout); if (!fgets(p, n, stdin)) goto end; if (p[0] == '\0') goto end; i = strlen(p); if (i <= 1) break; if (p[i - 2] != '\\') break; i -= 2; p += i; n -= i; #else { extern char *readline(const char *); extern void add_history(const char *cp); char *text; text = readline(prompt); if (text == NULL) goto end; i = strlen(text); if (i == 0 || i > n) break; if (text[i - 1] != '\\') { p += strlen(strcpy(p, text)); free(text); add_history(buf); break; } text[i - 1] = '\0'; p += strlen(strcpy(p, text)); free(text); n -= i; } #endif } if (!chopup_args(&arg, buf)) { BIO_printf(bio_err, "Can't parse (no memory?)\n"); break; } ret = do_cmd(prog, arg.argc, arg.argv); if (ret == EXIT_THE_PROGRAM) { ret = 0; goto end; } if (ret != 0) BIO_printf(bio_err, "error in %s\n", arg.argv[0]); (void)BIO_flush(bio_out); (void)BIO_flush(bio_err); } ret = 1; end: OPENSSL_free(copied_argv); OPENSSL_free(default_config_file); NCONF_free(config); config = NULL; lh_FUNCTION_free(prog); OPENSSL_free(arg.argv); BIO_free(bio_in); BIO_free_all(bio_out); apps_shutdown(); #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks(bio_err) <= 0) ret = 1; #endif BIO_free(bio_err); EXIT(ret); }
int main(int Argc, char *Argv[]) { ARGS arg; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; FUNCTION f,*fp; MS_STATIC const char *prompt; MS_STATIC char buf[1024]; char *to_free=NULL; int n,i,ret=0; int argc; char **argv,*p; LHASH *prog=NULL; long errline; arg.data=NULL; arg.count=0; if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */ { if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) { CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { /* OPENSSL_DEBUG_MEMORY=off */ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #if 0 if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) #endif { CRYPTO_set_locking_callback(lock_dbg_cb); } apps_startup(); /* Lets load up our environment a little */ p=getenv("OPENSSL_CONF"); if (p == NULL) p=getenv("SSLEAY_CONF"); if (p == NULL) p=to_free=make_config_name(); default_config_file=p; config=NCONF_new(NULL); i=NCONF_load(config,p,&errline); if (i == 0) { NCONF_free(config); config = NULL; ERR_clear_error(); } prog=prog_init(); /* first check the program name */ program_name(Argv[0],pname,sizeof pname); f.name=pname; fp=(FUNCTION *)lh_retrieve(prog,&f); if (fp != NULL) { Argv[0]=pname; ret=fp->func(Argc,Argv); goto end; } /* ok, now check that there are not arguments, if there are, * run with them, shifting the ssleay off the front */ if (Argc != 1) { Argc--; Argv++; ret=do_cmd(prog,Argc,Argv); if (ret < 0) ret=0; goto end; } /* ok, lets enter the old 'OpenSSL>' mode */ for (;;) { ret=0; p=buf; n=sizeof buf; i=0; for (;;) { p[0]='\0'; if (i++) prompt=">"; else prompt="OpenSSL> "; fputs(prompt,stdout); fflush(stdout); fgets(p,n,stdin); if (p[0] == '\0') goto end; i=strlen(p); if (i <= 1) break; if (p[i-2] != '\\') break; i-=2; p+=i; n-=i; } if (!chopup_args(&arg,buf,&argc,&argv)) break; ret=do_cmd(prog,argc,argv); if (ret < 0) { ret=0; goto end; } if (ret != 0) BIO_printf(bio_err,"error in %s\n",argv[0]); (void)BIO_flush(bio_err); } BIO_printf(bio_err,"bad exit\n"); ret=1; end: if (to_free) OPENSSL_free(to_free); if (config != NULL) { NCONF_free(config); config=NULL; } if (prog != NULL) lh_free(prog); if (arg.data != NULL) OPENSSL_free(arg.data); apps_shutdown(); CRYPTO_mem_leaks(bio_err); if (bio_err != NULL) { BIO_free(bio_err); bio_err=NULL; } OPENSSL_EXIT(ret); }
int main(int Argc, char *ARGV[]) { ARGS arg; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; FUNCTION f,*fp; MS_STATIC const char *prompt; MS_STATIC char buf[1024]; char *to_free=NULL; int n,i,ret=0; int argc; char **argv,*p; LHASH_OF(FUNCTION) *prog=NULL; long errline; #if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) /* 2011-03-22 SMS. * If we have 32-bit pointers everywhere, then we're safe, and * we bypass this mess, as on non-VMS systems. (See ARGV, * above.) * Problem 1: Compaq/HP C before V7.3 always used 32-bit * pointers for argv[]. * Fix 1: For a 32-bit argv[], when we're using 64-bit pointers * everywhere else, we always allocate and use a 64-bit * duplicate of argv[]. * Problem 2: Compaq/HP C V7.3 (Alpha, IA64) before ECO1 failed * to NULL-terminate a 64-bit argv[]. (As this was written, the * compiler ECO was available only on IA64.) * Fix 2: Unless advised not to (VMS_TRUST_ARGV), we test a * 64-bit argv[argc] for NULL, and, if necessary, use a * (properly) NULL-terminated (64-bit) duplicate of argv[]. * The same code is used in either case to duplicate argv[]. * Some of these decisions could be handled in preprocessing, * but the code tends to get even uglier, and the penalty for * deciding at compile- or run-time is tiny. */ char **Argv = NULL; int free_Argv = 0; if ((sizeof( _Argv) < 8) /* 32-bit argv[]. */ # if !defined( VMS_TRUST_ARGV) || (_Argv[ Argc] != NULL) /* Untrusted argv[argc] not NULL. */ # endif ) { int i; Argv = OPENSSL_malloc( (Argc+ 1)* sizeof( char *)); if (Argv == NULL) { ret = -1; goto end; } for(i = 0; i < Argc; i++) Argv[i] = _Argv[i]; Argv[ Argc] = NULL; /* Certain NULL termination. */ free_Argv = 1; } else { /* Use the known-good 32-bit argv[] (which needs the * type cast to satisfy the compiler), or the trusted or * tested-good 64-bit argv[] as-is. */ Argv = (char **)_Argv; } #endif /* defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) */ arg.data=NULL; arg.count=0; if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */ { if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) { CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { /* OPENSSL_DEBUG_MEMORY=off */ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #if 0 if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) #endif { CRYPTO_set_locking_callback(lock_dbg_cb); } if(getenv("OPENSSL_FIPS")) { #ifdef OPENSSL_FIPS if (!FIPS_mode_set(1)) { ERR_load_crypto_strings(); ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); EXIT(1); } #else fprintf(stderr, "FIPS mode not supported.\n"); EXIT(1); #endif } apps_startup(); /* Lets load up our environment a little */ p=getenv("OPENSSL_CONF"); if (p == NULL) p=getenv("SSLEAY_CONF"); if (p == NULL) p=to_free=make_config_name(); default_config_file=p; config=NCONF_new(NULL); i=NCONF_load(config,p,&errline); if (i == 0) { if (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE) { BIO_printf(bio_err, "WARNING: can't open config file: %s\n",p); ERR_clear_error(); NCONF_free(config); config = NULL; } else { ERR_print_errors(bio_err); NCONF_free(config); exit(1); } } prog=prog_init(); /* first check the program name */ program_name(Argv[0],pname,sizeof pname); f.name=pname; fp=lh_FUNCTION_retrieve(prog,&f); if (fp != NULL) { Argv[0]=pname; ret=fp->func(Argc,Argv); goto end; } /* ok, now check that there are not arguments, if there are, * run with them, shifting the ssleay off the front */ if (Argc != 1) { Argc--; Argv++; ret=do_cmd(prog,Argc,Argv); if (ret < 0) ret=0; goto end; } /* ok, lets enter the old 'OpenSSL>' mode */ for (;;) { ret=0; p=buf; n=sizeof buf; i=0; for (;;) { p[0]='\0'; if (i++) prompt=">"; else prompt="OpenSSL> "; fputs(prompt,stdout); fflush(stdout); if (!fgets(p,n,stdin)) goto end; if (p[0] == '\0') goto end; i=strlen(p); if (i <= 1) break; if (p[i-2] != '\\') break; i-=2; p+=i; n-=i; } if (!chopup_args(&arg,buf,&argc,&argv)) break; ret=do_cmd(prog,argc,argv); if (ret < 0) { ret=0; goto end; } if (ret != 0) BIO_printf(bio_err,"error in %s\n",argv[0]); (void)BIO_flush(bio_err); } BIO_printf(bio_err,"bad exit\n"); ret=1; end: if (to_free) OPENSSL_free(to_free); if (config != NULL) { NCONF_free(config); config=NULL; } if (prog != NULL) lh_FUNCTION_free(prog); if (arg.data != NULL) OPENSSL_free(arg.data); apps_shutdown(); CRYPTO_mem_leaks(bio_err); if (bio_err != NULL) { BIO_free(bio_err); bio_err=NULL; } #if defined( OPENSSL_SYS_VMS) && (__INITIAL_POINTER_SIZE == 64) /* Free any duplicate Argv[] storage. */ if (free_Argv) { OPENSSL_free(Argv); } #endif OPENSSL_EXIT(ret); }
int main(int argc, char **argv) { ARGS arg; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE + 1]; FUNCTION f, *fp; const char *prompt; char buf[1024]; char *to_free = NULL; int n, i, ret = 0; char *p; LHASH_OF(FUNCTION) * prog = NULL; long errline; arg.data = NULL; arg.count = 0; bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (bio_err == NULL) errx(1, "failed to initialise bio_err"); CRYPTO_set_locking_callback(lock_dbg_cb); openssl_startup(); /* Lets load up our environment a little */ p = getenv("OPENSSL_CONF"); if (p == NULL) p = getenv("SSLEAY_CONF"); if (p == NULL) { p = to_free = make_config_name(); if (p == NULL) { BIO_printf(bio_err, "error making config file name\n"); goto end; } } default_config_file = p; config = NCONF_new(NULL); i = NCONF_load(config, p, &errline); if (i == 0) { if (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE) { BIO_printf(bio_err, "WARNING: can't open config file: %s\n", p); ERR_clear_error(); NCONF_free(config); config = NULL; } else { ERR_print_errors(bio_err); NCONF_free(config); exit(1); } } prog = prog_init(); /* first check the program name */ program_name(argv[0], pname, sizeof pname); f.name = pname; fp = lh_FUNCTION_retrieve(prog, &f); if (fp != NULL) { argv[0] = pname; ret = fp->func(argc, argv); goto end; } /* * ok, now check that there are not arguments, if there are, run with * them, shifting the ssleay off the front */ if (argc != 1) { argc--; argv++; ret = do_cmd(prog, argc, argv); if (ret < 0) ret = 0; goto end; } /* ok, lets enter the old 'OpenSSL>' mode */ for (;;) { ret = 0; p = buf; n = sizeof buf; i = 0; for (;;) { p[0] = '\0'; if (i++) prompt = ">"; else prompt = "OpenSSL> "; fputs(prompt, stdout); fflush(stdout); if (!fgets(p, n, stdin)) goto end; if (p[0] == '\0') goto end; i = strlen(p); if (i <= 1) break; if (p[i - 2] != '\\') break; i -= 2; p += i; n -= i; } if (!chopup_args(&arg, buf, &argc, &argv)) break; ret = do_cmd(prog, argc, argv); if (ret < 0) { ret = 0; goto end; } if (ret != 0) BIO_printf(bio_err, "error in %s\n", argv[0]); (void) BIO_flush(bio_err); } BIO_printf(bio_err, "bad exit\n"); ret = 1; end: free(to_free); if (config != NULL) { NCONF_free(config); config = NULL; } if (prog != NULL) lh_FUNCTION_free(prog); free(arg.data); openssl_shutdown(); if (bio_err != NULL) { BIO_free(bio_err); bio_err = NULL; } return (ret); }
int srp_main(int argc, char **argv) { int add_user = 0; int list_user = 0; int delete_user = 0; int modify_user = 0; char *user = NULL; char *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; char *gN = NULL; int gNindex = -1; char **gNrow = NULL; int maxgN = -1; char *userinfo = NULL; int badops = 0; int ret = 1; int errors = 0; int verbose = 0; int doupdatedb = 0; char *configfile = NULL; char *dbfile = NULL; CA_DB *db = NULL; char **pp; int i; long errorline = -1; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif char *tofree = NULL; DB_ATTR db_attr; #ifdef EFENCE EF_PROTECT_FREE = 1; EF_PROTECT_BELOW = 1; EF_ALIGNMENT = 0; #endif apps_startup(); conf = NULL; section = NULL; if (bio_err == NULL) if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); argc--; argv++; while (argc >= 1 && badops == 0) { if (strcmp(*argv, "-verbose") == 0) verbose++; else if (strcmp(*argv, "-config") == 0) { if (--argc < 1) goto bad; configfile = *(++argv); } else if (strcmp(*argv, "-name") == 0) { if (--argc < 1) goto bad; section = *(++argv); } else if (strcmp(*argv, "-srpvfile") == 0) { if (--argc < 1) goto bad; dbfile = *(++argv); } else if (strcmp(*argv, "-add") == 0) add_user = 1; else if (strcmp(*argv, "-delete") == 0) delete_user = 1; else if (strcmp(*argv, "-modify") == 0) modify_user = 1; else if (strcmp(*argv, "-list") == 0) list_user = 1; else if (strcmp(*argv, "-gn") == 0) { if (--argc < 1) goto bad; gN = *(++argv); } else if (strcmp(*argv, "-userinfo") == 0) { if (--argc < 1) goto bad; userinfo = *(++argv); } else if (strcmp(*argv, "-passin") == 0) { if (--argc < 1) goto bad; passargin = *(++argv); } else if (strcmp(*argv, "-passout") == 0) { if (--argc < 1) goto bad; passargout = *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) goto bad; engine = *(++argv); } #endif else if (**argv == '-') { bad: BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; } else break; argc--; argv++; } if (dbfile && configfile) { BIO_printf(bio_err, "-dbfile and -configfile cannot be specified together.\n"); badops = 1; } if (add_user + delete_user + modify_user + list_user != 1) { BIO_printf(bio_err, "Exactly one of the options -add, -delete, -modify -list must be specified.\n"); badops = 1; } if (delete_user + modify_user + delete_user == 1 && argc <= 0) { BIO_printf(bio_err, "Need at least one user for options -add, -delete, -modify. \n"); badops = 1; } if ((passin || passout) && argc != 1) { BIO_printf(bio_err, "-passin, -passout arguments only valid with one user.\n"); badops = 1; } if (badops) { for (pp = srp_usage; (*pp != NULL); pp++) BIO_printf(bio_err, "%s", *pp); BIO_printf(bio_err, " -rand file:file:...\n"); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); goto err; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto err; } if (!dbfile) { /*****************************************************************/ tofree = NULL; if (configfile == NULL) configfile = getenv("OPENSSL_CONF"); if (configfile == NULL) configfile = getenv("SSLEAY_CONF"); if (configfile == NULL) { if ((tofree = make_config_name()) == NULL) { BIO_printf(bio_err, "error making config file name\n"); goto err; } configfile = tofree; } VERBOSE BIO_printf(bio_err, "Using configuration from %s\n", configfile); conf = NCONF_new(NULL); if (NCONF_load(conf, configfile, &errorline) <= 0) { if (errorline <= 0) BIO_printf(bio_err, "error loading the config file '%s'\n", configfile); else BIO_printf(bio_err, "error on line %ld of config file '%s'\n" ,errorline, configfile); goto err; } if (tofree) { free(tofree); tofree = NULL; } if (!load_config(bio_err, conf)) goto err; /* Lets get the config section we are using */ if (section == NULL) { VERBOSE BIO_printf(bio_err, "trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n"); section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_SRP); if (section == NULL) { lookup_fail(BASE_SECTION, ENV_DEFAULT_SRP); goto err; } } VERBOSE BIO_printf(bio_err, "trying to read " ENV_DATABASE " in section \"%s\"\n", section); if ((dbfile = NCONF_get_string(conf, section, ENV_DATABASE)) == NULL) { lookup_fail(section, ENV_DATABASE); goto err; } } ERR_clear_error(); VERBOSE BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n", dbfile); db = load_index(dbfile, &db_attr); if (db == NULL) goto err; /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); if (pp[DB_srptype][0] == DB_SRP_INDEX) { maxgN = i; if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid])) gNindex = i; print_index(db, bio_err, i, verbose > 1); } } VERBOSE BIO_printf(bio_err, "Database initialised\n"); if (gNindex >= 0) { gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex); print_entry(db, bio_err, gNindex, verbose > 1, "Default g and N"); } else if (maxgN > 0 && !SRP_get_default_gN(gN)) { BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN); goto err; } else { VERBOSE BIO_printf(bio_err, "Database has no g N information.\n"); gNrow = NULL; } VVERBOSE BIO_printf(bio_err, "Starting user processing\n"); if (argc > 0) user = *(argv++); while (list_user || user) { int userindex = -1; if (user) VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n", user); if ((userindex = get_index(db, user, 'U')) >= 0) { print_user(db, bio_err, userindex, (verbose > 0) || list_user); } if (list_user) { if (user == NULL) { BIO_printf(bio_err, "List all users\n"); for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { print_user(db, bio_err, i, 1); } list_user = 0; } else if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n", user); errors++; } } else if (add_user) { if (userindex >= 0) { /* reactivation of a new user */ char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex); BIO_printf(bio_err, "user \"%s\" reactivated.\n", user); row[DB_srptype][0] = 'V'; doupdatedb = 1; } else { char *row[DB_NUMBER]; char *gNid; row[DB_srpverifier] = NULL; row[DB_srpsalt] = NULL; row[DB_srpinfo] = NULL; 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))) { BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned .\n", user); errors++; goto err; } row[DB_srpid] = BUF_strdup(user); row[DB_srptype] = BUF_strdup("v"); row[DB_srpgN] = BUF_strdup(gNid); if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] || (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) || !update_index(db, bio_err, row)) { if (row[DB_srpid]) free(row[DB_srpid]); if (row[DB_srpgN]) free(row[DB_srpgN]); if (row[DB_srpinfo]) free(row[DB_srpinfo]); if (row[DB_srptype]) free(row[DB_srptype]); if (row[DB_srpverifier]) free(row[DB_srpverifier]); if (row[DB_srpsalt]) free(row[DB_srpsalt]); goto err; } doupdatedb = 1; } } else if (modify_user) { if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored.\n", user); errors++; } else { char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex); char type = row[DB_srptype][0]; if (type == 'v') { BIO_printf(bio_err, "user \"%s\" already updated, operation ignored.\n", user); errors++; } else { char *gNid; if (row[DB_srptype][0] == 'V') { int user_gN; char **irow = NULL; VERBOSE BIO_printf(bio_err, "Verifying password for user \"%s\"\n", user); if ((user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0) irow = (char **) sk_OPENSSL_PSTRING_value(db->db->data, userindex); 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)) { BIO_printf(bio_err, "Invalid password for user \"%s\", operation abandoned.\n", user); errors++; goto err; } } VERBOSE BIO_printf(bio_err, "Password for user \"%s\" ok.\n", user); 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))) { BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user); errors++; goto err; } row[DB_srptype][0] = 'v'; row[DB_srpgN] = BUF_strdup(gNid); if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] || (userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo))))) goto err; doupdatedb = 1; } } } else if (delete_user) { if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user); errors++; } else { char **xpp = sk_OPENSSL_PSTRING_value(db->db->data, userindex); BIO_printf(bio_err, "user \"%s\" revoked. t\n", user); xpp[DB_srptype][0] = 'R'; doupdatedb = 1; } } if (--argc > 0) user = *(argv++); else { user = NULL; list_user = 0; } } VERBOSE BIO_printf(bio_err, "User procession done.\n"); if (doupdatedb) { /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); if (pp[DB_srptype][0] == 'v') { pp[DB_srptype][0] = 'V'; print_user(db, bio_err, i, verbose); } } VERBOSE BIO_printf(bio_err, "Trying to update srpvfile.\n"); if (!save_index(dbfile, "new", db)) goto err; VERBOSE BIO_printf(bio_err, "Temporary srpvfile created.\n"); if (!rotate_index(dbfile, "new", "old")) goto err; VERBOSE BIO_printf(bio_err, "srpvfile updated.\n"); } ret = (errors != 0); err: if (errors != 0) VERBOSE BIO_printf(bio_err, "User errors %d.\n", errors); VERBOSE BIO_printf(bio_err, "SRP terminating with code %d.\n", ret); if (tofree) free(tofree); if (ret) ERR_print_errors(bio_err); if (conf) NCONF_free(conf); if (db) free_index(db); OBJ_cleanup(); apps_shutdown(); return (ret); }
int main(int argc, char *argv[]) { FUNCTION f, *fp; LHASH_OF(FUNCTION) *prog = NULL; char **copied_argv = NULL; char *p, *pname; char buf[1024]; const char *prompt; ARGS arg; int first, n, i, ret = 0; arg.argv = NULL; arg.size = 0; /* Set up some of the environment. */ default_config_file = make_config_name(); bio_in = dup_bio_in(FORMAT_TEXT); bio_out = dup_bio_out(FORMAT_TEXT); bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); #if defined( OPENSSL_SYS_VMS) copied_argv = argv = copy_argv(&argc, argv); #endif p = getenv("OPENSSL_DEBUG_MEMORY"); if (p == NULL) /* if not set, use compiled-in default */ ; else if (strcmp(p, "off") != 0) { CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); CRYPTO_set_locking_callback(lock_dbg_cb); if (getenv("OPENSSL_FIPS")) { #ifdef OPENSSL_FIPS if (!FIPS_mode_set(1)) { ERR_load_crypto_strings(); ERR_print_errors(bio_err); return 1; } #else BIO_printf(bio_err, "FIPS mode not supported.\n"); return 1; #endif } apps_startup(); /* * If first argument is a colon, skip it. Because in "interactive" * mode our prompt is a colon and we can cut/paste whole lines * by doing this hack. */ if (argv[1] && strcmp(argv[1], ":") == 0) { argv[1] = argv[0]; argc--; argv++; } prog = prog_init(); pname = opt_progname(argv[0]); /* first check the program name */ f.name = pname; fp = lh_FUNCTION_retrieve(prog, &f); if (fp != NULL) { argv[0] = pname; ret = fp->func(argc, argv); goto end; } /* If there is stuff on the command line, run with that. */ if (argc != 1) { argc--; argv++; ret = do_cmd(prog, argc, argv); if (ret < 0) ret = 0; goto end; } /* ok, lets enter interactive mode */ for (;;) { ret = 0; /* Read a line, continue reading if line ends with \ */ for (p = buf, n = sizeof buf, i = 0, first = 1; n > 0; first = 0) { prompt = first ? "openssl : " : "> "; p[0] = '\0'; #ifndef READLINE fputs(prompt, stdout); fflush(stdout); if (!fgets(p, n, stdin)) goto end; if (p[0] == '\0') goto end; i = strlen(p); if (i <= 1) break; if (p[i - 2] != '\\') break; i -= 2; p += i; n -= i; #else { extern char *readline(const char *); extern void add_history(const char *cp); char *text; char *text = readline(prompt); if (text == NULL) goto end; i = strlen(text); if (i == 0 || i > n) break; if (text[i - 1] != '\\') { p += strlen(strcpy(p, text)); free(text); add_history(buf); break; } text[i - 1] = '\0'; p += strlen(strcpy(p, text)); free(text); n -= i; } #endif } if (!chopup_args(&arg, buf)) { BIO_printf(bio_err, "Can't parse (no memory?)\n"); break; } ret = do_cmd(prog, arg.argc, arg.argv); if (ret == EXIT_THE_PROGRAM) { ret = 0; goto end; } if (ret != 0) BIO_printf(bio_err, "error in %s\n", arg.argv[0]); (void)BIO_flush(bio_out); (void)BIO_flush(bio_err); } ret = 1; end: OPENSSL_free(copied_argv); OPENSSL_free(default_config_file); NCONF_free(config); config = NULL; lh_FUNCTION_free(prog); OPENSSL_free(arg.argv); BIO_free(bio_in); BIO_free_all(bio_out); apps_shutdown(); CRYPTO_mem_leaks(bio_err); BIO_free(bio_err); return (ret); }