Exemple #1
0
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;
}