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()

Reply via email to