Merge "adb: stop using adbkey.pub." am: fa105049d8
am: d78cbabf5d
Change-Id: Ib1b358c09f40b7c2419fe89ef0de83e6355c76a0
This commit is contained in:
commit
ab48cdfd04
3 changed files with 57 additions and 75 deletions
|
|
@ -36,6 +36,7 @@
|
||||||
void adb_auth_init();
|
void adb_auth_init();
|
||||||
|
|
||||||
int adb_auth_keygen(const char* filename);
|
int adb_auth_keygen(const char* filename);
|
||||||
|
int adb_auth_pubkey(const char* filename);
|
||||||
std::string adb_auth_get_userkey();
|
std::string adb_auth_get_userkey();
|
||||||
std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys();
|
std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
#include "adb_auth.h"
|
#include "adb_auth.h"
|
||||||
|
#include "adb_io.h"
|
||||||
#include "adb_utils.h"
|
#include "adb_utils.h"
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
|
@ -52,30 +53,7 @@ static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
|
||||||
*new std::map<std::string, std::shared_ptr<RSA>>;
|
*new std::map<std::string, std::shared_ptr<RSA>>;
|
||||||
static std::map<int, std::string>& g_monitored_paths = *new std::map<int, std::string>;
|
static std::map<int, std::string>& g_monitored_paths = *new std::map<int, std::string>;
|
||||||
|
|
||||||
static std::string get_user_info() {
|
static bool calculate_public_key(std::string* out, RSA* private_key) {
|
||||||
LOG(INFO) << "get_user_info...";
|
|
||||||
|
|
||||||
std::string hostname;
|
|
||||||
if (getenv("HOSTNAME")) hostname = getenv("HOSTNAME");
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
char buf[64];
|
|
||||||
if (hostname.empty() && gethostname(buf, sizeof(buf)) != -1) hostname = buf;
|
|
||||||
#endif
|
|
||||||
if (hostname.empty()) hostname = "unknown";
|
|
||||||
|
|
||||||
std::string username;
|
|
||||||
if (getenv("LOGNAME")) username = getenv("LOGNAME");
|
|
||||||
#if !defined _WIN32 && !defined ADB_HOST_ON_TARGET
|
|
||||||
if (username.empty() && getlogin()) username = getlogin();
|
|
||||||
#endif
|
|
||||||
if (username.empty()) hostname = "unknown";
|
|
||||||
|
|
||||||
return " " + username + "@" + hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool write_public_keyfile(RSA* private_key, const std::string& private_key_path) {
|
|
||||||
LOG(INFO) << "write_public_keyfile...";
|
|
||||||
|
|
||||||
uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
|
uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
|
||||||
if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
|
if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
|
||||||
LOG(ERROR) << "Failed to convert to public key";
|
LOG(ERROR) << "Failed to convert to public key";
|
||||||
|
|
@ -88,20 +66,10 @@ static bool write_public_keyfile(RSA* private_key, const std::string& private_ke
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string content;
|
out->resize(expected_length);
|
||||||
content.resize(expected_length);
|
size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(out->data()), binary_key_data,
|
||||||
size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(&content[0]), binary_key_data,
|
|
||||||
sizeof(binary_key_data));
|
sizeof(binary_key_data));
|
||||||
content.resize(actual_length);
|
out->resize(actual_length);
|
||||||
|
|
||||||
content += get_user_info();
|
|
||||||
|
|
||||||
std::string path(private_key_path + ".pub");
|
|
||||||
if (!android::base::WriteStringToFile(content, path)) {
|
|
||||||
PLOG(ERROR) << "Failed to write public key to '" << path << "'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,11 +108,6 @@ static int generate_key(const std::string& file) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!write_public_keyfile(rsa, file)) {
|
|
||||||
D("Failed to write public key");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
@ -170,36 +133,41 @@ static std::string hash_key(RSA* key) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_key_file(const std::string& file) {
|
static std::shared_ptr<RSA> read_key_file(const std::string& file) {
|
||||||
LOG(INFO) << "read_key_file '" << file << "'...";
|
|
||||||
|
|
||||||
std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(file.c_str(), "r"), fclose);
|
std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(file.c_str(), "r"), fclose);
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
PLOG(ERROR) << "Failed to open '" << file << "'";
|
PLOG(ERROR) << "Failed to open '" << file << "'";
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RSA* key = RSA_new();
|
RSA* key = RSA_new();
|
||||||
if (!PEM_read_RSAPrivateKey(fp.get(), &key, nullptr, nullptr)) {
|
if (!PEM_read_RSAPrivateKey(fp.get(), &key, nullptr, nullptr)) {
|
||||||
LOG(ERROR) << "Failed to read key";
|
LOG(ERROR) << "Failed to read key";
|
||||||
RSA_free(key);
|
RSA_free(key);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::shared_ptr<RSA>(key, RSA_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool load_key(const std::string& file) {
|
||||||
|
std::shared_ptr<RSA> key = read_key_file(file);
|
||||||
|
if (!key) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(g_keys_mutex);
|
std::lock_guard<std::mutex> lock(g_keys_mutex);
|
||||||
std::string fingerprint = hash_key(key);
|
std::string fingerprint = hash_key(key.get());
|
||||||
if (g_keys.find(fingerprint) != g_keys.end()) {
|
if (g_keys.find(fingerprint) != g_keys.end()) {
|
||||||
LOG(INFO) << "ignoring already-loaded key: " << file;
|
LOG(INFO) << "ignoring already-loaded key: " << file;
|
||||||
RSA_free(key);
|
|
||||||
} else {
|
} else {
|
||||||
g_keys[fingerprint] = std::shared_ptr<RSA>(key, RSA_free);
|
g_keys[fingerprint] = std::move(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_keys(const std::string& path, bool allow_dir = true) {
|
static bool load_keys(const std::string& path, bool allow_dir = true) {
|
||||||
LOG(INFO) << "read_keys '" << path << "'...";
|
LOG(INFO) << "load_keys '" << path << "'...";
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path.c_str(), &st) != 0) {
|
if (stat(path.c_str(), &st) != 0) {
|
||||||
|
|
@ -208,7 +176,7 @@ static bool read_keys(const std::string& path, bool allow_dir = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISREG(st.st_mode)) {
|
if (S_ISREG(st.st_mode)) {
|
||||||
return read_key_file(path);
|
return load_key(path);
|
||||||
} else if (S_ISDIR(st.st_mode)) {
|
} else if (S_ISDIR(st.st_mode)) {
|
||||||
if (!allow_dir) {
|
if (!allow_dir) {
|
||||||
// inotify isn't recursive. It would break expectations to load keys in nested
|
// inotify isn't recursive. It would break expectations to load keys in nested
|
||||||
|
|
@ -237,7 +205,7 @@ static bool read_keys(const std::string& path, bool allow_dir = true) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result |= read_key_file((path + OS_PATH_SEPARATOR + name));
|
result |= load_key((path + OS_PATH_SEPARATOR + name));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +218,7 @@ static std::string get_user_key_path() {
|
||||||
return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adbkey";
|
return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adbkey";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_user_key() {
|
static bool generate_userkey() {
|
||||||
std::string path = get_user_key_path();
|
std::string path = get_user_key_path();
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
PLOG(ERROR) << "Error getting user key filename";
|
PLOG(ERROR) << "Error getting user key filename";
|
||||||
|
|
@ -266,7 +234,7 @@ static bool get_user_key() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return read_key_file(path);
|
return load_key(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::set<std::string> get_vendor_keys() {
|
static std::set<std::string> get_vendor_keys() {
|
||||||
|
|
@ -320,26 +288,42 @@ static std::string adb_auth_sign(RSA* key, const char* token, size_t token_size)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pubkey_from_privkey(std::string* out, const std::string& path) {
|
||||||
|
std::shared_ptr<RSA> privkey = read_key_file(path);
|
||||||
|
if (!privkey) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return calculate_public_key(out, privkey.get());
|
||||||
|
}
|
||||||
|
|
||||||
std::string adb_auth_get_userkey() {
|
std::string adb_auth_get_userkey() {
|
||||||
std::string path = get_user_key_path();
|
std::string path = get_user_key_path();
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
PLOG(ERROR) << "Error getting user key filename";
|
PLOG(ERROR) << "Error getting user key filename";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
path += ".pub";
|
|
||||||
|
|
||||||
std::string content;
|
std::string result;
|
||||||
if (!android::base::ReadFileToString(path, &content)) {
|
if (!pubkey_from_privkey(&result, path)) {
|
||||||
PLOG(ERROR) << "Can't load '" << path << "'";
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return content;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int adb_auth_keygen(const char* filename) {
|
int adb_auth_keygen(const char* filename) {
|
||||||
return (generate_key(filename) == 0);
|
return (generate_key(filename) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int adb_auth_pubkey(const char* filename) {
|
||||||
|
std::string pubkey;
|
||||||
|
if (!pubkey_from_privkey(&pubkey, filename)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pubkey.push_back('\n');
|
||||||
|
|
||||||
|
return WriteFdExactly(STDOUT_FILENO, pubkey.data(), pubkey.size()) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
static void adb_auth_inotify_update(int fd, unsigned fd_event, void*) {
|
static void adb_auth_inotify_update(int fd, unsigned fd_event, void*) {
|
||||||
LOG(INFO) << "adb_auth_inotify_update called";
|
LOG(INFO) << "adb_auth_inotify_update called";
|
||||||
|
|
@ -380,7 +364,7 @@ static void adb_auth_inotify_update(int fd, unsigned fd_event, void*) {
|
||||||
LOG(INFO) << "ignoring new directory at '" << path << "'";
|
LOG(INFO) << "ignoring new directory at '" << path << "'";
|
||||||
} else {
|
} else {
|
||||||
LOG(INFO) << "observed new file at '" << path << "'";
|
LOG(INFO) << "observed new file at '" << path << "'";
|
||||||
read_keys(path, false);
|
load_keys(path, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(WARNING) << "unmonitored event for " << path << ": 0x" << std::hex
|
LOG(WARNING) << "unmonitored event for " << path << ": 0x" << std::hex
|
||||||
|
|
@ -420,8 +404,8 @@ static void adb_auth_inotify_init(const std::set<std::string>& paths) {
|
||||||
void adb_auth_init() {
|
void adb_auth_init() {
|
||||||
LOG(INFO) << "adb_auth_init...";
|
LOG(INFO) << "adb_auth_init...";
|
||||||
|
|
||||||
if (!get_user_key()) {
|
if (!generate_userkey()) {
|
||||||
LOG(ERROR) << "Failed to get user key";
|
LOG(ERROR) << "Failed to generate user key";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -432,7 +416,7 @@ void adb_auth_init() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (const std::string& path : key_paths) {
|
for (const std::string& path : key_paths) {
|
||||||
read_keys(path.c_str());
|
load_keys(path.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,6 @@ static void help() {
|
||||||
" enable-verity re-enable dm-verity checking on userdebug builds\n"
|
" enable-verity re-enable dm-verity checking on userdebug builds\n"
|
||||||
" keygen FILE\n"
|
" keygen FILE\n"
|
||||||
" generate adb public/private key; private key stored in FILE,\n"
|
" generate adb public/private key; private key stored in FILE,\n"
|
||||||
" public key stored in FILE.pub (existing files overwritten)\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"scripting:\n"
|
"scripting:\n"
|
||||||
" wait-for[-TRANSPORT]-STATE\n"
|
" wait-for[-TRANSPORT]-STATE\n"
|
||||||
|
|
@ -1756,14 +1755,14 @@ int adb_commandline(int argc, const char** argv) {
|
||||||
// Always print key generation information for keygen command.
|
// Always print key generation information for keygen command.
|
||||||
adb_trace_enable(AUTH);
|
adb_trace_enable(AUTH);
|
||||||
return adb_auth_keygen(argv[1]);
|
return adb_auth_keygen(argv[1]);
|
||||||
}
|
} else if (!strcmp(argv[0], "pubkey")) {
|
||||||
else if (!strcmp(argv[0], "jdwp")) {
|
if (argc != 2) error_exit("pubkey requires an argument");
|
||||||
|
return adb_auth_pubkey(argv[1]);
|
||||||
|
} else if (!strcmp(argv[0], "jdwp")) {
|
||||||
return adb_connect_command("jdwp");
|
return adb_connect_command("jdwp");
|
||||||
}
|
} else if (!strcmp(argv[0], "track-jdwp")) {
|
||||||
else if (!strcmp(argv[0], "track-jdwp")) {
|
|
||||||
return adb_connect_command("track-jdwp");
|
return adb_connect_command("track-jdwp");
|
||||||
}
|
} else if (!strcmp(argv[0], "track-devices")) {
|
||||||
else if (!strcmp(argv[0], "track-devices")) {
|
|
||||||
return adb_connect_command("host:track-devices");
|
return adb_connect_command("host:track-devices");
|
||||||
} else if (!strcmp(argv[0], "raw")) {
|
} else if (!strcmp(argv[0], "raw")) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
|
|
@ -1772,13 +1771,11 @@ int adb_commandline(int argc, const char** argv) {
|
||||||
return adb_connect_command(argv[1]);
|
return adb_connect_command(argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* "adb /?" is a common idiom under Windows */
|
/* "adb /?" is a common idiom under Windows */
|
||||||
else if (!strcmp(argv[0], "--help") || !strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
|
else if (!strcmp(argv[0], "--help") || !strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
|
||||||
help();
|
help();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (!strcmp(argv[0], "--version") || !strcmp(argv[0], "version")) {
|
||||||
else if (!strcmp(argv[0], "--version") || !strcmp(argv[0], "version")) {
|
|
||||||
fprintf(stdout, "%s", adb_version().c_str());
|
fprintf(stdout, "%s", adb_version().c_str());
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!strcmp(argv[0], "features")) {
|
} else if (!strcmp(argv[0], "features")) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue