From 2f2a3a129c91de540e66c3bfbe30b0df1942cd4b Mon Sep 17 00:00:00 2001 From: pikusa Date: Wed, 03 Apr 2013 13:18:17 +0000 Subject: project commit and dir tree change --- (limited to 'Monitoring/MonitoringService/Credential') 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 -- cgit