[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
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index 8f154fd..273a0e6 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -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 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 @@
}
}
- 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)
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index 3333fc6..0645122 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -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 @@
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
+}
+
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 89fcd66..cf42067 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -31,6 +31,12 @@
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);
diff --git a/adb/console.cpp b/adb/console.cpp
index 15c6abd..e9b90a5 100644
--- a/adb/console.cpp
+++ b/adb/console.cpp
@@ -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 @@
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");