r46948 - generate the key!

hawkowl-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org
Newsgroups gmane.comp.python.twisted.commits
Message-ID <[email protected]>
Author: hawkowl
Date: Tue Mar  8 09:22:50 2016
New Revision: 46948

Modified:
   branches/manhole-hardcodedkey-8229/twisted/conch/manhole_tap.py
   branches/manhole-hardcodedkey-8229/twisted/conch/ssh/keys.py

Log:
generate the key!

Modified: branches/manhole-hardcodedkey-8229/twisted/conch/manhole_tap.py
==============================================================================
--- branches/manhole-hardcodedkey-8229/twisted/conch/manhole_tap.py	(original)
+++ branches/manhole-hardcodedkey-8229/twisted/conch/manhole_tap.py	Tue Mar  8 09:22:50 2016
@@ -12,10 +12,11 @@
 from twisted.internet import protocol
 from twisted.application import service, strports
 from twisted.cred import portal, checkers
-from twisted.python import usage
+from twisted.python import usage, filepath
 
-from twisted.conch.insults import insults
 from twisted.conch import manhole, manhole_ssh, telnet
+from twisted.conch.insults import insults
+from twisted.conch.ssh import keys
 
 class makeTelnetProtocol:
     def __init__(self, portal):
@@ -29,7 +30,7 @@
 class chainedProtocolFactory:
     def __init__(self, namespace):
         self.namespace = namespace
-    
+
     def __call__(self):
         return insults.ServerProtocol(manhole.ColoredManhole, self.namespace)
 
@@ -53,18 +54,23 @@
     optParameters = [
         ["telnetPort", "t", None, "strports description of the address on which to listen for telnet connections"],
         ["sshPort", "s", None, "strports description of the address on which to listen for ssh connections"],
-        ["passwd", "p", "/etc/passwd", "name of a passwd(5)-format username/password file"]]
+        ["passwd", "p", "/etc/passwd", "name of a passwd(5)-format username/password file"],
+        ["sshKeyDir", None, None, "Directory where the autogenerated SSH key is kept."],
+        ["sshKeyName", None, None, "Filename of the autogenerated SSH key."],
+        ["sshKeySize", None, 4096, "Size of the automatically generated SSH key."],
+    ]
 
     def __init__(self):
         usage.Options.__init__(self)
         self['namespace'] = None
-    
+
     def postOptions(self):
         if self['telnetPort'] is None and self['sshPort'] is None:
             raise usage.UsageError("At least one of --telnetPort and --sshPort must be specified")
 
 def makeService(options):
-    """Create a manhole server service.
+    """
+    Create a manhole server service.
 
     @type options: C{dict}
     @param options: A mapping describing the configuration of
@@ -87,7 +93,6 @@
     @rtype: L{twisted.application.service.IService}
     @return: A manhole service.
     """
-
     svc = service.MultiService()
 
     namespace = options['namespace']
@@ -116,8 +121,12 @@
 
         sshPortal = portal.Portal(sshRealm, [checker])
         sshFactory = manhole_ssh.ConchFactory(sshPortal)
-        sshService = strports.service(options['sshPort'],
-                                      sshFactory)
+
+        sshKey = keys._generateSavedRSAKey()
+        sshFactory.publicKeys["ssh-rsa"] = sshKey
+        sshFactory.privateKeys["ssh-rsa"] = sshKey
+
+        sshService = strports.service(options['sshPort'], sshFactory)
         sshService.setServiceParent(svc)
 
     return svc

Modified: branches/manhole-hardcodedkey-8229/twisted/conch/ssh/keys.py
==============================================================================
--- branches/manhole-hardcodedkey-8229/twisted/conch/ssh/keys.py	(original)
+++ branches/manhole-hardcodedkey-8229/twisted/conch/ssh/keys.py	Tue Mar  8 09:22:50 2016
@@ -15,7 +15,7 @@
 
 from cryptography.exceptions import InvalidSignature
 from cryptography.hazmat.backends import default_backend
-from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives import hashes, serialization
 from cryptography.hazmat.primitives.asymmetric import dsa, rsa, padding
 try:
     from cryptography.hazmat.primitives.asymmetric.utils import (
@@ -33,7 +33,7 @@
 
 from twisted.conch.ssh import common, sexpy
 from twisted.conch.ssh.common import int_from_bytes, int_to_bytes
-from twisted.python import randbytes
+from twisted.python import randbytes, filepath
 from twisted.python.compat import iterbytes, long, izip, nativeString, _PY3
 from twisted.python.deprecate import deprecated, getDeprecationWarningString
 from twisted.python.versions import Version
@@ -1229,6 +1229,49 @@
         raise BadKeyError("invalid key object", obj)
 
 
+
+def _generateSavedRSAKey(directory=None, filename="server.pem", keySize=4096):
+    """
+    This function generates a persistent server key
+    """
+    if directory is None:
+        from appdirs import user_data_dir
+        directory = user_data_dir("Twisted", "Conch")
+
+    configDir = filepath.FilePath(directory)
+    configDir.makedirs(ignoreExistingDirectory=True)
+    pemFile = configDir.child(filename)
+
+    # If it doesn't exist, we want to generate a new key and save it
+    if not pemFile.exists():
+        privateKey = rsa.generate_private_key(
+            public_exponent=65537,
+            key_size=keySize,
+            backend=default_backend()
+        )
+
+        pem = privateKey.private_bytes(
+            encoding=serialization.Encoding.PEM,
+            format=serialization.PrivateFormat.TraditionalOpenSSL,
+            encryption_algorithm=serialization.NoEncryption()
+        )
+
+        pemFile.setContent(pem)
+
+    # By this point (save any hilarious race conditions) we should have a
+    # working PEM file. Load it!
+    # (Future archelogical readers: I chose not to short circuit above, because
+    # then there's two exit paths to this code!)
+    with pemFile.open("rb") as key_file:
+        privateKey = serialization.load_pem_private_key(
+            key_file.read(),
+            password=None,
+            backend=default_backend()
+        )
+        return Key(privateKey)
+
+
+
 if _PY3:
     # The objectType function is deprecated and not being ported to Python 3.
     del objectType
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.