Branch: refs/heads/master
  Home:   https://github.com/NixOS/charon
  Commit: 63ddb7293cafd10d50a815e6dcc2d563c4e8bac0
      
https://github.com/NixOS/charon/commit/63ddb7293cafd10d50a815e6dcc2d563c4e8bac0
  Author: Eelco Dolstra <[email protected]>
  Date:   2012-04-25 (Wed, 25 Apr 2012)

  Changed paths:
    M charon/backends/__init__.py
    M charon/backends/ec2.py
    M charon/backends/virtualbox.py
    R nix/id_charon-virtualbox
    R nix/id_charon-virtualbox.pub
    M nix/virtualbox-image-charon.nix

  Log Message:
  -----------
  VirtualBox backend: don't hard-code an SSH key into the image but generate 
one on the fly

Charon generates an SSH key and the client adds it to root's
authorized_keys file using ‘VBoxControl guestproperty get’.


diff --git a/charon/backends/__init__.py b/charon/backends/__init__.py
index 61f232f..335af12 100644
--- a/charon/backends/__init__.py
+++ b/charon/backends/__init__.py
@@ -1,7 +1,9 @@
 # -*- coding: utf-8 -*-
 
+import os
 import sys
 import time
+import shutil
 import subprocess
 
 
@@ -123,7 +125,20 @@ def run_command(self, command, check=True, 
capture_stdout=False):
                 raise Exception("command ‘{0}’ failed on machine 
‘{1}’".format(command, self.name))
             return res
 
+    def _create_key_pair(self):
+        key_dir = self.depl.tempdir + "/ssh-key-" + self.name
+        os.mkdir(key_dir, 0700)
+        fnull = open(os.devnull, 'w')
+        res = subprocess.call(["ssh-keygen", "-t", "dsa", "-f", key_dir + 
"/key", "-N", '', "-C", "Charon auto-generated key"],
+                              stdout=fnull)
+        fnull.close()
+        if res != 0: raise Exception("unable to generate an SSH key")
+        f = open(key_dir + "/key"); private = f.read(); f.close()
+        f = open(key_dir + "/key.pub"); public = f.read().rstrip(); f.close()
+        shutil.rmtree(key_dir)
+        return (private, public)
 
+    
 import charon.backends.none
 import charon.backends.virtualbox
 import charon.backends.ec2
diff --git a/charon/backends/ec2.py b/charon/backends/ec2.py
index 01aa6a8..b4c1e73 100644
--- a/charon/backends/ec2.py
+++ b/charon/backends/ec2.py
@@ -251,20 +251,6 @@ def _get_volume_by_id(self, volume_id):
         return volumes[0]
 
 
-    def _create_key_pair(self):
-        key_dir = self.depl.tempdir + "/ssh-key-" + self.name
-        os.mkdir(key_dir, 0700)
-        fnull = open(os.devnull, 'w')
-        res = subprocess.call(["ssh-keygen", "-t", "dsa", "-f", key_dir + 
"/key", "-N", '', "-C", "Charon auto-generated key"],
-                              stdout=fnull)
-        fnull.close()
-        if res != 0: raise Exception("unable to generate an SSH key")
-        f = open(key_dir + "/key"); private = f.read(); f.close()
-        f = open(key_dir + "/key.pub"); public = f.read().rstrip(); f.close()
-        shutil.rmtree(key_dir)
-        return (private, public)
-
-    
     def create(self, defn, check):
         assert isinstance(defn, EC2Definition)
         assert defn.type == "ec2"
diff --git a/charon/backends/virtualbox.py b/charon/backends/virtualbox.py
index 9bf01eb..03f2705 100644
--- a/charon/backends/virtualbox.py
+++ b/charon/backends/virtualbox.py
@@ -43,6 +43,8 @@ def __init__(self, depl, name):
         self._disk = None
         self._disk_attached = False
         self._started = False
+        self._client_private_key = None
+        self._client_public_key = None
         
     def serialise(self):
         x = MachineState.serialise(self)
@@ -51,6 +53,8 @@ def serialise(self):
 
         y = {}
         if self._disk: y['disk'] = self._disk
+        if self._client_private_key: y['clientPrivateKey'] = 
self._client_private_key
+        if self._client_public_key: y['clientPublicKey'] = 
self._client_public_key
         y['diskAttached'] = self._disk_attached
         y['started'] = self._started
         x['virtualbox'] = y
@@ -65,6 +69,8 @@ def deserialise(self, x):
         y = x.get('virtualbox')
         self._disk = y.get('disk', None)
         self._disk_attached = y.get('diskAttached', False)
+        self._client_private_key = y.get('clientPrivateKey', None)
+        self._client_public_key = y.get('clientPublicKey', None)
         self._started = y.get('started', False)
 
     def get_ssh_name(self):
@@ -72,11 +78,11 @@ def get_ssh_name(self):
         return self._ipv4
 
     def get_ssh_flags(self):
-        copy = self.depl.tempdir + "/id_charon-virtualbox"
-        if not os.path.exists(copy):
-            shutil.copy(self.depl.expr_path + "/id_charon-virtualbox", copy)
-            os.chmod(copy, stat.S_IRUSR | stat.S_IWUSR)
-        return ["-o", "StrictHostKeyChecking=no", "-i", copy]
+        key_file = "{0}/id_charon-{1}".format(self.depl.tempdir, self.name)
+        if not os.path.exists(key_file):
+            with os.fdopen(os.open(key_file, os.O_CREAT | os.O_WRONLY, 0600), 
"w") as f:
+                f.write(self._client_private_key)
+        return ["-o", "StrictHostKeyChecking=no", "-i", key_file]
 
     def get_physical_spec(self, machines):
         return ['    require = [ <charon/virtualbox-image-charon.nix> ];',
@@ -188,6 +194,9 @@ def create(self, defn, check):
                 self._started = False
                 self.write()
 
+        if not self._client_private_key:
+            (self._client_private_key, self._client_public_key) = 
self._create_key_pair()
+
         if not self._started:
             res = subprocess.call(
                 ["VBoxManage", "modifyvm", self._vm_id,
@@ -201,6 +210,10 @@ def create(self, defn, check):
                 ["VBoxManage", "guestproperty", "set", self._vm_id, 
"/VirtualBox/GuestInfo/Net/1/V4/IP", ''])
             if res != 0: raise Exception("unable to clear IP address of 
VirtualBox VM ‘{0}’".format(self.name))
 
+            res = subprocess.call(
+                ["VBoxManage", "guestproperty", "set", self._vm_id, 
"/VirtualBox/GuestInfo/Charon/ClientPublicKey", self._client_public_key])
+            if res != 0: raise Exception("unable to client key of VirtualBox 
VM ‘{0}’".format(self.name))
+
             res = subprocess.call(["VBoxManage", "startvm", self._vm_id] + 
(["--type", "headless"] if defn.headless else []))
             if res != 0: raise Exception("unable to start VirtualBox VM 
‘{0}’".format(self.name))
 
diff --git a/nix/id_charon-virtualbox b/nix/id_charon-virtualbox
deleted file mode 100644
index 5c2c282..0000000
--- a/nix/id_charon-virtualbox
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN DSA PRIVATE KEY-----
-MIIBugIBAAKBgQCOQjyR1OxMJWQIpHfxynk9g4F8i5Mz3BBrwsfJIYQf6w7fnyDR
-YC+S6BxkMkTQW4o9NnkloOwqopHHJ7nwLTyJpQB40UqXJbO8j3FhHk5AjOS2KXfc
-cg4c48e6k3LfGrAGVDA6Egw3hT7LnX8KEBzl8zrJxsOtGvgcqRieXsQr2wIVAKch
-xwwKaMDMVfvOid4cHOSStzYXAoGAJVbnqgbpucuif0OMxh8q8vK8wOdHUKSrvIQ/
-U8+61QYp6gRzCETaFREnx7aDKkwPvA7QpGvt+JQQqpS9rey6nAUH1imPYZ0nakBZ
-s1Xs2MSyNiON7fCQXrzbYjBDYWp1SqKJzi9BByC3VWOSxVRinTrj/Eo9palhE+te
-DrYUJ94CgYBS3GiAKU4QPGHzJbUAKKrs/FW3AGkgur0izOM3MgrYEl7q2B3GSYRU
-BGL+jPHcmziJYTbr0ttVRJyge/mf+fnSpm684IL8mnmytVnVpTy0iFwgafyLkE8B
-oy5b56s3n2sg/iI5yAOkgCar8gKsyPHXVTo92OtxT4jvrXZhTRONzAIUQFpnij7I
-F7poaGBdyYat5tgioL0=
------END DSA PRIVATE KEY-----
diff --git a/nix/id_charon-virtualbox.pub b/nix/id_charon-virtualbox.pub
deleted file mode 100644
index ec53a70..0000000
--- a/nix/id_charon-virtualbox.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-dss 
AAAAB3NzaC1kc3MAAACBAI5CPJHU7EwlZAikd/HKeT2DgXyLkzPcEGvCx8khhB/rDt+fINFgL5LoHGQyRNBbij02eSWg7CqikccnufAtPImlAHjRSpcls7yPcWEeTkCM5LYpd9xyDhzjx7qTct8asAZUMDoSDDeFPsudfwoQHOXzOsnGw60a+BypGJ5exCvbAAAAFQCnIccMCmjAzFX7zoneHBzkkrc2FwAAAIAlVueqBum5y6J/Q4zGHyry8rzA50dQpKu8hD9Tz7rVBinqBHMIRNoVESfHtoMqTA+8DtCka+34lBCqlL2t7LqcBQfWKY9hnSdqQFmzVezYxLI2I43t8JBevNtiMENhanVKoonOL0EHILdVY5LFVGKdOuP8Sj2lqWET614OthQn3gAAAIBS3GiAKU4QPGHzJbUAKKrs/FW3AGkgur0izOM3MgrYEl7q2B3GSYRUBGL+jPHcmziJYTbr0ttVRJyge/mf+fnSpm684IL8mnmytVnVpTy0iFwgafyLkE8Boy5b56s3n2sg/iI5yAOkgCar8gKsyPHXVTo92OtxT4jvrXZhTRONzA==
 eelco@disabn
diff --git a/nix/virtualbox-image-charon.nix b/nix/virtualbox-image-charon.nix
index bee4dd7..bac4e67 100644
--- a/nix/virtualbox-image-charon.nix
+++ b/nix/virtualbox-image-charon.nix
@@ -1,13 +1,26 @@
 { config, pkgs, ... }:
 
+let
+
+  clientKeyPath = "/root/.vbox-client-key";
+
+in
+
 { require = [ <nixos/modules/virtualisation/virtualbox-image.nix> ];
 
   services.openssh.enable = true;
 
-  # For now, use a hard-coded key to access the VirtualBox VM.  Since
-  # this is only for testing and they're not reachable from the
-  # outside, this is not a big problem.
-  users.extraUsers.root.openssh.authorizedKeys.keyFiles = [ 
./id_charon-virtualbox.pub ];
+  jobs."get-vbox-charon-client-key" =
+    { startOn = "starting sshd";
+      task = true;
+      path = [ config.boot.kernelPackages.virtualboxGuestAdditions ];
+      exec =
+        ''
+          VBoxControl -nologo guestproperty get 
/VirtualBox/GuestInfo/Charon/ClientPublicKey | sed 's/Value: //' > 
${clientKeyPath}
+        '';
+    };
+
+  users.extraUsers.root.openssh.authorizedKeys.keyFiles = [ clientKeyPath ];
 
   boot.vesa = false;
 }


================================================================

_______________________________________________
nix-commits mailing list
[email protected]
http://lists.science.uu.nl/mailman/listinfo/nix-commits

Reply via email to