Merge "adb: split up adb_auth.cpp."
am: 4a8b178c97
Change-Id: I846a06ca04aad456c6659dd6db4c8d0666fc6707
This commit is contained in:
commit
4546c8ac3d
8 changed files with 124 additions and 141 deletions
|
|
@ -45,7 +45,6 @@ ADB_COMMON_windows_CFLAGS := \
|
||||||
# get enough of adb in here that we no longer need minadb. https://b/17626262
|
# get enough of adb in here that we no longer need minadb. https://b/17626262
|
||||||
LIBADB_SRC_FILES := \
|
LIBADB_SRC_FILES := \
|
||||||
adb.cpp \
|
adb.cpp \
|
||||||
adb_auth.cpp \
|
|
||||||
adb_io.cpp \
|
adb_io.cpp \
|
||||||
adb_listeners.cpp \
|
adb_listeners.cpp \
|
||||||
adb_trace.cpp \
|
adb_trace.cpp \
|
||||||
|
|
@ -103,7 +102,7 @@ LOCAL_MODULE := libadbd
|
||||||
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0
|
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
$(LIBADB_SRC_FILES) \
|
$(LIBADB_SRC_FILES) \
|
||||||
adb_auth_client.cpp \
|
adbd_auth.cpp \
|
||||||
jdwp_service.cpp \
|
jdwp_service.cpp \
|
||||||
usb_linux_client.cpp \
|
usb_linux_client.cpp \
|
||||||
|
|
||||||
|
|
|
||||||
38
adb/adb.cpp
38
adb/adb.cpp
|
|
@ -351,19 +351,31 @@ void handle_packet(apacket *p, atransport *t)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case A_AUTH:
|
case A_AUTH:
|
||||||
if (p->msg.arg0 == ADB_AUTH_TOKEN) {
|
switch (p->msg.arg0) {
|
||||||
t->connection_state = kCsUnauthorized;
|
#if ADB_HOST
|
||||||
send_auth_response(p->data, p->msg.data_length, t);
|
case ADB_AUTH_TOKEN:
|
||||||
} else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
|
t->connection_state = kCsUnauthorized;
|
||||||
if (adb_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
|
send_auth_response(p->data, p->msg.data_length, t);
|
||||||
adb_auth_verified(t);
|
break;
|
||||||
t->failed_auth_attempts = 0;
|
#else
|
||||||
} else {
|
case ADB_AUTH_SIGNATURE:
|
||||||
if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
|
if (adbd_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
|
||||||
send_auth_request(t);
|
adbd_auth_verified(t);
|
||||||
}
|
t->failed_auth_attempts = 0;
|
||||||
} else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
|
} else {
|
||||||
adb_auth_confirm_key(p->data, p->msg.data_length, t);
|
if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
|
||||||
|
send_auth_request(t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ADB_AUTH_RSAPUBLICKEY:
|
||||||
|
adbd_auth_confirm_key(p->data, p->msg.data_length, t);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
t->connection_state = kCsOffline;
|
||||||
|
handle_offline(t);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
101
adb/adb_auth.cpp
101
adb/adb_auth.cpp
|
|
@ -1,101 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2015 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 TRACE_TAG ADB
|
|
||||||
|
|
||||||
#include "adb.h"
|
|
||||||
#include "adb_auth.h"
|
|
||||||
#include "transport.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
bool auth_required = true;
|
|
||||||
|
|
||||||
void send_auth_request(atransport *t)
|
|
||||||
{
|
|
||||||
LOG(INFO) << "Calling send_auth_request...";
|
|
||||||
|
|
||||||
if (!adb_auth_generate_token(t->token, sizeof(t->token))) {
|
|
||||||
PLOG(ERROR) << "Error generating token";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
apacket* p = get_apacket();
|
|
||||||
memcpy(p->data, t->token, sizeof(t->token));
|
|
||||||
p->msg.command = A_AUTH;
|
|
||||||
p->msg.arg0 = ADB_AUTH_TOKEN;
|
|
||||||
p->msg.data_length = sizeof(t->token);
|
|
||||||
send_packet(p, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_auth_publickey(atransport* t) {
|
|
||||||
LOG(INFO) << "Calling send_auth_publickey";
|
|
||||||
|
|
||||||
std::string key = adb_auth_get_userkey();
|
|
||||||
if (key.empty()) {
|
|
||||||
D("Failed to get user public key");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.size() >= MAX_PAYLOAD_V1) {
|
|
||||||
D("User public key too large (%zu B)", key.size());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
apacket* p = get_apacket();
|
|
||||||
memcpy(p->data, key.c_str(), key.size() + 1);
|
|
||||||
|
|
||||||
p->msg.command = A_AUTH;
|
|
||||||
p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
|
|
||||||
|
|
||||||
// adbd expects a null-terminated string.
|
|
||||||
p->msg.data_length = key.size() + 1;
|
|
||||||
send_packet(p, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_auth_response(uint8_t* token, size_t token_size, atransport* t) {
|
|
||||||
std::shared_ptr<RSA> key = t->NextKey();
|
|
||||||
if (key == nullptr) {
|
|
||||||
// No more private keys to try, send the public key.
|
|
||||||
send_auth_publickey(t);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(INFO) << "Calling send_auth_response";
|
|
||||||
apacket* p = get_apacket();
|
|
||||||
|
|
||||||
int ret = adb_auth_sign(key.get(), token, token_size, p->data);
|
|
||||||
if (!ret) {
|
|
||||||
D("Error signing the token");
|
|
||||||
put_apacket(p);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->msg.command = A_AUTH;
|
|
||||||
p->msg.arg0 = ADB_AUTH_SIGNATURE;
|
|
||||||
p->msg.data_length = ret;
|
|
||||||
send_packet(p, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void adb_auth_verified(atransport *t)
|
|
||||||
{
|
|
||||||
handle_online(t);
|
|
||||||
send_connect(t);
|
|
||||||
}
|
|
||||||
|
|
@ -24,14 +24,6 @@
|
||||||
|
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
extern bool auth_required;
|
|
||||||
|
|
||||||
int adb_auth_keygen(const char* filename);
|
|
||||||
void adb_auth_verified(atransport *t);
|
|
||||||
|
|
||||||
void send_auth_request(atransport *t);
|
|
||||||
void send_auth_response(uint8_t *token, size_t token_size, atransport *t);
|
|
||||||
|
|
||||||
/* AUTH packets first argument */
|
/* AUTH packets first argument */
|
||||||
/* Request */
|
/* Request */
|
||||||
#define ADB_AUTH_TOKEN 1
|
#define ADB_AUTH_TOKEN 1
|
||||||
|
|
@ -42,25 +34,26 @@ void send_auth_response(uint8_t *token, size_t token_size, atransport *t);
|
||||||
#if ADB_HOST
|
#if ADB_HOST
|
||||||
|
|
||||||
void adb_auth_init();
|
void adb_auth_init();
|
||||||
|
|
||||||
|
int adb_auth_keygen(const char* filename);
|
||||||
int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig);
|
int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig);
|
||||||
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();
|
||||||
|
|
||||||
static inline bool adb_auth_generate_token(void*, size_t) { abort(); }
|
void send_auth_response(uint8_t *token, size_t token_size, atransport *t);
|
||||||
static inline bool adb_auth_verify(void*, size_t, void*, int) { abort(); }
|
|
||||||
static inline void adb_auth_confirm_key(unsigned char*, size_t, atransport*) { abort(); }
|
|
||||||
|
|
||||||
#else // !ADB_HOST
|
#else // !ADB_HOST
|
||||||
|
|
||||||
static inline int adb_auth_sign(void*, const unsigned char*, size_t, unsigned char*) { abort(); }
|
extern bool auth_required;
|
||||||
static inline std::string adb_auth_get_userkey() { abort(); }
|
|
||||||
static inline std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys() { abort(); }
|
|
||||||
|
|
||||||
void adbd_auth_init(void);
|
void adbd_auth_init(void);
|
||||||
|
void adbd_auth_verified(atransport *t);
|
||||||
|
|
||||||
void adbd_cloexec_auth_socket();
|
void adbd_cloexec_auth_socket();
|
||||||
bool adb_auth_generate_token(void* token, size_t token_size);
|
bool adbd_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len);
|
||||||
bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len);
|
void adbd_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
|
||||||
void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
|
|
||||||
|
void send_auth_request(atransport *t);
|
||||||
|
|
||||||
#endif // ADB_HOST
|
#endif // ADB_HOST
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
#include "adb_auth.h"
|
#include "adb_auth.h"
|
||||||
#include "adb_utils.h"
|
#include "adb_utils.h"
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
static std::mutex& g_keys_mutex = *new std::mutex;
|
static std::mutex& g_keys_mutex = *new std::mutex;
|
||||||
static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
|
static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
|
||||||
|
|
@ -421,3 +422,52 @@ void adb_auth_init() {
|
||||||
read_keys(path.c_str());
|
read_keys(path.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void send_auth_publickey(atransport* t) {
|
||||||
|
LOG(INFO) << "Calling send_auth_publickey";
|
||||||
|
|
||||||
|
std::string key = adb_auth_get_userkey();
|
||||||
|
if (key.empty()) {
|
||||||
|
D("Failed to get user public key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.size() >= MAX_PAYLOAD_V1) {
|
||||||
|
D("User public key too large (%zu B)", key.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
apacket* p = get_apacket();
|
||||||
|
memcpy(p->data, key.c_str(), key.size() + 1);
|
||||||
|
|
||||||
|
p->msg.command = A_AUTH;
|
||||||
|
p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
|
||||||
|
|
||||||
|
// adbd expects a null-terminated string.
|
||||||
|
p->msg.data_length = key.size() + 1;
|
||||||
|
send_packet(p, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_auth_response(uint8_t* token, size_t token_size, atransport* t) {
|
||||||
|
std::shared_ptr<RSA> key = t->NextKey();
|
||||||
|
if (key == nullptr) {
|
||||||
|
// No more private keys to try, send the public key.
|
||||||
|
send_auth_publickey(t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Calling send_auth_response";
|
||||||
|
apacket* p = get_apacket();
|
||||||
|
|
||||||
|
int ret = adb_auth_sign(key.get(), token, token_size, p->data);
|
||||||
|
if (!ret) {
|
||||||
|
D("Error signing the token");
|
||||||
|
put_apacket(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->msg.command = A_AUTH;
|
||||||
|
p->msg.arg0 = ADB_AUTH_SIGNATURE;
|
||||||
|
p->msg.data_length = ret;
|
||||||
|
send_packet(p, t);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,9 @@ static struct adisconnect usb_disconnect = { usb_disconnected, nullptr};
|
||||||
static atransport* usb_transport;
|
static atransport* usb_transport;
|
||||||
static bool needs_retry = false;
|
static bool needs_retry = false;
|
||||||
|
|
||||||
bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len) {
|
bool auth_required = true;
|
||||||
|
|
||||||
|
bool adbd_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len) {
|
||||||
static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
|
static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
|
||||||
|
|
||||||
for (const auto& path : key_paths) {
|
for (const auto& path : key_paths) {
|
||||||
|
|
@ -85,7 +87,7 @@ bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_le
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool adb_auth_generate_token(void* token, size_t token_size) {
|
static bool adbd_auth_generate_token(void* token, size_t token_size) {
|
||||||
FILE* fp = fopen("/dev/urandom", "re");
|
FILE* fp = fopen("/dev/urandom", "re");
|
||||||
if (!fp) return false;
|
if (!fp) return false;
|
||||||
bool okay = (fread(token, token_size, 1, fp) == 1);
|
bool okay = (fread(token, token_size, 1, fp) == 1);
|
||||||
|
|
@ -105,7 +107,7 @@ static void framework_disconnected() {
|
||||||
framework_fd = -1;
|
framework_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adb_auth_event(int fd, unsigned events, void*) {
|
static void adbd_auth_event(int fd, unsigned events, void*) {
|
||||||
if (events & FDE_READ) {
|
if (events & FDE_READ) {
|
||||||
char response[2];
|
char response[2];
|
||||||
int ret = unix_read(fd, response, sizeof(response));
|
int ret = unix_read(fd, response, sizeof(response));
|
||||||
|
|
@ -113,13 +115,13 @@ static void adb_auth_event(int fd, unsigned events, void*) {
|
||||||
framework_disconnected();
|
framework_disconnected();
|
||||||
} else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
|
} else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
|
||||||
if (usb_transport) {
|
if (usb_transport) {
|
||||||
adb_auth_verified(usb_transport);
|
adbd_auth_verified(usb_transport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void adb_auth_confirm_key(unsigned char* key, size_t len, atransport* t) {
|
void adbd_auth_confirm_key(unsigned char* key, size_t len, atransport* t) {
|
||||||
if (!usb_transport) {
|
if (!usb_transport) {
|
||||||
usb_transport = t;
|
usb_transport = t;
|
||||||
t->AddDisconnect(&usb_disconnect);
|
t->AddDisconnect(&usb_disconnect);
|
||||||
|
|
@ -150,7 +152,7 @@ void adb_auth_confirm_key(unsigned char* key, size_t len, atransport* t) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adb_auth_listener(int fd, unsigned events, void* data) {
|
static void adbd_auth_listener(int fd, unsigned events, void* data) {
|
||||||
int s = adb_socket_accept(fd, nullptr, nullptr);
|
int s = adb_socket_accept(fd, nullptr, nullptr);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
PLOG(ERROR) << "Failed to accept";
|
PLOG(ERROR) << "Failed to accept";
|
||||||
|
|
@ -163,7 +165,7 @@ static void adb_auth_listener(int fd, unsigned events, void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
framework_fd = s;
|
framework_fd = s;
|
||||||
fdevent_install(&framework_fde, framework_fd, adb_auth_event, nullptr);
|
fdevent_install(&framework_fde, framework_fd, adbd_auth_event, nullptr);
|
||||||
fdevent_add(&framework_fde, FDE_READ);
|
fdevent_add(&framework_fde, FDE_READ);
|
||||||
|
|
||||||
if (needs_retry) {
|
if (needs_retry) {
|
||||||
|
|
@ -193,6 +195,28 @@ void adbd_auth_init(void) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fdevent_install(&listener_fde, fd, adb_auth_listener, NULL);
|
fdevent_install(&listener_fde, fd, adbd_auth_listener, NULL);
|
||||||
fdevent_add(&listener_fde, FDE_READ);
|
fdevent_add(&listener_fde, FDE_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_auth_request(atransport* t) {
|
||||||
|
LOG(INFO) << "Calling send_auth_request...";
|
||||||
|
|
||||||
|
if (!adbd_auth_generate_token(t->token, sizeof(t->token))) {
|
||||||
|
PLOG(ERROR) << "Error generating token";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
apacket* p = get_apacket();
|
||||||
|
memcpy(p->data, t->token, sizeof(t->token));
|
||||||
|
p->msg.command = A_AUTH;
|
||||||
|
p->msg.arg0 = ADB_AUTH_TOKEN;
|
||||||
|
p->msg.data_length = sizeof(t->token);
|
||||||
|
send_packet(p, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void adbd_auth_verified(atransport *t)
|
||||||
|
{
|
||||||
|
handle_online(t);
|
||||||
|
send_connect(t);
|
||||||
|
}
|
||||||
|
|
@ -1071,6 +1071,7 @@ int check_data(apacket *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ADB_HOST
|
||||||
std::shared_ptr<RSA> atransport::NextKey() {
|
std::shared_ptr<RSA> atransport::NextKey() {
|
||||||
if (keys_.empty()) keys_ = adb_auth_get_private_keys();
|
if (keys_.empty()) keys_ = adb_auth_get_private_keys();
|
||||||
|
|
||||||
|
|
@ -1078,3 +1079,4 @@ std::shared_ptr<RSA> atransport::NextKey() {
|
||||||
keys_.pop_front();
|
keys_.pop_front();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,9 @@ public:
|
||||||
return type == kTransportLocal && local_port_for_emulator_ == -1;
|
return type == kTransportLocal && local_port_for_emulator_ == -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ADB_HOST
|
||||||
std::shared_ptr<RSA> NextKey();
|
std::shared_ptr<RSA> NextKey();
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char token[TOKEN_SIZE] = {};
|
unsigned char token[TOKEN_SIZE] = {};
|
||||||
size_t failed_auth_attempts = 0;
|
size_t failed_auth_attempts = 0;
|
||||||
|
|
@ -161,7 +163,9 @@ private:
|
||||||
// A list of adisconnect callbacks called when the transport is kicked.
|
// A list of adisconnect callbacks called when the transport is kicked.
|
||||||
std::list<adisconnect*> disconnects_;
|
std::list<adisconnect*> disconnects_;
|
||||||
|
|
||||||
|
#if ADB_HOST
|
||||||
std::deque<std::shared_ptr<RSA>> keys_;
|
std::deque<std::shared_ptr<RSA>> keys_;
|
||||||
|
#endif
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(atransport);
|
DISALLOW_COPY_AND_ASSIGN(atransport);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue