1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <stdint.h>
19#include <string.h>
20#include <sys/types.h>
21#include <sys/socket.h>
22
23#include <cutils/sockets.h>
24
25#include "keystore.h"
26
27static const char* responses[] = {
28    NULL,
29    /* [NO_ERROR]           = */ "No error",
30    /* [LOCKED]             = */ "Locked",
31    /* [UNINITIALIZED]      = */ "Uninitialized",
32    /* [SYSTEM_ERROR]       = */ "System error",
33    /* [PROTOCOL_ERROR]     = */ "Protocol error",
34    /* [PERMISSION_DENIED]  = */ "Permission denied",
35    /* [KEY_NOT_FOUND]      = */ "Key not found",
36    /* [VALUE_CORRUPTED]    = */ "Value corrupted",
37    /* [UNDEFINED_ACTION]   = */ "Undefined action",
38    /* [WRONG_PASSWORD]     = */ "Wrong password (last chance)",
39    /* [WRONG_PASSWORD + 1] = */ "Wrong password (2 tries left)",
40    /* [WRONG_PASSWORD + 2] = */ "Wrong password (3 tries left)",
41    /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
42};
43
44int main(int argc, char* argv[])
45{
46    if (argc < 2) {
47        printf("Usage: %s action [parameter ...]\n", argv[0]);
48        return 0;
49    }
50
51    int sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
52                                   SOCK_STREAM);
53    if (sock == -1) {
54        puts("Failed to connect");
55        return 1;
56    }
57
58    send(sock, argv[1], 1, 0);
59    uint8_t bytes[65536];
60    for (int i = 2; i < argc; ++i) {
61        uint16_t length = strlen(argv[i]);
62        bytes[0] = length >> 8;
63        bytes[1] = length;
64        send(sock, &bytes, 2, 0);
65        send(sock, argv[i], length, 0);
66    }
67    shutdown(sock, SHUT_WR);
68
69    uint8_t code;
70    if (recv(sock, &code, 1, 0) != 1) {
71        puts("Failed to receive");
72        return 1;
73    }
74    printf("%d %s\n", code , responses[code] ? responses[code] : "Unknown");
75    int i;
76    while ((i = recv(sock, &bytes[0], 1, 0)) == 1) {
77        int length;
78        int offset;
79        if ((i = recv(sock, &bytes[1], 1, 0)) != 1) {
80            puts("Failed to receive");
81            return 1;
82        }
83        length = bytes[0] << 8 | bytes[1];
84        for (offset = 0; offset < length; offset += i) {
85            i = recv(sock, &bytes[offset], length - offset, 0);
86            if (i <= 0) {
87                puts("Failed to receive");
88                return 1;
89            }
90        }
91        fwrite(bytes, 1, length, stdout);
92        puts("");
93    }
94    return 0;
95}
96