Add tests and misc fixes on keystore.

* Refactor netkeystore.c to make client and server code testable.
* Add a client test for setting new passwd and changing passwd.
* Exclude "." and ".." from reset_keystore().
* Change ServerCommand.executeCommand() to accept variable length of
  arguments and add convert() to marshalling the args to bytes.
* Keystore.java is revised accordingly.
This commit is contained in:
Hung-ying Tyan 2009-09-11 18:34:28 +08:00
parent 63a85fc420
commit b2de5bd4da
7 changed files with 94 additions and 24 deletions

View File

@ -4,7 +4,7 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
netkeystore.c keymgmt.c
netkeystore.c netkeystore_main.c keymgmt.c
LOCAL_C_INCLUDES := \
$(call include-path-for, system-core)/cutils \

View File

@ -385,7 +385,10 @@ int reset_keystore()
return -1;
}
while ((de = readdir(d))) {
if (unlink(de->d_name) != 0) ret = -1;
char *dirname = de->d_name;
if (strcmp(".", dirname) == 0) continue;
if (strcmp("..", dirname) == 0) continue;
if (unlink(dirname) != 0) ret = -1;
}
closedir(d);
state = UNINITIALIZED;

View File

@ -14,8 +14,6 @@
** limitations under the License.
*/
#define LOG_TAG "keystore"
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
@ -247,7 +245,7 @@ static void do_reset_keystore(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
reply->retcode = reset_keystore();
}
static void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
{
uint32_t cmd_max = sizeof(cmds)/sizeof(struct cmdinfo);
@ -309,7 +307,7 @@ static int flatten_str_args(int argc, const char **argv, LPC_MARSHAL *cmd)
return 0;
}
static int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd)
int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd)
{
uint32_t i, len = 0;
uint32_t cmd_max = sizeof(cmds)/sizeof(cmds[0]);
@ -335,30 +333,30 @@ static int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd)
}
}
static int shell_command(const int argc, const char **argv)
int shell_command(const int argc, const char **argv)
{
int fd, i;
LPC_MARSHAL cmd;
if (parse_cmd(argc, argv , &cmd)) {
if (parse_cmd(argc, argv, &cmd)) {
fprintf(stderr, "Incorrect command or command line is too long.\n");
exit(1);
return -1;
}
fd = socket_local_client(SOCKET_PATH,
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
if (fd == -1) {
fprintf(stderr, "Keystore service is not up and running.\n");
exit(1);
return -1;
}
if (write_marshal(fd, &cmd)) {
fprintf(stderr, "Incorrect command or command line is too long.\n");
exit(1);
return -1;
}
if (read_marshal(fd, &cmd)) {
fprintf(stderr, "Failed to read the result.\n");
exit(1);
return -1;
}
cmd.data[cmd.len] = 0;
fprintf(stdout, "%s\n", (cmd.retcode == 0) ? "Succeeded!" : "Failed!");
@ -367,30 +365,26 @@ static int shell_command(const int argc, const char **argv)
return 0;
}
int main(const int argc, const char *argv[])
int server_main(const int argc, const char *argv[])
{
struct sockaddr addr;
socklen_t alen;
int lsocket, s;
LPC_MARSHAL cmd, reply;
if (argc > 1) {
return shell_command(argc - 1, argv + 1);
}
if (init_keystore(KEYSTORE_DIR)) {
LOGE("Can not initialize the keystore, the directory exist?\n");
exit(1);
return -1;
}
lsocket = android_get_control_socket(SOCKET_PATH);
if (lsocket < 0) {
LOGE("Failed to get socket from environment: %s\n", strerror(errno));
exit(1);
return -1;
}
if (listen(lsocket, 5)) {
LOGE("Listen on socket failed: %s\n", strerror(errno));
exit(1);
return -1;
}
fcntl(lsocket, F_SETFD, FD_CLOEXEC);
memset(&reply, 0, sizeof(LPC_MARSHAL));

View File

@ -25,6 +25,10 @@
#include "common.h"
// for testing
int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd);
void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply);
static inline int readx(int s, void *_buf, int count)
{
char *buf = _buf;

View File

@ -0,0 +1,29 @@
/*
** Copyright 2009, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#define LOG_TAG "keystore"
int shell_command(const int argc, const char **argv);
int server_main(const int argc, const char *argv[]);
int main(const int argc, const char *argv[])
{
if (argc > 1) {
return shell_command(argc - 1, argv + 1);
} else {
return server_main(argc, argv);
}
}

View File

@ -16,7 +16,7 @@
ifdef KEYSTORE_TESTS
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= netkeystore_test.c ../keymgmt.c
LOCAL_SRC_FILES:= netkeystore_test.c ../keymgmt.c ../netkeystore.c
LOCAL_SHARED_LIBRARIES := libcutils libssl
LOCAL_MODULE:= netkeystore_test
LOCAL_MODULE_TAGS := optional

View File

@ -29,9 +29,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <cutils/log.h>
#include "common.h"
#include "keymgmt.h"
#include "netkeystore.h"
#define LOG_TAG "keystore_test"
typedef int FUNC_PTR();
typedef struct {
@ -61,7 +65,9 @@ void setup()
void teardown()
{
reset_keystore();
if (reset_keystore() != 0) {
fprintf(stderr, "Can not reset the test directory %s\n", TEST_DIR);
}
rmdir(TEST_DIR);
}
@ -74,7 +80,7 @@ FUNC_BODY(init_keystore)
FUNC_BODY(reset_keystore)
{
chdir("/procx");
int ret = chdir("/proc");
if (reset_keystore() == 0) return -1;
chdir(TEST_DIR);
return EXIT_SUCCESS;
@ -87,7 +93,8 @@ FUNC_BODY(get_state)
if (get_state() != UNLOCKED) return -1;
lock();
if (get_state() != LOCKED) return -1;
reset_keystore();
if (reset_keystore() != 0) return -1;
if (get_state() != UNINITIALIZED) return -1;
return EXIT_SUCCESS;
}
@ -218,6 +225,37 @@ FUNC_BODY(list_keys)
return EXIT_SUCCESS;
}
static int execute_cmd(int argc, const char *argv[], LPC_MARSHAL *cmd,
LPC_MARSHAL *reply)
{
memset(cmd, 0, sizeof(LPC_MARSHAL));
memset(reply, 0, sizeof(LPC_MARSHAL));
if (parse_cmd(argc, argv, cmd)) return -1;
execute(cmd, reply);
return (reply->retcode ? -1 : 0);
}
FUNC_BODY(client_passwd)
{
LPC_MARSHAL cmd, reply;
const char *set_passwd_cmds[2] = {"passwd", TEST_PASSWD};
const char *change_passwd_cmds[3] = {"passwd", TEST_PASSWD, TEST_NPASSWD};
if (execute_cmd(2, set_passwd_cmds, &cmd, &reply)) return -1;
lock();
if (unlock("55555555") == 0) return -1;
if (unlock(TEST_PASSWD) != 0) return -1;
if (execute_cmd(3, change_passwd_cmds, &cmd, &reply)) return -1;
lock();
if (unlock(TEST_PASSWD) == 0) return -1;
if (unlock(TEST_NPASSWD) != 0) return -1;
return EXIT_SUCCESS;
}
TESTFUNC all_tests[] = {
FUNC_NAME(init_keystore),
FUNC_NAME(reset_keystore),
@ -229,11 +267,13 @@ TESTFUNC all_tests[] = {
FUNC_NAME(get_key),
FUNC_NAME(remove_key),
FUNC_NAME(list_keys),
FUNC_NAME(client_passwd),
};
int main(int argc, char **argv) {
int i, ret;
for (i = 0 ; i < (int)(sizeof(all_tests)/sizeof(TESTFUNC)) ; ++i) {
LOGD("run %s...\n", all_tests[i].name);
setup();
if ((ret = all_tests[i].func()) != EXIT_SUCCESS) {
fprintf(stderr, "ERROR in function %s\n", all_tests[i].name);