Introduce "adb keygen"

Introduce the "adb keygen" command.

  Usage: adb keygen <filename>

This command creates an adb public/private key pair in a user
specified file. This can be used to create new adb keys, or rotate
existing keys.

Modify adb's key generation routines to use the HOSTNAME/LOGNAME
environment variables if available. This allows someone to override
the username/hostname embedded within the adb public key file if
desired. Fallback to the old mechanisms if those environment
variables aren't available.

Bug: 18342715
Change-Id: Ibccee6088d4609aa05ad6687d3a1d8a8689d3e8a

(cherry picked from commit a85094151253845648ee005325dcd0a254270253)

Change-Id: Ic76ffc9412171dddc879af0bbf6e20fbe1a8f057
diff --git a/adb_auth.h b/adb_auth.h
index b24c674..54dd537 100644
--- a/adb_auth.h
+++ b/adb_auth.h
@@ -18,6 +18,7 @@
 #define __ADB_AUTH_H
 
 void adb_auth_init(void);
+int adb_auth_keygen(const char* filename);
 void adb_auth_verified(atransport *t);
 
 void send_auth_request(atransport *t);
diff --git a/adb_auth_host.c b/adb_auth_host.c
index c72fe42..4c33d14 100644
--- a/adb_auth_host.c
+++ b/adb_auth_host.c
@@ -114,18 +114,34 @@
 static void get_user_info(char *buf, size_t len)
 {
     char hostname[1024], username[1024];
-    int ret;
+    int ret = -1;
+
+    if (getenv("HOSTNAME") != NULL) {
+        strncpy(hostname, getenv("HOSTNAME"), sizeof(hostname));
+        hostname[sizeof(hostname)-1] = '\0';
+        ret = 0;
+    }
 
 #ifndef _WIN32
-    ret = gethostname(hostname, sizeof(hostname));
     if (ret < 0)
+        ret = gethostname(hostname, sizeof(hostname));
 #endif
+    if (ret < 0)
         strcpy(hostname, "unknown");
 
+    ret = -1;
+
+    if (getenv("LOGNAME") != NULL) {
+        strncpy(username, getenv("LOGNAME"), sizeof(username));
+        username[sizeof(username)-1] = '\0';
+        ret = 0;
+    }
+
 #if !defined _WIN32 && !defined ADB_HOST_ON_TARGET
-    ret = getlogin_r(username, sizeof(username));
     if (ret < 0)
+        ret = getlogin_r(username, sizeof(username));
 #endif
+    if (ret < 0)
         strcpy(username, "unknown");
 
     ret = snprintf(buf, len, " %s@%s", username, hostname);
@@ -436,6 +452,11 @@
     return ret + 1;
 }
 
+int adb_auth_keygen(const char* filename) {
+    adb_trace_mask |= (1 << TRACE_AUTH);
+    return (generate_key(filename) == 0);
+}
+
 void adb_auth_init(void)
 {
     int ret;
diff --git a/commandline.c b/commandline.c
index 23e9ea4..aa97eb4 100644
--- a/commandline.c
+++ b/commandline.c
@@ -36,6 +36,7 @@
 #define  TRACE_TAG  TRACE_ADB
 #include "adb.h"
 #include "adb_client.h"
+#include "adb_auth.h"
 #include "file_sync_service.h"
 
 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
@@ -189,6 +190,9 @@
         "\n"
         "  adb restore <file>           - restore device contents from the <file> backup archive\n"
         "\n"
+        "  adb keygen <file>            - generate adb public/private key. The private key is stored in <file>,\n"
+        "                                 and the public key is stored in <file>.pub. Any existing files\n"
+        "                                 are overwritten.\n"
         "  adb help                     - show this help message\n"
         "  adb version                  - show version num\n"
         "\n"
@@ -1725,6 +1729,11 @@
         return restore(argc, argv);
     }
 
+    if (!strcmp(argv[0], "keygen")) {
+        if (argc < 2) return usage();
+        return adb_auth_keygen(argv[1]);
+    }
+
     if (!strcmp(argv[0], "jdwp")) {
         int  fd = adb_connect("jdwp");
         if (fd >= 0) {