int common_init(char *cmd) { int rc; struct securid_token *t; int is_import = !strcmp(cmd, "import"); /* * we don't actually scrub memory, but at least try to keep the seeds * from being swapped out to disk */ mlockall(MCL_CURRENT | MCL_FUTURE); cfg = xzalloc(sizeof(*cfg)); if (__stoken_read_rcfile(opt_rcfile, cfg, &warn) != ERR_NONE) __stoken_zap_rcfile_data(cfg); if (cfg->rc_ver && atoi(cfg->rc_ver) != RC_VER) { warn("rcfile: version mismatch, ignoring contents\n"); __stoken_zap_rcfile_data(cfg); } /* accept a token from the command line, or fall back to the rcfile */ do { t = xmalloc(sizeof(struct securid_token)); if (opt_token) { rc = __stoken_parse_and_decode_token(opt_token, t); if (rc != ERR_NONE) die("error: --token string is garbled: %s\n", stoken_errstr[rc]); current_token = t; break; } if (opt_file) { rc = read_token_from_file(opt_file, t); if (rc != ERR_NONE) die("error: no valid token in file '%s': %s\n", opt_file, stoken_errstr[rc]); current_token = t; break; } if (opt_random) { rc = securid_random_token(t); if (rc != ERR_NONE) die("error: can't generate random token\n"); current_token = t; break; } if (cfg->rc_token) { if (is_import) die("error: please specify --file, --token, or --random\n"); if (decode_rc_token(cfg, t) == ERR_NONE) { current_token = t; break; } } free(t); } while (0); if (is_import && cfg->rc_token && !opt_force) die("error: token already exists; use --force to overwrite it\n"); return ERR_NONE; }
// Implementation static boolean verify_authentication_request(BIO *bio_client, char *username_ret, boolean *is_admin_flag_ret, char *key_exchange_passwd_ret) { boolean verification_flag; MYSQL *db_conn = NULL; MYSQL_RES *result = NULL; MYSQL_ROW row; char stat[SQL_STATEMENT_LENGTH + 1]; char err_msg[ERR_MSG_LENGTH + 1]; char token_name[TOKEN_NAME_LENGTH + 1]; char is_admin_flag_str_tmp[FLAG_LENGTH + 1]; // "0" or "1" char passwd[PASSWD_LENGTH + 1]; char salted_passwd_hash_cmp[SHA1_DIGEST_LENGTH + 1]; char salted_passwd_hash[SHA1_DIGEST_LENGTH + 1]; char salt_value[SALT_VALUE_LENGTH + 1]; char passwd_with_salt_value[PASSWD_LENGTH + SALT_VALUE_LENGTH + 1]; // Receive the verification information if(!BIO_recv_file(bio_client, VERIFICATION_INFO_CIPHERTEXT_PATH)) { fprintf(stderr, "Receiving verification information failed\n"); goto ERROR; } // Decrypt the verification information with the User Authority's private key if(!smime_decrypt_with_cert(VERIFICATION_INFO_CIPHERTEXT_PATH, VERIFICATION_INFO_PLAINTEXT_PATH, UA_CERTFILE_PATH, UA_CERTFILE_PASSWD, err_msg)) { fprintf(stderr, "Decrypting verification information failed\n\"%s\"\n", err_msg); goto ERROR; } unlink(VERIFICATION_INFO_CIPHERTEXT_PATH); // Get the verification information from file if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 1, token_name, is_admin_flag_str_tmp) != READ_TOKEN_SUCCESS || strcmp(token_name, "is_admin_flag") != 0) { int_error("Extracting the is_admin_flag failed"); } *is_admin_flag_ret = (strcmp(is_admin_flag_str_tmp, "1") == 0) ? true : false; if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 2, token_name, username_ret) != READ_TOKEN_SUCCESS || strcmp(token_name, "username") != 0) { int_error("Extracting the username failed"); } if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 3, token_name, passwd) != READ_TOKEN_SUCCESS || strcmp(token_name, "passwd") != 0) { int_error("Extracting the passwd failed"); } if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 4, token_name, key_exchange_passwd_ret) != READ_TOKEN_SUCCESS || strcmp(token_name, "key_exchange_passwd") != 0) { int_error("Extracting the key_exchange_passwd failed"); } unlink(VERIFICATION_INFO_PLAINTEXT_PATH); // Connect the database connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME); // Verify the user sprintf(stat, "SELECT salted_passwd_hash, salt_value FROM %s WHERE username LIKE '%s' " "COLLATE latin1_general_cs", (*is_admin_flag_ret) ? UA__ADMINS : UA__USERS, username_ret); if(mysql_query(db_conn, stat)) { sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn)); int_error(err_msg); } result = mysql_store_result(db_conn); row = mysql_fetch_row(result); if(row) { strcpy(salted_passwd_hash_cmp, row[0]); strcpy(salt_value, row[1]); // Get the salted password hash sprintf(passwd_with_salt_value, "%s%s", passwd, salt_value); sum_sha1_from_string(passwd_with_salt_value, strlen(passwd_with_salt_value), salted_passwd_hash, SALTED_PASSWD_HASH_PATH); if(strcmp(salted_passwd_hash, salted_passwd_hash_cmp) == 0) // Authentication succeed { verification_flag = true; if(!write_token_into_file("verification_result_flag", "1", true, VERIFICATION_RESULT_PLAINTEXT_PATH)) int_error("Writing the verification_result_flag failed"); } else // Authentication failed { verification_flag = false; if(!write_token_into_file("verification_result_flag", "0", true, VERIFICATION_RESULT_PLAINTEXT_PATH)) int_error("Writing the verification_result_flag failed"); if(!write_token_into_file("error_msg", "Invalid username or password", false, VERIFICATION_RESULT_PLAINTEXT_PATH)) int_error("Writing the error_msg failed"); } } else // Authentication failed { verification_flag = false; if(!write_token_into_file("verification_result_flag", "0", true, VERIFICATION_RESULT_PLAINTEXT_PATH)) int_error("Writing the verification_result_flag failed"); if(!write_token_into_file("error_msg", "Invalid username or password", false, VERIFICATION_RESULT_PLAINTEXT_PATH)) int_error("Writing the error_msg failed"); } if(result) { mysql_free_result(result); result = NULL; } disconnect_db(&db_conn); // Encrypt the verification result with random session password if(!des3_encrypt(VERIFICATION_RESULT_PLAINTEXT_PATH, VERIFICATION_RESULT_CIPHERTEXT_PATH, key_exchange_passwd_ret, err_msg)) { fprintf(stderr, "Encrypting the verification result failed\n\"%s\"\n", err_msg); goto ERROR; } unlink(VERIFICATION_RESULT_PLAINTEXT_PATH); // Send the verification result if(!BIO_send_file(bio_client, VERIFICATION_RESULT_CIPHERTEXT_PATH)) { fprintf(stderr, "Sending the verification result failed"); goto ERROR; } unlink(VERIFICATION_RESULT_CIPHERTEXT_PATH); return verification_flag; ERROR: unlink(VERIFICATION_INFO_CIPHERTEXT_PATH); unlink(VERIFICATION_INFO_PLAINTEXT_PATH); unlink(VERIFICATION_RESULT_PLAINTEXT_PATH); unlink(VERIFICATION_RESULT_CIPHERTEXT_PATH); return false; }