4141 SCPError
4242from ...constants import DEFAULT_RETRIES , RETRY_DELAY
4343from ...native ._ssh2 import wait_select , _read_output # , sftp_get, sftp_put
44+ from .common import _validate_pkey_path
4445
4546
4647Hub .NOT_ERROR = (Exception ,)
@@ -75,9 +76,9 @@ def __init__(self, host,
7576 :type password: str
7677 :param port: SSH port to connect to. Defaults to SSH default (22)
7778 :type port: int
78- :param pkey: Private key file path to use for authentication.
79- Note that the public key file
80- pair *must* also exist in the same location with name ``<pkey>.pub``
79+ :param pkey: Private key file path to use for authentication. Path must
80+ be either absolute path or relative to user home directory
81+ like ``~/<path>``.
8182 :type pkey: str
8283 :param num_retries: (Optional) Number of connection and authentication
8384 attempts before the client gives up. Defaults to 3.
@@ -98,6 +99,9 @@ def __init__(self, host,
9899 :param proxy_host: Connection to host is via provided proxy host
99100 and client should use self.proxy_host for connection attempts.
100101 :type proxy_host: str
102+
103+ :raises: :py:class:`pssh.exceptions.PKeyFileError` on errors finding
104+ provided private key.
101105 """
102106 self .host = host
103107 self .user = user if user else None
@@ -107,7 +111,6 @@ def __init__(self, host,
107111 raise ValueError ("Must provide user parameter on Windows" )
108112 self .password = password
109113 self .port = port if port else 22
110- self .pkey = pkey
111114 self .num_retries = num_retries
112115 self .sock = None
113116 self .timeout = timeout * 1000 if timeout else None
@@ -117,6 +120,7 @@ def __init__(self, host,
117120 self ._forward_requested = False
118121 self .session = None
119122 self ._host = proxy_host if proxy_host else host
123+ self .pkey = _validate_pkey_path (pkey , self .host )
120124 self ._connect (self ._host , self .port )
121125 if _auth_thread_pool :
122126 THREAD_POOL .apply (self ._init )
@@ -130,7 +134,7 @@ def disconnect(self):
130134 self ._eagain (self .session .disconnect )
131135 except Exception :
132136 pass
133- if not self .sock .closed :
137+ if self . sock is not None and not self .sock .closed :
134138 self .sock .close ()
135139
136140 def __del__ (self ):
@@ -202,29 +206,24 @@ def _connect(self, host, port, retries=1):
202206 self .num_retries ,)
203207
204208 def _pkey_auth (self ):
205- pub_file = "%s.pub" % self .pkey
206- logger .debug ("Attempting authentication with public key %s for user %s" ,
207- pub_file , self .user )
208209 self .session .userauth_publickey_fromfile (
209210 self .user ,
210- pub_file ,
211211 self .pkey ,
212- self .password if self .password is not None else '' )
212+ passphrase = self .password if self .password is not None else '' )
213213
214214 def _identity_auth (self ):
215+ passphrase = self .password if self .password is not None else ''
215216 for identity_file in self .IDENTITIES :
216217 if not os .path .isfile (identity_file ):
217218 continue
218- pub_file = "%s.pub" % (identity_file )
219219 logger .debug (
220220 "Trying to authenticate with identity file %s" ,
221221 identity_file )
222222 try :
223223 self .session .userauth_publickey_fromfile (
224224 self .user ,
225- pub_file ,
226225 identity_file ,
227- self . password if self . password is not None else '' )
226+ passphrase = passphrase )
228227 except Exception :
229228 logger .debug ("Authentication with identity file %s failed, "
230229 "continuing with other identities" ,
@@ -239,7 +238,7 @@ def _identity_auth(self):
239238 def auth (self ):
240239 if self .pkey is not None :
241240 logger .debug (
242- "Proceeding with public key file authentication" )
241+ "Proceeding with private key file authentication" )
243242 return self ._pkey_auth ()
244243 if self .allow_agent :
245244 try :
@@ -256,11 +255,13 @@ def auth(self):
256255 except AuthenticationException :
257256 if self .password is None :
258257 raise
259- logger .debug ("Public key auth failed, trying password" )
258+ logger .debug ("Private key auth failed, trying password" )
260259 self ._password_auth ()
261260
262261 def _password_auth (self ):
263- if self .session .userauth_password (self .user , self .password ) != 0 :
262+ try :
263+ self .session .userauth_password (self .user , self .password )
264+ except Exception :
264265 raise AuthenticationException ("Password authentication failed" )
265266
266267 def open_session (self ):
0 commit comments