Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6822d7a authored by Mathias Agopian's avatar Mathias Agopian
Browse files

Merge commit 'goog/master' into merge_master

parents 375f5636 ecbcd559
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -215,7 +215,7 @@ status_t CameraService::Client::unlock()
{
    Mutex::Autolock _l(mLock);
    // allow anyone to use camera
    LOGV("unlock (%p)", getCameraClient()->asBinder().get());
    LOGD("unlock (%p)", getCameraClient()->asBinder().get());
    status_t result = checkPid();
    if (result == NO_ERROR) {
        mClientPid = 0;
@@ -230,7 +230,7 @@ status_t CameraService::Client::unlock()
status_t CameraService::Client::connect(const sp<ICameraClient>& client)
{
    // connect a new process to the camera
    LOGV("connect (%p)", client->asBinder().get());
    LOGD("connect (%p)", client->asBinder().get());

    // I hate this hack, but things get really ugly when the media recorder
    // service is handing back the camera to the app. The ICameraClient
@@ -245,7 +245,7 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client)
        sp<ICameraClient> oldClient;
        {
            Mutex::Autolock _l(mLock);
            if (mClientPid != 0) {
            if (mClientPid != 0 && checkPid() != NO_ERROR) {
                LOGW("Tried to connect to locked camera");
                return -EBUSY;
            }
@@ -257,7 +257,7 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client)
            mCameraClient = client;
            mClientPid = -1;
            mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
            LOGV("connect new process (%d) to existing camera client", mClientPid);
            LOGD("connect new process (%d) to existing camera client", mClientPid);
        }

    }
@@ -319,17 +319,17 @@ void CameraService::Client::disconnect()
            IPCThreadState::self()->getCallingPid());
    Mutex::Autolock lock(mLock);
    if (mClientPid <= 0) {
        LOGV("camera is unlocked, don't tear down hardware");
        LOGD("camera is unlocked, don't tear down hardware");
        return;
    }
    if (checkPid() != NO_ERROR) {
        LOGV("Different client - don't disconnect");
        LOGD("Different client - don't disconnect");
        return;
    }

    mCameraService->removeClient(mCameraClient);
    if (mHardware != 0) {
        LOGV("hardware teardown");
        LOGD("hardware teardown");
        // Before destroying mHardware, we must make sure it's in the
        // idle state.
        mHardware->stopPreview();
+21 −0
Original line number Diff line number Diff line
ifneq ($(TARGET_SIMULATOR),true)

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
    keystore.c commands.c

LOCAL_C_INCLUDES := \
    $(call include-path-for, system-core)/cutils

LOCAL_SHARED_LIBRARIES := \
    libcutils

LOCAL_STATIC_LIBRARIES :=

LOCAL_MODULE:= keystore

include $(BUILD_EXECUTABLE)

endif # !simulator))
+141 −0
Original line number Diff line number Diff line
/*
** Copyright 2008, 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.
*/

#include "keystore.h"

static DIR *open_keystore(const char *dir)
{
    DIR *d;
    if ((d = opendir(dir)) == NULL) {
        if (mkdir(dir, 0770) < 0) {
            LOGE("cannot create dir '%s': %s\n", dir, strerror(errno));
            unlink(dir);
            return NULL;
        }
        d = open_keystore(dir);
    }
    return d;
}

static int list_files(const char *dir, char reply[REPLY_MAX]) {
    struct dirent *de;
    DIR *d;

    if ((d = open_keystore(dir)) == NULL) {
        return -1;
    }
    reply[0]=0;
    while ((de = readdir(d))) {
        if (de->d_type != DT_REG) continue;
        if (reply[0] != 0) strlcat(reply, " ", REPLY_MAX);
        if (strlcat(reply, de->d_name, REPLY_MAX) >= REPLY_MAX) {
            LOGE("reply is too long(too many files under '%s'\n", dir);
            return -1;
        }
    }
    closedir(d);
    return 0;
}

static int copy_keyfile(const char *keystore, const char *srcfile) {
    int srcfd, dstfd;
    int length;
    char buf[2048];
    char dstfile[KEYNAME_LENGTH];
    const char *filename = strrchr(srcfile, '/');

    strlcpy(dstfile, keystore, KEYNAME_LENGTH);
    strlcat(dstfile, "/", KEYNAME_LENGTH);
    if (strlcat(dstfile, filename ? filename + 1 : srcfile,
                KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
        LOGE("keyname is too long '%s'\n", srcfile);
        return -1;
    }

    if ((srcfd = open(srcfile, O_RDONLY)) == -1) {
        LOGE("Cannot open the original file '%s'\n", srcfile);
        return -1;
    }
    if ((dstfd = open(dstfile, O_CREAT|O_RDWR)) == -1) {
        LOGE("Cannot open the destination file '%s'\n", dstfile);
        return -1;
    }
    while((length = read(srcfd, buf, 2048)) > 0) {
        write(dstfd, buf, length);
    }
    close(srcfd);
    close(dstfd);
    chmod(dstfile, 0440);
    return 0;
}

static int install_key(const char *dir, const char *keyfile)
{
    struct dirent *de;
    DIR *d;

    if ((d = open_keystore(dir)) == NULL) {
        return -1;
    }
    return copy_keyfile(dir, keyfile);
}

static int remove_key(const char *dir, const char *keyfile)
{
    char dstfile[KEYNAME_LENGTH];

    strlcpy(dstfile, dir, KEYNAME_LENGTH);
    strlcat(dstfile, "/", KEYNAME_LENGTH);
    if (strlcat(dstfile, keyfile, KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
        LOGE("keyname is too long '%s'\n", keyfile);
        return -1;
    }
    if (unlink(dstfile)) {
        LOGE("cannot delete '%s': %s\n", dstfile, strerror(errno));
        return -1;
    }
    return 0;
}

int list_certs(char reply[REPLY_MAX])
{
    return list_files(CERTS_DIR, reply);
}

int list_userkeys(char reply[REPLY_MAX])
{
    return list_files(USERKEYS_DIR, reply);
}

int install_cert(const char *certfile)
{
    return install_key(CERTS_DIR, certfile);
}

int install_userkey(const char *keyfile)
{
    return install_key(USERKEYS_DIR, keyfile);
}

int remove_cert(const char *certfile)
{
    return remove_key(CERTS_DIR, certfile);
}

int remove_userkey(const char *keyfile)
{
    return remove_key(USERKEYS_DIR, keyfile);
}
+255 −0
Original line number Diff line number Diff line
/*
** 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.
*/

#include "keystore.h"


static int do_list_certs(char **arg, char reply[REPLY_MAX])
{
    return list_certs(reply);
}

static int do_list_userkeys(char **arg, char reply[REPLY_MAX])
{
    return list_userkeys(reply);
}

static int do_install_cert(char **arg, char reply[REPLY_MAX])
{
    return install_cert(arg[0]); /* move the certificate to keystore */
}

static int do_remove_cert(char **arg, char reply[REPLY_MAX])
{
    return remove_cert(arg[0]); /* certificate */
}

static int do_install_userkey(char **arg, char reply[REPLY_MAX])
{
    return install_userkey(arg[0]); /* move the certificate to keystore */
}

static int do_remove_userkey(char **arg, char reply[REPLY_MAX])
{
    return remove_userkey(arg[0]); /* userkey */
}

struct cmdinfo {
    const char *name;
    unsigned numargs;
    int (*func)(char **arg, char reply[REPLY_MAX]);
};


struct cmdinfo cmds[] = {
    { "listcerts",            0, do_list_certs },
    { "listuserkeys",         0, do_list_userkeys },
    { "installcert",          1, do_install_cert },
    { "removecert",           1, do_remove_cert },
    { "installuserkey",       1, do_install_userkey },
    { "removeuserkey",        1, do_remove_userkey },
};

static int readx(int s, void *_buf, int count)
{
    char *buf = _buf;
    int n = 0, r;
    if (count < 0) return -1;
    while (n < count) {
        r = read(s, buf + n, count - n);
        if (r < 0) {
            if (errno == EINTR) continue;
            LOGE("read error: %s\n", strerror(errno));
            return -1;
        }
        if (r == 0) {
            LOGE("eof\n");
            return -1; /* EOF */
        }
        n += r;
    }
    return 0;
}

static int writex(int s, const void *_buf, int count)
{
    const char *buf = _buf;
    int n = 0, r;
    if (count < 0) return -1;
    while (n < count) {
        r = write(s, buf + n, count - n);
        if (r < 0) {
            if (errno == EINTR) continue;
            LOGE("write error: %s\n", strerror(errno));
            return -1;
        }
        n += r;
    }
    return 0;
}


/* Tokenize the command buffer, locate a matching command,
 * ensure that the required number of arguments are provided,
 * call the function(), return the result.
 */
static int execute(int s, char cmd[BUFFER_MAX])
{
    char reply[REPLY_MAX];
    char *arg[TOKEN_MAX+1];
    unsigned i;
    unsigned n = 0;
    unsigned short count;
    short ret = -1;

    /* default reply is "" */
    reply[0] = 0;

    /* n is number of args (not counting arg[0]) */
    arg[0] = cmd;
    while (*cmd) {
        if (isspace(*cmd)) {
            *cmd++ = 0;
            n++;
            arg[n] = cmd;
            if (n == TOKEN_MAX) {
                LOGE("too many arguments\n");
                goto done;
            }
        }
        cmd++;
    }

    for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) {
        if (!strcmp(cmds[i].name,arg[0])) {
            if (n != cmds[i].numargs) {
                LOGE("%s requires %d arguments (%d given)\n",
                     cmds[i].name, cmds[i].numargs, n);
            } else {
                ret = (short) cmds[i].func(arg + 1, reply);
            }
            goto done;
        }
    }
    LOGE("unsupported command '%s'\n", arg[0]);

done:
    if (reply[0]) {
        strlcpy(cmd, reply, BUFFER_MAX);
        count = strlen(cmd);
    } else {
        count = 0;
    }
    if (writex(s, &ret, sizeof(ret))) return -1;
    if (ret == 0) {
        if (writex(s, &count, sizeof(count))) return -1;
        if (writex(s, cmd, count)) return -1;
    }

    return 0;
}

int shell_command(const int argc, const char **argv)
{
    int fd, i;
    short ret;
    unsigned short count;
    char buf[BUFFER_MAX]="";

    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);
    }
    for(i = 0; i < argc; i++) {
        if (i > 0) strlcat(buf, " ", BUFFER_MAX);
        if(strlcat(buf, argv[i], BUFFER_MAX) >= BUFFER_MAX) {
            fprintf(stderr, "Arguments are too long\n");
            exit(1);
        }
    }
    count = strlen(buf);
    if (writex(fd, &count, sizeof(count))) return -1;
    if (writex(fd, buf, strlen(buf))) return -1;
    if (readx(fd, &ret, sizeof(ret))) return -1;
    if (ret == 0) {
        if (readx(fd, &count, sizeof(count))) return -1;
        if (readx(fd, buf, count)) return -1;
        buf[count]=0;
        fprintf(stdout, "%s\n", buf);
    } else {
        fprintf(stderr, "Failed, please check log!\n");
    }
    return 0;
}

int main(const int argc, const char *argv[])
{
    char buf[BUFFER_MAX];
    struct sockaddr addr;
    socklen_t alen;
    int lsocket, s, count;

    if (argc > 1) {
        return shell_command(argc - 1, argv + 1);
    }

    lsocket = android_get_control_socket(SOCKET_PATH);
    if (lsocket < 0) {
        LOGE("Failed to get socket from environment: %s\n", strerror(errno));
        exit(1);
    }
    if (listen(lsocket, 5)) {
        LOGE("Listen on socket failed: %s\n", strerror(errno));
        exit(1);
    }
    fcntl(lsocket, F_SETFD, FD_CLOEXEC);

    for (;;) {
        alen = sizeof(addr);
        s = accept(lsocket, &addr, &alen);
        if (s < 0) {
            LOGE("Accept failed: %s\n", strerror(errno));
            continue;
        }
        fcntl(s, F_SETFD, FD_CLOEXEC);

        LOGI("new connection\n");
        for (;;) {
            unsigned short count;
            if (readx(s, &count, sizeof(count))) {
                LOGE("failed to read size\n");
                break;
            }
            if ((count < 1) || (count >= BUFFER_MAX)) {
                LOGE("invalid size %d\n", count);
                break;
            }
            if (readx(s, buf, count)) {
                LOGE("failed to read command\n");
                break;
            }
            buf[count] = 0;
            if (execute(s, buf)) break;
        }
        LOGI("closing connection\n");
        close(s);
    }

    return 0;
}
+57 −0
Original line number Diff line number Diff line
/*
**
** 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"

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <utime.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <cutils/sockets.h>
#include <cutils/log.h>
#include <cutils/properties.h>

#define SOCKET_PATH "keystore"


/* path of the keystore */

#define KEYSTORE_DIR_PREFIX "/data/misc/keystore"
#define CERTS_DIR           KEYSTORE_DIR_PREFIX "/certs"
#define USERKEYS_DIR         KEYSTORE_DIR_PREFIX "/userkeys"

#define BUFFER_MAX      1024  /* input buffer for commands */
#define TOKEN_MAX       8     /* max number of arguments in buffer */
#define REPLY_MAX       1024  /* largest reply allowed */
#define KEYNAME_LENGTH  128

/* commands.c */
int list_certs(char reply[REPLY_MAX]);
int list_userkeys(char reply[REPLY_MAX]);
int install_cert(const char *certfile);
int install_userkey(const char *keyfile);
int remove_cert(const char *certfile);
int remove_userkey(const char *keyfile);
Loading