[adb] Issue the "auth" emulator command before any other one

Emulator console now requires authentication; this means
'adb emu ...' commands silently fail because of it.
This CL adds an 'auth <token>' command to each user command,
making sure it won't be silently ignored.

Bug: https://code.google.com/p/android/issues/detail?id=211233
Change-Id: Id9ca4999fd2e6393cc88278eaf444243e13c0ec0
This commit is contained in:
Yurii Zubrytskyi 2016-05-25 15:17:10 -07:00
parent 1265fd4934
commit a9e2b99a7f
4 changed files with 77 additions and 36 deletions

View file

@ -18,18 +18,13 @@
#include "sysdeps.h"
#include "adb_auth.h"
#include "adb_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include "windows.h"
# include "shlobj.h"
#else
#ifndef _WIN32
# include <sys/types.h>
# include <sys/stat.h>
# include <unistd.h>
@ -298,36 +293,14 @@ static int read_key(const char *file, struct listnode *list)
static int get_user_keyfilepath(char *filename, size_t len)
{
const char *format, *home;
char android_dir[PATH_MAX];
struct stat buf;
#ifdef _WIN32
std::string home_str;
home = getenv("ANDROID_SDK_HOME");
if (!home) {
WCHAR path[MAX_PATH];
const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path);
if (FAILED(hr)) {
D("SHGetFolderPathW failed: %s", android::base::SystemErrorCodeToString(hr).c_str());
return -1;
}
if (!android::base::WideToUTF8(path, &home_str)) {
return -1;
}
home = home_str.c_str();
}
format = "%s\\%s";
#else
home = getenv("HOME");
if (!home)
return -1;
format = "%s/%s";
#endif
D("home '%s'", home);
std::string home = adb_get_homedir_path(true);
D("home '%s'", home.c_str());
if (snprintf(android_dir, sizeof(android_dir), format, home,
ANDROID_PATH) >= (int)sizeof(android_dir))
if (snprintf(android_dir, sizeof(android_dir), "%s%c%s", home.c_str(),
OS_PATH_SEPARATOR, ANDROID_PATH) >= (int)sizeof(android_dir))
return -1;
if (stat(android_dir, &buf)) {
@ -337,7 +310,8 @@ static int get_user_keyfilepath(char *filename, size_t len)
}
}
return snprintf(filename, len, format, android_dir, ADB_KEY_FILE);
return snprintf(filename, len, "%s%c%s", android_dir, OS_PATH_SEPARATOR,
ADB_KEY_FILE);
}
static int get_user_key(struct listnode *list)

View file

@ -34,6 +34,14 @@
#include "adb_trace.h"
#include "sysdeps.h"
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include "windows.h"
# include "shlobj.h"
#endif
ADB_MUTEX_DEFINE(basename_lock);
ADB_MUTEX_DEFINE(dirname_lock);
@ -230,3 +238,31 @@ bool set_file_block_mode(int fd, bool block) {
return true;
}
#endif
std::string adb_get_homedir_path(bool check_env_first) {
#ifdef _WIN32
if (check_env_first) {
if (const char* const home = getenv("ANDROID_SDK_HOME")) {
return home;
}
}
WCHAR path[MAX_PATH];
const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path);
if (FAILED(hr)) {
D("SHGetFolderPathW failed: %s", android::base::SystemErrorCodeToString(hr).c_str());
return {};
}
std::string home_str;
if (!android::base::WideToUTF8(path, &home_str)) {
return {};
}
return home_str;
#else
if (const char* const home = getenv("HOME")) {
return home;
}
return {};
#endif
}

View file

@ -31,6 +31,12 @@ bool directory_exists(const std::string& path);
std::string adb_basename(const std::string& path);
std::string adb_dirname(const std::string& path);
// Return the user's home directory.
// |check_env_first| - if true, on Windows check the ANDROID_SDK_HOME
// environment variable before trying the WinAPI call (useful when looking for
// the .android directory)
std::string adb_get_homedir_path(bool check_env_first);
bool mkdirs(const std::string& path);
std::string escape_arg(const std::string& s);

View file

@ -26,6 +26,31 @@
#include "adb.h"
#include "adb_client.h"
#include "adb_io.h"
#include "adb_utils.h"
// Return the console authentication command for the emulator, if needed
static std::string adb_construct_auth_command() {
static const char auth_token_filename[] = ".emulator_console_auth_token";
std::string auth_token_path = adb_get_homedir_path(false);
auth_token_path += OS_PATH_SEPARATOR;
auth_token_path += auth_token_filename;
// read the token
std::string token;
if (!android::base::ReadFileToString(auth_token_path, &token)
|| token.empty()) {
// we either can't read the file, or it doesn't exist, or it's empty -
// either way we won't add any authentication command.
return {};
}
// now construct and return the actual command: "auth <token>\n"
std::string command = "auth ";
command += token;
command += '\n';
return command;
}
// Return the console port of the currently connected emulator (if any) or -1 if
// there is no emulator, and -2 if there is more than one.
@ -88,11 +113,11 @@ int adb_send_emulator_command(int argc, const char** argv, const char* serial) {
return 1;
}
std::string commands;
std::string commands = adb_construct_auth_command();
for (int i = 1; i < argc; i++) {
commands.append(argv[i]);
commands.append(i == argc - 1 ? "\n" : " ");
commands.push_back(i == argc - 1 ? '\n' : ' ');
}
commands.append("quit\n");