Loading cmds/keystore/commands.c +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ static int list_files(const char *dir, char reply[REPLY_MAX]) { reply[0]=0; while ((de = readdir(d))) { if (de->d_type != DT_REG) continue; strlcat(reply, " ", REPLY_MAX); 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; Loading cmds/keystore/keystore.c +26 −19 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ static int execute(int s, char cmd[BUFFER_MAX]) unsigned i; unsigned n = 0; unsigned short count; int ret = -1; short ret = -1; /* default reply is "" */ reply[0] = 0; Loading @@ -139,7 +139,7 @@ static int execute(int s, char cmd[BUFFER_MAX]) LOGE("%s requires %d arguments (%d given)\n", cmds[i].name, cmds[i].numargs, n); } else { ret = cmds[i].func(arg + 1, reply); ret = (short) cmds[i].func(arg + 1, reply); } goto done; } Loading @@ -148,24 +148,26 @@ static int execute(int s, char cmd[BUFFER_MAX]) done: if (reply[0]) { n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); strlcpy(cmd, reply, BUFFER_MAX); count = strlen(cmd); } else { n = snprintf(cmd, BUFFER_MAX, "%d", ret); count = 0; } if (n > BUFFER_MAX) n = BUFFER_MAX; count = n; 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, r; int fd, i; short ret; unsigned short count; char cmd[BUFFER_MAX]=""; char buf[BUFFER_MAX]=""; fd = socket_local_client(SOCKET_PATH, ANDROID_SOCKET_NAMESPACE_RESERVED, Loading @@ -175,19 +177,24 @@ int shell_command(const int argc, const char **argv) exit(1); } for(i = 0; i < argc; i++) { if (i > 0) strlcat(cmd, " ", BUFFER_MAX); if(strlcat(cmd, argv[i], BUFFER_MAX) >= BUFFER_MAX) { 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(cmd); count = strlen(buf); if (writex(fd, &count, sizeof(count))) return -1; if (writex(fd, cmd, strlen(cmd))) 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, cmd, count)) return -1; cmd[count]=0; fprintf(stdout, "%s\n", cmd); 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; } Loading keystore/java/android/security/Keystore.java 0 → 100644 +103 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ package android.security; /** * The Keystore class provides the functions to list the certs/keys in keystore. * {@hide} */ public abstract class Keystore { private static final String TAG = "Keystore"; private static final String[] NOTFOUND = new String[0]; /** */ public static Keystore getInstance() { return new FileKeystore(); } /** */ public abstract String getUserkey(String key); /** */ public abstract String getCertificate(String key); /** */ public abstract String[] getAllCertificateKeys(); /** */ public abstract String[] getAllUserkeyKeys(); private static class FileKeystore extends Keystore { private static final String SERVICE_NAME = "keystore"; private static final String LIST_CERTIFICATES = "listcerts"; private static final String LIST_USERKEYS = "listuserkeys"; private static final String PATH = "/data/misc/keystore/"; private static final String USERKEY_PATH = PATH + "userkeys/"; private static final String CERT_PATH = PATH + "certs/"; private static final ServiceCommand mServiceCommand = new ServiceCommand(SERVICE_NAME); @Override public String getUserkey(String key) { return USERKEY_PATH + key; } @Override public String getCertificate(String key) { return CERT_PATH + key; } /** * Returns the array of the certificate names in keystore if successful. * Or return an empty array if error. * * @return array of the certificates */ @Override public String[] getAllCertificateKeys() { try { String result = mServiceCommand.execute(LIST_CERTIFICATES); if (result != null) return result.split("\\s+"); return NOTFOUND; } catch (NumberFormatException ex) { return NOTFOUND; } } /** * Returns the array of the names of private keys in keystore if successful. * Or return an empty array if errors. * * @return array of the user keys */ @Override public String[] getAllUserkeyKeys() { try { String result = mServiceCommand.execute(LIST_USERKEYS); if (result != null) return result.split("\\s+"); return NOTFOUND; } catch (NumberFormatException ex) { return NOTFOUND; } } } } keystore/java/android/security/ServiceCommand.java 0 → 100644 +178 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ package android.security; import android.net.LocalSocketAddress; import android.net.LocalSocket; import android.util.Config; import android.util.Log; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /* * ServiceCommand is used to connect to a service throught the local socket, * and send out the command, return the result to the caller. * {@hide} */ public class ServiceCommand { public static final String SUCCESS = "0"; public static final String FAILED = "-1"; private String mServiceName; private String mTag; private InputStream mIn; private OutputStream mOut; private LocalSocket mSocket; private static final int BUFFER_LENGTH = 1024; private byte buf[] = new byte[BUFFER_LENGTH]; private int buflen = 0; private boolean connect() { if (mSocket != null) { return true; } Log.i(mTag, "connecting..."); try { mSocket = new LocalSocket(); LocalSocketAddress address = new LocalSocketAddress( mServiceName, LocalSocketAddress.Namespace.RESERVED); mSocket.connect(address); mIn = mSocket.getInputStream(); mOut = mSocket.getOutputStream(); } catch (IOException ex) { disconnect(); return false; } return true; } private void disconnect() { Log.i(mTag,"disconnecting..."); try { if (mSocket != null) mSocket.close(); } catch (IOException ex) { } try { if (mIn != null) mIn.close(); } catch (IOException ex) { } try { if (mOut != null) mOut.close(); } catch (IOException ex) { } mSocket = null; mIn = null; mOut = null; } private boolean readBytes(byte buffer[], int len) { int off = 0, count; if (len < 0) return false; while (off != len) { try { count = mIn.read(buffer, off, len - off); if (count <= 0) { Log.e(mTag, "read error " + count); break; } off += count; } catch (IOException ex) { Log.e(mTag,"read exception"); break; } } if (off == len) return true; disconnect(); return false; } private boolean readReply() { int len, ret; buflen = 0; if (!readBytes(buf, 2)) return false; ret = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8); if (ret != 0) return false; if (!readBytes(buf, 2)) return false; len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8); if (len > BUFFER_LENGTH) { Log.e(mTag,"invalid reply length (" + len + ")"); disconnect(); return false; } if (!readBytes(buf, len)) return false; buflen = len; return true; } private boolean writeCommand(String _cmd) { byte[] cmd = _cmd.getBytes(); int len = cmd.length; if ((len < 1) || (len > BUFFER_LENGTH)) return false; buf[0] = (byte) (len & 0xff); buf[1] = (byte) ((len >> 8) & 0xff); try { mOut.write(buf, 0, 2); mOut.write(cmd, 0, len); } catch (IOException ex) { Log.e(mTag,"write error"); disconnect(); return false; } return true; } private String executeCommand(String cmd) { if (!writeCommand(cmd)) { /* If service died and restarted in the background * (unlikely but possible) we'll fail on the next * write (this one). Try to reconnect and write * the command one more time before giving up. */ Log.e(mTag, "write command failed? reconnect!"); if (!connect() || !writeCommand(cmd)) { return null; } } if (readReply()) { return new String(buf, 0, buflen); } else { return null; } } public synchronized String execute(String cmd) { String result; if (!connect()) { Log.e(mTag, "connection failed"); return null; } result = executeCommand(cmd); disconnect(); return result; } public ServiceCommand(String service) { mServiceName = service; mTag = service; } } Loading
cmds/keystore/commands.c +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ static int list_files(const char *dir, char reply[REPLY_MAX]) { reply[0]=0; while ((de = readdir(d))) { if (de->d_type != DT_REG) continue; strlcat(reply, " ", REPLY_MAX); 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; Loading
cmds/keystore/keystore.c +26 −19 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ static int execute(int s, char cmd[BUFFER_MAX]) unsigned i; unsigned n = 0; unsigned short count; int ret = -1; short ret = -1; /* default reply is "" */ reply[0] = 0; Loading @@ -139,7 +139,7 @@ static int execute(int s, char cmd[BUFFER_MAX]) LOGE("%s requires %d arguments (%d given)\n", cmds[i].name, cmds[i].numargs, n); } else { ret = cmds[i].func(arg + 1, reply); ret = (short) cmds[i].func(arg + 1, reply); } goto done; } Loading @@ -148,24 +148,26 @@ static int execute(int s, char cmd[BUFFER_MAX]) done: if (reply[0]) { n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); strlcpy(cmd, reply, BUFFER_MAX); count = strlen(cmd); } else { n = snprintf(cmd, BUFFER_MAX, "%d", ret); count = 0; } if (n > BUFFER_MAX) n = BUFFER_MAX; count = n; 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, r; int fd, i; short ret; unsigned short count; char cmd[BUFFER_MAX]=""; char buf[BUFFER_MAX]=""; fd = socket_local_client(SOCKET_PATH, ANDROID_SOCKET_NAMESPACE_RESERVED, Loading @@ -175,19 +177,24 @@ int shell_command(const int argc, const char **argv) exit(1); } for(i = 0; i < argc; i++) { if (i > 0) strlcat(cmd, " ", BUFFER_MAX); if(strlcat(cmd, argv[i], BUFFER_MAX) >= BUFFER_MAX) { 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(cmd); count = strlen(buf); if (writex(fd, &count, sizeof(count))) return -1; if (writex(fd, cmd, strlen(cmd))) 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, cmd, count)) return -1; cmd[count]=0; fprintf(stdout, "%s\n", cmd); 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; } Loading
keystore/java/android/security/Keystore.java 0 → 100644 +103 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ package android.security; /** * The Keystore class provides the functions to list the certs/keys in keystore. * {@hide} */ public abstract class Keystore { private static final String TAG = "Keystore"; private static final String[] NOTFOUND = new String[0]; /** */ public static Keystore getInstance() { return new FileKeystore(); } /** */ public abstract String getUserkey(String key); /** */ public abstract String getCertificate(String key); /** */ public abstract String[] getAllCertificateKeys(); /** */ public abstract String[] getAllUserkeyKeys(); private static class FileKeystore extends Keystore { private static final String SERVICE_NAME = "keystore"; private static final String LIST_CERTIFICATES = "listcerts"; private static final String LIST_USERKEYS = "listuserkeys"; private static final String PATH = "/data/misc/keystore/"; private static final String USERKEY_PATH = PATH + "userkeys/"; private static final String CERT_PATH = PATH + "certs/"; private static final ServiceCommand mServiceCommand = new ServiceCommand(SERVICE_NAME); @Override public String getUserkey(String key) { return USERKEY_PATH + key; } @Override public String getCertificate(String key) { return CERT_PATH + key; } /** * Returns the array of the certificate names in keystore if successful. * Or return an empty array if error. * * @return array of the certificates */ @Override public String[] getAllCertificateKeys() { try { String result = mServiceCommand.execute(LIST_CERTIFICATES); if (result != null) return result.split("\\s+"); return NOTFOUND; } catch (NumberFormatException ex) { return NOTFOUND; } } /** * Returns the array of the names of private keys in keystore if successful. * Or return an empty array if errors. * * @return array of the user keys */ @Override public String[] getAllUserkeyKeys() { try { String result = mServiceCommand.execute(LIST_USERKEYS); if (result != null) return result.split("\\s+"); return NOTFOUND; } catch (NumberFormatException ex) { return NOTFOUND; } } } }
keystore/java/android/security/ServiceCommand.java 0 → 100644 +178 −0 Original line number Diff line number Diff line /* * Copyright (C) 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. */ package android.security; import android.net.LocalSocketAddress; import android.net.LocalSocket; import android.util.Config; import android.util.Log; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /* * ServiceCommand is used to connect to a service throught the local socket, * and send out the command, return the result to the caller. * {@hide} */ public class ServiceCommand { public static final String SUCCESS = "0"; public static final String FAILED = "-1"; private String mServiceName; private String mTag; private InputStream mIn; private OutputStream mOut; private LocalSocket mSocket; private static final int BUFFER_LENGTH = 1024; private byte buf[] = new byte[BUFFER_LENGTH]; private int buflen = 0; private boolean connect() { if (mSocket != null) { return true; } Log.i(mTag, "connecting..."); try { mSocket = new LocalSocket(); LocalSocketAddress address = new LocalSocketAddress( mServiceName, LocalSocketAddress.Namespace.RESERVED); mSocket.connect(address); mIn = mSocket.getInputStream(); mOut = mSocket.getOutputStream(); } catch (IOException ex) { disconnect(); return false; } return true; } private void disconnect() { Log.i(mTag,"disconnecting..."); try { if (mSocket != null) mSocket.close(); } catch (IOException ex) { } try { if (mIn != null) mIn.close(); } catch (IOException ex) { } try { if (mOut != null) mOut.close(); } catch (IOException ex) { } mSocket = null; mIn = null; mOut = null; } private boolean readBytes(byte buffer[], int len) { int off = 0, count; if (len < 0) return false; while (off != len) { try { count = mIn.read(buffer, off, len - off); if (count <= 0) { Log.e(mTag, "read error " + count); break; } off += count; } catch (IOException ex) { Log.e(mTag,"read exception"); break; } } if (off == len) return true; disconnect(); return false; } private boolean readReply() { int len, ret; buflen = 0; if (!readBytes(buf, 2)) return false; ret = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8); if (ret != 0) return false; if (!readBytes(buf, 2)) return false; len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8); if (len > BUFFER_LENGTH) { Log.e(mTag,"invalid reply length (" + len + ")"); disconnect(); return false; } if (!readBytes(buf, len)) return false; buflen = len; return true; } private boolean writeCommand(String _cmd) { byte[] cmd = _cmd.getBytes(); int len = cmd.length; if ((len < 1) || (len > BUFFER_LENGTH)) return false; buf[0] = (byte) (len & 0xff); buf[1] = (byte) ((len >> 8) & 0xff); try { mOut.write(buf, 0, 2); mOut.write(cmd, 0, len); } catch (IOException ex) { Log.e(mTag,"write error"); disconnect(); return false; } return true; } private String executeCommand(String cmd) { if (!writeCommand(cmd)) { /* If service died and restarted in the background * (unlikely but possible) we'll fail on the next * write (this one). Try to reconnect and write * the command one more time before giving up. */ Log.e(mTag, "write command failed? reconnect!"); if (!connect() || !writeCommand(cmd)) { return null; } } if (readReply()) { return new String(buf, 0, buflen); } else { return null; } } public synchronized String execute(String cmd) { String result; if (!connect()) { Log.e(mTag, "connection failed"); return null; } result = executeCommand(cmd); disconnect(); return result; } public ServiceCommand(String service) { mServiceName = service; mTag = service; } }