# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""Authentication token retrieval."""
+
from bzrlib.config import AuthenticationConfig
from bzrlib.ui import ui_factory
-from svn.core import (svn_auth_cred_username_t,
- svn_auth_cred_simple_t,
- svn_auth_cred_ssl_client_cert_t,
- svn_auth_cred_ssl_client_cert_pw_t,
- svn_auth_cred_ssl_server_trust_t,
- svn_auth_get_username_prompt_provider,
- svn_auth_get_simple_prompt_provider,
- svn_auth_get_ssl_server_trust_prompt_provider,
- svn_auth_get_ssl_client_cert_pw_prompt_provider)
-
+from bzrlib.plugins.svn.ra import (get_username_prompt_provider,
+ get_simple_prompt_provider,
+ get_ssl_server_trust_prompt_provider,
+ get_ssl_client_cert_pw_prompt_provider)
+ get_simple_provider, get_username_provider,
+ get_ssl_client_cert_file_provider,
+ get_ssl_client_cert_pw_file_provider,
+ get_ssl_server_trust_file_provider,
+ Auth
+ )
+from bzrlib.plugins.svn import ra
+import urlparse
+import urllib
+
+AUTH_PARAM_DEFAULT_USERNAME = 'svn:auth:username'
+AUTH_PARAM_DEFAULT_PASSWORD = 'svn:auth:password'
class SubversionAuthenticationConfig(AuthenticationConfig):
"""Simple extended version of AuthenticationConfig that can provide
the information Subversion requires.
"""
- def __init__(self, file=None, scheme="svn", host=None):
+ def __init__(self, scheme, host, port, path, file=None):
super(SubversionAuthenticationConfig, self).__init__(file)
self.scheme = scheme
self.host = host
-
- def get_svn_username(self, realm, may_save, pool=None):
+ self.port = port
+ self.path = path
+
+ def get_svn_username(self, realm, may_save):
"""Look up a Subversion user name in the Bazaar authentication cache.
:param realm: Authentication realm (optional)
:param may_save: Whether or not the username should be saved.
- :param pool: Allocation pool, is ignored.
"""
- username_cred = svn_auth_cred_username_t()
- username_cred.username = self.get_user(self.scheme, host=self.host, realm=realm)
- username_cred.may_save = False
- return username_cred
+ username = self.get_user(self.scheme, host=self.host, path=self.path, realm=realm)
+ return (username, False)
def get_svn_simple(self, realm, username, may_save, pool):
- """Look up a Subversion user name+password combination in the Bazaar authentication cache.
+ """Look up a Subversion user name+password combination in the Bazaar
+ authentication cache.
:param realm: Authentication realm (optional)
:param username: Username, if it is already known, or None.
:param may_save: Whether or not the username should be saved.
:param pool: Allocation pool, is ignored.
"""
- simple_cred = svn_auth_cred_simple_t()
- simple_cred.username = username or self.get_username(realm, may_save, pool, prompt="%s password" % realm)
- simple_cred.password = self.get_password(self.scheme, host=self.host,
- user=simple_cred.username, realm=realm,
- prompt="%s password" % realm)
- simple_cred.may_save = False
- return simple_cred
-
- def get_svn_ssl_server_trust(self, realm, failures, cert_info, may_save, pool):
+ username = self.get_user(self.scheme,
+ host=self.host, path=self.path, realm=realm) or username
+ password = self.get_password(self.scheme, host=self.host,
+ path=self.path, user=simple_cred.username,
+ realm=realm, prompt="%s %s password" % (realm, simple_cred.username))
+ return (username, password, False)
+
+ def get_svn_ssl_server_trust(self, realm, failures, cert_info, may_save,
+ pool):
"""Return a Subversion auth provider that verifies SSL server trust.
:param realm: Realm name (optional)
:param cert_info: Certificate information
:param may_save: Whether this information may be stored.
"""
- ssl_server_trust = svn_auth_cred_ssl_server_trust_t()
credentials = self.get_credentials(self.scheme, host=self.host)
if (credentials is not None and
credentials.has_key("verify_certificates") and
credentials["verify_certificates"] == False):
- ssl_server_trust.accepted_failures = (svn.core.SVN_AUTH_SSL_NOTYETVALID +
- svn.core.SVN_AUTH_SSL_EXPIRED +
- svn.core.SVN_AUTH_SSL_CNMISMATCH +
- svn.core.SVN_AUTH_SSL_UNKNOWNCA +
- svn.core.SVN_AUTH_SSL_OTHER)
+ accepted_failures = (
+ AUTH_SSL_NOTYETVALID +
+ AUTH_SSL_EXPIRED +
+ AUTH_SSL_CNMISMATCH +
+ AUTH_SSL_UNKNOWNCA +
+ AUTH_SSL_OTHER)
else:
- ssl_server_trust.accepted_failures = 0
- ssl_server_trust.may_save = False
- return ssl_server_trust
+ accepted_failures = 0
+ return (accepted_failures, False)
def get_svn_username_prompt_provider(self, retries):
"""Return a Subversion auth provider for retrieving the username, as
:param retries: Number of allowed retries.
"""
- return svn_auth_get_username_prompt_provider(self.get_svn_username, retries)
+ return get_username_prompt_provider(self.get_svn_username,
+ retries)
def get_svn_simple_prompt_provider(self, retries):
"""Return a Subversion auth provider for retrieving a
:param retries: Number of allowed retries.
"""
- return svn_auth_get_simple_prompt_provider(self.get_svn_simple, retries)
+ return get_simple_prompt_provider(self.get_svn_simple, retries)
def get_svn_ssl_server_trust_prompt_provider(self):
"""Return a Subversion auth provider for checking
whether a SSL server is trusted."""
- return svn_auth_get_ssl_server_trust_prompt_provider(self.get_svn_ssl_server_trust)
+ return get_ssl_server_trust_prompt_provider(
+ self.get_svn_ssl_server_trust)
def get_svn_auth_providers(self):
"""Return a list of auth providers for this authentication file.
self.get_svn_simple_prompt_provider(1),
self.get_svn_ssl_server_trust_prompt_provider()]
-
def get_ssl_client_cert_pw(realm, may_save, pool):
"""Simple SSL client certificate password prompter.
:param realm: Realm, optional.
:param may_save: Whether the password can be cached.
"""
- ssl_cred_pw = svn_auth_cred_ssl_client_cert_pw_t()
- ssl_cred_pw.password = \
- ui_factory.get_password("Please enter password for client certificate[realm=%s]" % realm)
- ssl_cred_pw.may_save = False
- return ssl_cred_pw
+ password = ui_factory.get_password(
+ "Please enter password for client certificate[realm=%s]" % realm)
+ return (password, False)
def get_ssl_client_cert_pw_provider(tries):
- return svn_auth_get_ssl_client_cert_pw_prompt_provider(get_ssl_client_cert_pw, tries)
-
+ return get_ssl_client_cert_pw_prompt_provider(
+ get_ssl_client_cert_pw, tries)
+
+def get_stock_svn_providers():
+ providers = [get_simple_provider(),
+ get_username_provider(),
+ get_ssl_client_cert_file_provider(),
+ get_ssl_client_cert_pw_file_provider(),
+ get_ssl_server_trust_file_provider(),
+ ]
+
+ if hasattr(ra, 'get_windows_simple_provider'):
+ providers.append(ra.get_windows_simple_provider())
+
+ if hasattr(ra, 'get_keychain_simple_provider'):
+ providers.append(ra.get_keychain_simple_provider())
+
+ if hasattr(ra, 'get_windows_ssl_server_trust_provider'):
+ providers.append(ra.get_windows_ssl_server_trust_provider())
+
+ return providers
+
+
+def create_auth_baton(url):
+ """Create an authentication baton for the specified URL."""
+ assert isinstance(url, str)
+ (scheme, netloc, path, _, _) = urlparse.urlsplit(url)
+ (creds, host) = urllib.splituser(netloc)
+ (host, port) = urllib.splitport(host)
+
+ auth_config = SubversionAuthenticationConfig(scheme, host, port, path)
+
+ # Specify Subversion providers first, because they use file data
+ # rather than prompting the user.
+ providers = get_stock_svn_providers()
+
+ (major, minor, patch, tag) = ra.version()
+ if major == 1 and minor >= 5:
+ providers += auth_config.get_svn_auth_providers()
+ providers += [get_ssl_client_cert_pw_provider(1)]
+
+ auth_baton = Auth(providers)
+ if creds is not None:
+ (user, password) = urllib.splitpasswd(creds)
+ if user is not None:
+ auth_baton.set_parameter(AUTH_PARAM_DEFAULT_USERNAME, user)
+ if password is not None:
+ auth_baton.set_parameter(AUTH_PARAM_DEFAULT_PASSWORD, password)
+ return auth_baton