diff --git a/adb/Android.mk b/adb/Android.mk index 9466beeb2..e17240bad 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -45,7 +45,6 @@ ADB_COMMON_windows_CFLAGS := \ # get enough of adb in here that we no longer need minadb. https://b/17626262 LIBADB_SRC_FILES := \ adb.cpp \ - adb_auth.cpp \ adb_io.cpp \ adb_listeners.cpp \ adb_trace.cpp \ @@ -103,7 +102,7 @@ LOCAL_MODULE := libadbd LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0 LOCAL_SRC_FILES := \ $(LIBADB_SRC_FILES) \ - adb_auth_client.cpp \ + adbd_auth.cpp \ jdwp_service.cpp \ usb_linux_client.cpp \ diff --git a/adb/adb.cpp b/adb/adb.cpp index 9ae3f1c26..89a20f0e4 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -351,19 +351,31 @@ void handle_packet(apacket *p, atransport *t) break; case A_AUTH: - if (p->msg.arg0 == ADB_AUTH_TOKEN) { - t->connection_state = kCsUnauthorized; - send_auth_response(p->data, p->msg.data_length, t); - } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) { - if (adb_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) { - adb_auth_verified(t); - t->failed_auth_attempts = 0; - } else { - if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000); - send_auth_request(t); - } - } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) { - adb_auth_confirm_key(p->data, p->msg.data_length, t); + switch (p->msg.arg0) { +#if ADB_HOST + case ADB_AUTH_TOKEN: + t->connection_state = kCsUnauthorized; + send_auth_response(p->data, p->msg.data_length, t); + break; +#else + case ADB_AUTH_SIGNATURE: + if (adbd_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) { + adbd_auth_verified(t); + t->failed_auth_attempts = 0; + } else { + 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; diff --git a/adb/adb_auth.cpp b/adb/adb_auth.cpp deleted file mode 100644 index 0b07158eb..000000000 --- a/adb/adb_auth.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include - -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 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); -} diff --git a/adb/adb_auth.h b/adb/adb_auth.h index 59b80d8fe..4db83a440 100644 --- a/adb/adb_auth.h +++ b/adb/adb_auth.h @@ -24,14 +24,6 @@ #include -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 */ /* Request */ #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 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); std::string adb_auth_get_userkey(); std::deque> adb_auth_get_private_keys(); -static inline bool adb_auth_generate_token(void*, size_t) { abort(); } -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(); } +void send_auth_response(uint8_t *token, size_t token_size, atransport *t); #else // !ADB_HOST -static inline int adb_auth_sign(void*, const unsigned char*, size_t, unsigned char*) { abort(); } -static inline std::string adb_auth_get_userkey() { abort(); } -static inline std::deque> adb_auth_get_private_keys() { abort(); } +extern bool auth_required; void adbd_auth_init(void); +void adbd_auth_verified(atransport *t); + void adbd_cloexec_auth_socket(); -bool adb_auth_generate_token(void* token, size_t token_size); -bool adb_auth_verify(uint8_t* token, size_t token_size, uint8_t* sig, int sig_len); -void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t); +bool adbd_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 send_auth_request(atransport *t); #endif // ADB_HOST diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp index 072c7f57d..b5b9b979d 100644 --- a/adb/adb_auth_host.cpp +++ b/adb/adb_auth_host.cpp @@ -45,6 +45,7 @@ #include "adb_auth.h" #include "adb_utils.h" #include "sysdeps.h" +#include "transport.h" static std::mutex& g_keys_mutex = *new std::mutex; static std::map>& g_keys = @@ -421,3 +422,52 @@ void adb_auth_init() { 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 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); +} diff --git a/adb/adb_auth_client.cpp b/adb/adbd_auth.cpp similarity index 83% rename from adb/adb_auth_client.cpp rename to adb/adbd_auth.cpp index 84ad6efae..fa76c8daf 100644 --- a/adb/adb_auth_client.cpp +++ b/adb/adbd_auth.cpp @@ -44,7 +44,9 @@ static struct adisconnect usb_disconnect = { usb_disconnected, nullptr}; static atransport* usb_transport; 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 }; 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; } -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"); if (!fp) return false; bool okay = (fread(token, token_size, 1, fp) == 1); @@ -105,7 +107,7 @@ static void framework_disconnected() { 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) { char response[2]; int ret = unix_read(fd, response, sizeof(response)); @@ -113,13 +115,13 @@ static void adb_auth_event(int fd, unsigned events, void*) { framework_disconnected(); } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { 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) { usb_transport = t; 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); if (s < 0) { PLOG(ERROR) << "Failed to accept"; @@ -163,7 +165,7 @@ static void adb_auth_listener(int fd, unsigned events, void* data) { } 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); if (needs_retry) { @@ -193,6 +195,28 @@ void adbd_auth_init(void) { 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); } + +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); +} diff --git a/adb/transport.cpp b/adb/transport.cpp index 87712fc46..98809025f 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -1071,6 +1071,7 @@ int check_data(apacket *p) } } +#if ADB_HOST std::shared_ptr atransport::NextKey() { if (keys_.empty()) keys_ = adb_auth_get_private_keys(); @@ -1078,3 +1079,4 @@ std::shared_ptr atransport::NextKey() { keys_.pop_front(); return result; } +#endif diff --git a/adb/transport.h b/adb/transport.h index 959681ff6..aaa8be438 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -108,7 +108,9 @@ public: return type == kTransportLocal && local_port_for_emulator_ == -1; } +#if ADB_HOST std::shared_ptr NextKey(); +#endif unsigned char token[TOKEN_SIZE] = {}; size_t failed_auth_attempts = 0; @@ -161,7 +163,9 @@ private: // A list of adisconnect callbacks called when the transport is kicked. std::list disconnects_; +#if ADB_HOST std::deque> keys_; +#endif DISALLOW_COPY_AND_ASSIGN(atransport); };