summaryrefslogtreecommitdiffstats
path: root/Monitoring/MonitoringService/Credential
diff options
context:
space:
mode:
Diffstat (limited to 'Monitoring/MonitoringService/Credential')
-rw-r--r--Monitoring/MonitoringService/Credential/SshKeygen.py100
-rw-r--r--Monitoring/MonitoringService/Credential/__init__.py0
-rw-r--r--Monitoring/MonitoringService/Credential/credentialtypes.py62
-rw-r--r--Monitoring/MonitoringService/Credential/test.py46
4 files changed, 208 insertions, 0 deletions
diff --git a/Monitoring/MonitoringService/Credential/SshKeygen.py b/Monitoring/MonitoringService/Credential/SshKeygen.py
new file mode 100644
index 0000000..6c8042d
--- /dev/null
+++ b/Monitoring/MonitoringService/Credential/SshKeygen.py
@@ -0,0 +1,100 @@
+'''
+Created on Jul 20, 2011
+
+@author: steger
+'''
+from M2Crypto import RSA
+from base64 import b64encode
+from os import chmod, path
+import stat
+
+# paramiko provides this functionality, so maybe we don't need this class. see paramiko.PKey
+
+class CannotSet(Exception):
+ pass
+
+class SshKeygen(object):
+ '''
+ Generates a pair of RSA keys.
+ Enables saving the keys to the file system.
+ '''
+ def __init__(self, bits = 1024, e = 65337):
+ '''
+ Initiates the pair of RSA keys
+ @param bits: the length of the keys in bits
+ @type bits: integer
+ @param e: the exponent
+ @type e: integer
+ '''
+ self.rsa = RSA.gen_key(bits, e, lambda: None)
+
+ def _check_filename(self, filename):
+ if path.exists(filename):
+ raise Exception("File exists: %s" % filename)
+
+ @property
+ def private(self):
+ '''
+ @summary: return the private key in PEM format
+ @return: the private key in PEM format
+ @rtype: string
+ '''
+ return self.rsa.as_pem(cipher = None)
+
+ @private.setter
+ def private(self, value):
+ raise CannotSet
+
+ @private.deleter
+ def private(self):
+ raise CannotSet
+
+ @staticmethod
+ def _convert(rsa):
+ return b64encode('\x00\x00\x00\x07ssh-rsa%s%s' % (rsa.pub()[0], rsa.pub()[1]))
+
+ @property
+ def public(self):
+ '''
+ @summary: return the public key in base64 format conforming to the content of authorized_keys
+ @return: the public key in base64 format
+ @rtype: string
+ '''
+ return self._convert(self.rsa)
+
+ @public.setter
+ def public(self, value):
+ raise CannotSet
+
+ @public.deleter
+ def public(self):
+ raise CannotSet
+
+ def save_private_key(self, filename):
+ '''
+ @summary: save the private key in the file system in a named file.
+ @param filename: the filename to store the private key.
+ @type filename: string
+ '''
+ self._check_filename(filename)
+ self.rsa.save_key(filename, cipher = None)
+ chmod(filename, stat.S_IRUSR)
+
+ def save_public_key(self, filename):
+ '''
+ @summary: save the public key in the file system in a named file.
+ @param filename: the filename to store the public key.
+ @type filename: string
+ '''
+ self._check_filename(filename)
+ with open(filename, "w") as f:
+ f.write("ssh-rsa %s" % self.public)
+
+ @staticmethod
+ def convert_key_from_file(filename):
+ '''
+ @summary: convert a private key stored in a file in PEM format and return the public key in base64 format conforming to the content of authorized_keys
+ @return: the public key in base64 format
+ @rtype: string
+ '''
+ return SshKeygen._convert( RSA.load_key(file = filename) )
diff --git a/Monitoring/MonitoringService/Credential/__init__.py b/Monitoring/MonitoringService/Credential/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Monitoring/MonitoringService/Credential/__init__.py
diff --git a/Monitoring/MonitoringService/Credential/credentialtypes.py b/Monitoring/MonitoringService/Credential/credentialtypes.py
new file mode 100644
index 0000000..45da0de
--- /dev/null
+++ b/Monitoring/MonitoringService/Credential/credentialtypes.py
@@ -0,0 +1,62 @@
+'''
+Created on Oct 27, 2011
+
+@author: steger, jozsef
+@organization: ELTE
+@contact: steger@complex.elte.hu
+'''
+
+class Credential(object):
+ '''
+ @summary: an empty credential to serve as an ancient class
+ @author: steger, jozsef
+ '''
+ pass
+
+class UsernamePassword(Credential):
+ '''
+ @summary: container for a pair of user name and password
+ @author: steger, jozsef
+ @ivar username: name of the user
+ @type username: str
+ @ivar password: password secret
+ @type password: str
+ '''
+
+ def __init__(self, username, password):
+ '''
+ @summary: Constructor
+ @param username: the username
+ @type username: string
+ @param password: the password
+ @type password: string
+ '''
+ self.username = username
+ self.password = password
+
+class UsernameRSAKey(Credential):
+ '''
+ @summary: container for a triple of user name, private key and an optional password for the key
+ @author: steger, jozsef
+ @ivar username: name of the user
+ @type username: str
+ @ivar rsakey: a file name pointing to the user's private key secret
+ @type rsakey: str
+ @ivar password: password secret
+ @type password: str
+ '''
+
+ def __init__(self, username, rsakey, password = ""):
+ '''
+ @summary: Constructor
+ @param username: the username
+ @type username: string
+ @param rsakey: the private key file
+ @type rsakey: string
+ @param password: the optional password to unlock the private key, default: ""
+ @type password: string
+ '''
+ self.username = username
+ self.rsakey = rsakey
+ self.password = password
+ \ No newline at end of file
diff --git a/Monitoring/MonitoringService/Credential/test.py b/Monitoring/MonitoringService/Credential/test.py
new file mode 100644
index 0000000..04a59f3
--- /dev/null
+++ b/Monitoring/MonitoringService/Credential/test.py
@@ -0,0 +1,46 @@
+'''
+Created on Aug 10, 2011
+
+@author: steger
+'''
+import unittest
+from os import close, unlink
+from tempfile import mkstemp
+from subprocess import Popen, PIPE
+from SshKeygen import SshKeygen
+
+class Test(unittest.TestCase):
+ sshkeygen = '/usr/bin/ssh-keygen'
+
+ def test_sshkeygen(self):
+ # generate a pair of RSA keys
+ self.key = SshKeygen()
+
+ # save keys in a file
+ fid, fn = mkstemp(suffix = "_rsa")
+ close(fid)
+ unlink(fn)
+ self.fn_private = fn
+ self.fn_public = "%s.pub" % fn
+ self.key.save_private_key(self.fn_private)
+ self.key.save_public_key(self.fn_public)
+
+ # Test the base64 format of the public key.
+ # convert and compare private key using ssh-keygen
+ proc = Popen(args = [self.sshkeygen, '-y', '-f', self.fn_private], stdout = PIPE)
+ converted = str(proc.communicate(input = None)[0])
+ expected = "ssh-rsa %s\n" % self.key.public
+ self.assertEqual(expected, converted, "Base64 encoded public RSA key differs from the one generated by %s" % self.sshkeygen)
+
+ # Test SshKeygen objects convert_key_from_file method.
+ expected = self.key.public
+ converted = SshKeygen.convert_key_from_file(self.fn_private)
+ self.assertEqual(expected, converted, "Base64 encoded public RSA key generated from file %s differs from expected" % self.fn_private)
+
+ # remove generated files
+ unlink(self.fn_private)
+ unlink(self.fn_public)
+
+if __name__ == "__main__":
+ #import sys;sys.argv = ['', 'Test.test_sshkeygen']
+ unittest.main() \ No newline at end of file