Author: janne.t.harkonen
Date: Tue Feb 24 22:52:26 2009
New Revision: 55
Added:
trunk/atest/invalid_rsa
Modified:
trunk/atest/connection.py
trunk/atest/connection_tests/open_and_close_connection.html
trunk/atest/ssh_library_resources.html
trunk/src/SSHLibrary/__init__.py
trunk/src/SSHLibrary/javaclient.py
trunk/src/SSHLibrary/pythonclient.py
Log:
Implementation and tests for public key authentication, see issue13
This version does not support keys given directly, only keys from files
can be used.
Modified: trunk/atest/connection.py
==============================================================================
--- trunk/atest/connection.py (original)
+++ trunk/atest/connection.py Tue Feb 24 22:52:26 2009
@@ -1,4 +1,14 @@
+import os
+
+basedir = os.path.dirname(__file__)
+
HOST = "localhost" #"172.21.106.53"
USERNAME = "test" #user"
PASSWORD = "test"
PROMPT = "$"
+
+PUBKEY_USERNAME = 'testkey'
+PUBKEY_PASSWORD = 'testkey'
+PUBKEY_FILE = '/home/jth/.ssh/id_rsa'
+INVALID_PUBKEY_USERNAME = 'invalid_key_username'
+INVALID_PUBKEY_FILE = os.path.join(basedir, 'invalid_rsa')
Modified: trunk/atest/connection_tests/open_and_close_connection.html
==============================================================================
--- trunk/atest/connection_tests/open_and_close_connection.html (original)
+++ trunk/atest/connection_tests/open_and_close_connection.html Tue Feb 24
22:52:26 2009
@@ -73,8 +73,8 @@
<th>Value</th>
</tr>
<tr>
-<td>Documentation</td>
-<td>\</td>
+<td>Test Teardown</td>
+<td>Close All Connections</td>
<td></td>
<td></td>
<td></td>
@@ -128,11 +128,11 @@
<th>Argument</th>
</tr>
<tr>
-<td><a name="test_Test Opening And Closing Connection">Test Opening And
Closing Connection</a></td>
+<td>Test Opening And Closing Connection</td>
+<td>[Setup]</td>
<td>Open Connection</td>
<td>${HOST}</td>
<td></td>
-<td></td>
</tr>
<tr>
<td></td>
@@ -143,20 +143,13 @@
</tr>
<tr>
<td></td>
-<td>Close Connection</td>
-<td></td>
-<td></td>
-<td></td>
-</tr>
-<tr>
-<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
-<td><a name="test_Switch Connection">Switch Connection</a></td>
+<td>Switch Connection</td>
<td>${id1} =</td>
<td>Open Connection</td>
<td>${HOST}</td>
@@ -234,7 +227,7 @@
</tr>
<tr>
<td></td>
-<td>${prev id}=</td>
+<td>${prev id} =</td>
<td>Switch Connection</td>
<td>second</td>
<td></td>
@@ -258,6 +251,83 @@
<td>Should Contain</td>
<td>${result}</td>
<td>/home</td>
+<td></td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>Login With Public Key</td>
+<td>[Setup]</td>
+<td>Open Connection</td>
+<td>${HOST}</td>
+<td></td>
+</tr>
+<tr>
+<td></td>
+<td>Login With Public Key</td>
+<td>${PUBKEY_USERNAME}</td>
+<td>${PUBKEY_FILE}</td>
+<td>${PUBKEY_PASSWORD}</td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>Login With Non Existing Public Key</td>
+<td>[Setup]</td>
+<td>Open Connection</td>
+<td>${HOST}</td>
+<td></td>
+</tr>
+<tr>
+<td></td>
+<td>Run Keyword And Expect Error</td>
+<td>Given key file '/invalid/path' does not exist</td>
+<td>Login With Public Key</td>
+<td>${PUBKEY_USERNAME}</td>
+</tr>
+<tr>
+<td></td>
+<td>...</td>
+<td>/invalid/path</td>
+<td>${PUBKEY_PASSWORD}</td>
+<td></td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>Login With Invalid Public Key</td>
+<td>[Setup]</td>
+<td>Open Connection</td>
+<td>${HOST}</td>
+<td></td>
+</tr>
+<tr>
+<td></td>
+<td>Run Keyword And Expect Error</td>
+<td>Login with public key failed</td>
+<td>Login With Public Key</td>
+<td>${PUBKEY_USERNAME}</td>
+</tr>
+<tr>
+<td></td>
+<td>...</td>
+<td>${INVALID PUBKEY FILE}</td>
+<td>invalid</td>
<td></td>
</tr>
<tr>
Added: trunk/atest/invalid_rsa
==============================================================================
--- (empty file)
+++ trunk/atest/invalid_rsa Tue Feb 24 22:52:26 2009
@@ -0,0 +1 @@
+invalid private key file
Modified: trunk/atest/ssh_library_resources.html
==============================================================================
--- trunk/atest/ssh_library_resources.html (original)
+++ trunk/atest/ssh_library_resources.html Tue Feb 24 22:52:26 2009
@@ -87,6 +87,13 @@
<td></td>
</tr>
<tr>
+<td>Library</td>
+<td>OperatingSystem</td>
+<td>WITH NAME</td>
+<td>OS</td>
+<td></td>
+</tr>
+<tr>
<td></td>
<td></td>
<td></td>
Modified: trunk/src/SSHLibrary/__init__.py
==============================================================================
--- trunk/src/SSHLibrary/__init__.py (original)
+++ trunk/src/SSHLibrary/__init__.py Tue Feb 24 22:52:26 2009
@@ -20,6 +20,7 @@
import posixpath
from robot import utils
+from robot.errors import DataError
if utils.is_jython:
from javaclient import SSHClient
@@ -173,6 +174,21 @@
self._info("Logging into '%s:%s' with username '%s' and
password '%s'"
% (self._host, self._port, username, password))
self._client.login(username, password)
+
+ def login_with_public_key(self, username, keyfile, password):
+ """Logs into SSH server with given information
+
+ `username` is the username on the remote system.
+ `keyfile` is a path to a valid OpenSSH *private* key file.
+ `password` is used to unlock `keyfile` if unlocking is required.
+ """
+ if not os.path.exists(keyfile):
+ raise DataError("Given key file '%s' does not exist" % keyfile)
+ self._info("Logging into '%s' as '%s'" % (self._host, username))
+ try:
+ self._client.login_with_public_key(username, keyfile, password)
+ except DataError:
+ raise DataError('Login with public key failed')
def execute_command(self, command, ret_mode='stdout'):
"""Executes command on remote host over existing SSH connection
and returns stdout and/or stderr.
Modified: trunk/src/SSHLibrary/javaclient.py
==============================================================================
--- trunk/src/SSHLibrary/javaclient.py (original)
+++ trunk/src/SSHLibrary/javaclient.py Tue Feb 24 22:52:26 2009
@@ -15,8 +15,10 @@
import jarray
-from java.io import BufferedReader, InputStreamReader, IOException, \
+from java.io import File, BufferedReader, InputStreamReader, IOException, \
FileOutputStream, BufferedWriter, OutputStreamWriter
+
+from robot.errors import DataError
try:
from com.trilead.ssh2 import StreamGobbler, SCPClient, Connection,
SFTPv3Client, \
SFTPv3FileAttributes, SFTPException,
DebugLogger
@@ -36,6 +38,13 @@
if not self.client.authenticateWithPassword(username, password):
raise AssertionError("Authentication failed for user: %s" %
username)
+ def login_with_public_key(self, username, key, password):
+ try:
+ if not self.client.authenticateWithPublicKey(username,
File(key), password):
+ raise AssertionError("Authentication failed for
user: %s" % username)
+ except IOException:
+ raise DataError()
+
def enable_ssh_logging(self, path):
self.client.enableDebugging(True, Logger(path))
Modified: trunk/src/SSHLibrary/pythonclient.py
==============================================================================
--- trunk/src/SSHLibrary/pythonclient.py (original)
+++ trunk/src/SSHLibrary/pythonclient.py Tue Feb 24 22:52:26 2009
@@ -16,6 +16,8 @@
import os
import stat
import posixpath
+
+from robot.errors import DataError
try:
import paramiko
except ImportError:
@@ -45,6 +47,13 @@
def login(self, username, password):
self.client.connect(self.host, self.port, username, password)
+ def login_with_public_key(self, username, keyfile, password):
+ try:
+ self.client.connect(self.host, self.port, username, password,
+ key_filename=keyfile)
+ except paramiko.AuthenticationException:
+ raise DataError()
+
def close(self):
self.client.close()