Support HTTP authentication using user input as fallback

If repo could not find authentication credentials from ~/.netrc, this
patch tries to get user and password from user's console input. This
could be a good choice if user doesn't want to save his plain password
in ~/.netrc or if user doesn't know about the netrc usage.

The user will be prompted only if authentication infomation does not
exist in the password manager. Since main.py firstly loads auth
infomation from ~/.netrc, this will be executed only as fallback
mechanism.

Example:
$ repo upload .
Upload project xxx/ to remote branch master:
 branch yyy ( 1 commit, ...):
 to https://review.zzz.com/gerrit/ (y/N)? y

(repo may try to access to https://review.zzz.com/gerrit/ssh_info and
will get the 401 HTTP Basic Authentication response from server. If no
authentication info in ~/.netrc, This patch will ask username/passwd)

Authorization Required (Message from Web Server)
User: pororo
Password:
....
[OK ] xxx/

Change-Id: Ia348a4609ac40060d9093c7dc8d7c2560020455a
diff --git a/main.py b/main.py
index 665a655..34dd27d 100755
--- a/main.py
+++ b/main.py
@@ -22,6 +22,7 @@
     del sys.argv[-1]
 del magic
 
+import getpass
 import netrc
 import optparse
 import os
@@ -276,7 +277,25 @@
     req.add_header('User-Agent', _UserAgent())
     return req
 
+def _AddPasswordFromUserInput(handler, msg, req):
+    # If repo could not find auth info from netrc, try to get it from user input
+    url = req.get_full_url()
+    user, password = handler.passwd.find_user_password(None, url)
+    if user is None:
+      print msg
+      try:
+        user = raw_input('User: ')
+        password = getpass.getpass()
+      except KeyboardInterrupt:
+        return
+      handler.passwd.add_password(None, url, user, password)
+
 class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler):
+  def http_error_401(self, req, fp, code, msg, headers):
+    _AddPasswordFromUserInput(self, msg, req)
+    return urllib2.HTTPBasicAuthHandler.http_error_401(
+      self, req, fp, code, msg, headers)
+
   def http_error_auth_reqed(self, authreq, host, req, headers):
     try:
       old_add_header = req.add_header
@@ -295,6 +314,11 @@
       raise
 
 class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler):
+  def http_error_401(self, req, fp, code, msg, headers):
+    _AddPasswordFromUserInput(self, msg, req)
+    return urllib2.HTTPDigestAuthHandler.http_error_401(
+      self, req, fp, code, msg, headers)
+
   def http_error_auth_reqed(self, auth_header, host, req, headers):
     try:
       old_add_header = req.add_header