aboutsummaryrefslogtreecommitdiff
path: root/paramiko/auth_handler.py
diff options
context:
space:
mode:
Diffstat (limited to 'paramiko/auth_handler.py')
-rw-r--r--paramiko/auth_handler.py111
1 files changed, 55 insertions, 56 deletions
diff --git a/paramiko/auth_handler.py b/paramiko/auth_handler.py
index acb7c8b..57babef 100644
--- a/paramiko/auth_handler.py
+++ b/paramiko/auth_handler.py
@@ -17,18 +17,21 @@
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
"""
-L{AuthHandler}
+`.AuthHandler`
"""
-import threading
import weakref
+from paramiko.common import cMSG_SERVICE_REQUEST, cMSG_DISCONNECT, \
+ DISCONNECT_SERVICE_NOT_AVAILABLE, DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, \
+ cMSG_USERAUTH_REQUEST, cMSG_SERVICE_ACCEPT, DEBUG, AUTH_SUCCESSFUL, INFO, \
+ cMSG_USERAUTH_SUCCESS, cMSG_USERAUTH_FAILURE, AUTH_PARTIALLY_SUCCESSFUL, \
+ cMSG_USERAUTH_INFO_REQUEST, WARNING, AUTH_FAILED, cMSG_USERAUTH_PK_OK, \
+ cMSG_USERAUTH_INFO_RESPONSE, MSG_SERVICE_REQUEST, MSG_SERVICE_ACCEPT, \
+ MSG_USERAUTH_REQUEST, MSG_USERAUTH_SUCCESS, MSG_USERAUTH_FAILURE, \
+ MSG_USERAUTH_BANNER, MSG_USERAUTH_INFO_REQUEST, MSG_USERAUTH_INFO_RESPONSE
-# this helps freezing utils
-import encodings.utf_8
-
-from paramiko.common import *
-from paramiko import util
from paramiko.message import Message
+from paramiko.py3compat import bytestring
from paramiko.ssh_exception import SSHException, AuthenticationException, \
BadAuthenticationType, PartialAuthentication
from paramiko.server import InteractiveQuery
@@ -45,6 +48,7 @@ class AuthHandler (object):
self.authenticated = False
self.auth_event = None
self.auth_method = ''
+ self.banner = None
self.password = None
self.private_key = None
self.interactive_handler = None
@@ -113,19 +117,17 @@ class AuthHandler (object):
if self.auth_event is not None:
self.auth_event.set()
-
### internals...
-
def _request_auth(self):
m = Message()
- m.add_byte(chr(MSG_SERVICE_REQUEST))
+ m.add_byte(cMSG_SERVICE_REQUEST)
m.add_string('ssh-userauth')
self.transport._send_message(m)
def _disconnect_service_not_available(self):
m = Message()
- m.add_byte(chr(MSG_DISCONNECT))
+ m.add_byte(cMSG_DISCONNECT)
m.add_int(DISCONNECT_SERVICE_NOT_AVAILABLE)
m.add_string('Service not available')
m.add_string('en')
@@ -134,7 +136,7 @@ class AuthHandler (object):
def _disconnect_no_more_auth(self):
m = Message()
- m.add_byte(chr(MSG_DISCONNECT))
+ m.add_byte(cMSG_DISCONNECT)
m.add_int(DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE)
m.add_string('No more auth methods available')
m.add_string('en')
@@ -144,14 +146,14 @@ class AuthHandler (object):
def _get_session_blob(self, key, service, username):
m = Message()
m.add_string(self.transport.session_id)
- m.add_byte(chr(MSG_USERAUTH_REQUEST))
+ m.add_byte(cMSG_USERAUTH_REQUEST)
m.add_string(username)
m.add_string(service)
m.add_string('publickey')
- m.add_boolean(1)
+ m.add_boolean(True)
m.add_string(key.get_name())
- m.add_string(str(key))
- return str(m)
+ m.add_string(key)
+ return m.asbytes()
def wait_for_response(self, event):
while True:
@@ -167,7 +169,7 @@ class AuthHandler (object):
e = self.transport.get_exception()
if e is None:
e = AuthenticationException('Authentication failed.')
- # this is horrible. python Exception isn't yet descended from
+ # this is horrible. Python Exception isn't yet descended from
# object, so type(e) won't work. :(
if issubclass(e.__class__, PartialAuthentication):
return e.allowed_types
@@ -175,11 +177,11 @@ class AuthHandler (object):
return []
def _parse_service_request(self, m):
- service = m.get_string()
+ service = m.get_text()
if self.transport.server_mode and (service == 'ssh-userauth'):
# accepted
m = Message()
- m.add_byte(chr(MSG_SERVICE_ACCEPT))
+ m.add_byte(cMSG_SERVICE_ACCEPT)
m.add_string(service)
self.transport._send_message(m)
return
@@ -187,27 +189,25 @@ class AuthHandler (object):
self._disconnect_service_not_available()
def _parse_service_accept(self, m):
- service = m.get_string()
+ service = m.get_text()
if service == 'ssh-userauth':
self.transport._log(DEBUG, 'userauth is OK')
m = Message()
- m.add_byte(chr(MSG_USERAUTH_REQUEST))
+ m.add_byte(cMSG_USERAUTH_REQUEST)
m.add_string(self.username)
m.add_string('ssh-connection')
m.add_string(self.auth_method)
if self.auth_method == 'password':
m.add_boolean(False)
- password = self.password
- if isinstance(password, unicode):
- password = password.encode('UTF-8')
+ password = bytestring(self.password)
m.add_string(password)
elif self.auth_method == 'publickey':
m.add_boolean(True)
m.add_string(self.private_key.get_name())
- m.add_string(str(self.private_key))
+ m.add_string(self.private_key)
blob = self._get_session_blob(self.private_key, 'ssh-connection', self.username)
- sig = self.private_key.sign_ssh_data(self.transport.rng, blob)
- m.add_string(str(sig))
+ sig = self.private_key.sign_ssh_data(blob)
+ m.add_string(sig)
elif self.auth_method == 'keyboard-interactive':
m.add_string('')
m.add_string(self.submethods)
@@ -224,16 +224,16 @@ class AuthHandler (object):
m = Message()
if result == AUTH_SUCCESSFUL:
self.transport._log(INFO, 'Auth granted (%s).' % method)
- m.add_byte(chr(MSG_USERAUTH_SUCCESS))
+ m.add_byte(cMSG_USERAUTH_SUCCESS)
self.authenticated = True
else:
self.transport._log(INFO, 'Auth rejected (%s).' % method)
- m.add_byte(chr(MSG_USERAUTH_FAILURE))
+ m.add_byte(cMSG_USERAUTH_FAILURE)
m.add_string(self.transport.server_object.get_allowed_auths(username))
if result == AUTH_PARTIALLY_SUCCESSFUL:
- m.add_boolean(1)
+ m.add_boolean(True)
else:
- m.add_boolean(0)
+ m.add_boolean(False)
self.auth_fail_count += 1
self.transport._send_message(m)
if self.auth_fail_count >= 10:
@@ -244,10 +244,10 @@ class AuthHandler (object):
def _interactive_query(self, q):
# make interactive query instead of response
m = Message()
- m.add_byte(chr(MSG_USERAUTH_INFO_REQUEST))
+ m.add_byte(cMSG_USERAUTH_INFO_REQUEST)
m.add_string(q.name)
m.add_string(q.instructions)
- m.add_string('')
+ m.add_string(bytes())
m.add_int(len(q.prompts))
for p in q.prompts:
m.add_string(p[0])
@@ -258,17 +258,17 @@ class AuthHandler (object):
if not self.transport.server_mode:
# er, uh... what?
m = Message()
- m.add_byte(chr(MSG_USERAUTH_FAILURE))
+ m.add_byte(cMSG_USERAUTH_FAILURE)
m.add_string('none')
- m.add_boolean(0)
+ m.add_boolean(False)
self.transport._send_message(m)
return
if self.authenticated:
# ignore
return
- username = m.get_string()
- service = m.get_string()
- method = m.get_string()
+ username = m.get_text()
+ service = m.get_text()
+ method = m.get_text()
self.transport._log(DEBUG, 'Auth request (type=%s) service=%s, username=%s' % (method, service, username))
if service != 'ssh-connection':
self._disconnect_service_not_available()
@@ -283,7 +283,7 @@ class AuthHandler (object):
result = self.transport.server_object.check_auth_none(username)
elif method == 'password':
changereq = m.get_boolean()
- password = m.get_string()
+ password = m.get_binary()
try:
password = password.decode('UTF-8')
except UnicodeError:
@@ -294,7 +294,7 @@ class AuthHandler (object):
# always treated as failure, since we don't support changing passwords, but collect
# the list of valid auth types from the callback anyway
self.transport._log(DEBUG, 'Auth request to change passwords (rejected)')
- newpassword = m.get_string()
+ newpassword = m.get_binary()
try:
newpassword = newpassword.decode('UTF-8', 'replace')
except UnicodeError:
@@ -304,11 +304,11 @@ class AuthHandler (object):
result = self.transport.server_object.check_auth_password(username, password)
elif method == 'publickey':
sig_attached = m.get_boolean()
- keytype = m.get_string()
- keyblob = m.get_string()
+ keytype = m.get_text()
+ keyblob = m.get_binary()
try:
key = self.transport._key_info[keytype](Message(keyblob))
- except SSHException, e:
+ except SSHException as e:
self.transport._log(INFO, 'Auth rejected: public key: %s' % str(e))
key = None
except:
@@ -325,12 +325,12 @@ class AuthHandler (object):
# client wants to know if this key is acceptable, before it
# signs anything... send special "ok" message
m = Message()
- m.add_byte(chr(MSG_USERAUTH_PK_OK))
+ m.add_byte(cMSG_USERAUTH_PK_OK)
m.add_string(keytype)
m.add_string(keyblob)
self.transport._send_message(m)
return
- sig = Message(m.get_string())
+ sig = Message(m.get_binary())
blob = self._get_session_blob(key, service, username)
if not key.verify_ssh_sig(blob, sig):
self.transport._log(INFO, 'Auth rejected: invalid signature')
@@ -352,7 +352,7 @@ class AuthHandler (object):
self.transport._log(INFO, 'Authentication (%s) successful!' % self.auth_method)
self.authenticated = True
self.transport._auth_trigger()
- if self.auth_event != None:
+ if self.auth_event is not None:
self.auth_event.set()
def _parse_userauth_failure(self, m):
@@ -370,29 +370,30 @@ class AuthHandler (object):
self.transport._log(INFO, 'Authentication (%s) failed.' % self.auth_method)
self.authenticated = False
self.username = None
- if self.auth_event != None:
+ if self.auth_event is not None:
self.auth_event.set()
def _parse_userauth_banner(self, m):
banner = m.get_string()
+ self.banner = banner
lang = m.get_string()
- self.transport._log(INFO, 'Auth banner: ' + banner)
+ self.transport._log(INFO, 'Auth banner: %s' % banner)
# who cares.
def _parse_userauth_info_request(self, m):
if self.auth_method != 'keyboard-interactive':
raise SSHException('Illegal info request from server')
- title = m.get_string()
- instructions = m.get_string()
- m.get_string() # lang
+ title = m.get_text()
+ instructions = m.get_text()
+ m.get_binary() # lang
prompts = m.get_int()
prompt_list = []
for i in range(prompts):
- prompt_list.append((m.get_string(), m.get_boolean()))
+ prompt_list.append((m.get_text(), m.get_boolean()))
response_list = self.interactive_handler(title, instructions, prompt_list)
m = Message()
- m.add_byte(chr(MSG_USERAUTH_INFO_RESPONSE))
+ m.add_byte(cMSG_USERAUTH_INFO_RESPONSE)
m.add_int(len(response_list))
for r in response_list:
m.add_string(r)
@@ -404,14 +405,13 @@ class AuthHandler (object):
n = m.get_int()
responses = []
for i in range(n):
- responses.append(m.get_string())
+ responses.append(m.get_text())
result = self.transport.server_object.check_auth_interactive_response(responses)
if isinstance(type(result), InteractiveQuery):
# make interactive query instead of response
self._interactive_query(result)
return
self._send_auth_result(self.auth_username, 'keyboard-interactive', result)
-
_handler_table = {
MSG_SERVICE_REQUEST: _parse_service_request,
@@ -423,4 +423,3 @@ class AuthHandler (object):
MSG_USERAUTH_INFO_REQUEST: _parse_userauth_info_request,
MSG_USERAUTH_INFO_RESPONSE: _parse_userauth_info_response,
}
-