Commit 8d719dd9 authored by Antoine Catton's avatar Antoine Catton

Add sshkeys_authority generic recipe

parent 0bc5ce04
......@@ -78,6 +78,8 @@ setup(name=name,
'siptester = slapos.recipe.siptester:SipTesterRecipe',
'simplelogger = slapos.recipe.simplelogger:Recipe',
'slaprunner = slapos.recipe.slaprunner:Recipe',
'sshkeys_authority = slapos.recipe.sshkeys_authority:Recipe',
'sshkeys_authority.request = slapos.recipe.sshkeys_authority:Request',
'stunnel = slapos.recipe.stunnel:Recipe',
'testnode = slapos.recipe.testnode:Recipe',
'urlparse = slapos.recipe.urlparse_:Recipe',
......
##############################################################################
#
# Copyright (c) 2010 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import json
import hashlib
import os
import subprocess
from slapos.recipe.librecipe import GenericBaseRecipe
from slapos.recipe.librecipe.inotify import subfiles
# This authority only works with dropbear sshkey generator
def sshkeys_authority(args):
requests_directory = args['requests']
keygen_binary = args['sshkeygen']
for request_filename in subfiles(requests_directory):
with open(request_filename) as request_file:
request = json.load(request_file)
key_type = request.get('type', 'rsa')
size = str(request.get('size', 2048))
try:
private_key = request['private_key']
public_key = request['public_key']
except KeyError:
break
if not os.path.exists(private_key):
keygen_cmd = [keygen_binary, '-t', key_type, '-f', private_key,
'-s', size]
# If the keygeneration return an non-zero status, it means there's a
# big problem. Let's exit in this case
subprocess.check_call(keygen_cmd, env=os.environ.copy())
if not os.path.exists(public_key):
keygen_cmd = [keygen_binary, '-f', private_key, '-y']
keygen = subprocess.Popen(keygen_cmd, stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=os.environ.copy())
keygen.stdin.flush()
keygen.stdin.close()
# If the keygeneration return an non-zero status, it means there's a
# big problem. Let's exit in this case
if keygen.wait() != 0:
raise subprocess.CalledProcessError("%r returned a non-zero status" % \
' '.join(keygen_cmd))
# Line : "Public key portion is :"
keygen.stdout.readline()
public_key_value = keygen.stdout.readline().strip()
with open(public_key, 'w') as public_key_file:
public_key_file.write(public_key_value)
class Recipe(GenericBaseRecipe):
def install(self):
args = dict(
requests=self.options['request-directory'],
sshkeygen=self.options['keygen-binary'],
)
wrapper = self.createPythonScript(self.options['wrapper'],
__name__ + '.sshkeys_authority', args)
return [wrapper]
class Request(GenericBaseRecipe):
def _options(self, options):
if 'name' not in options:
options['name'] = self.name
keys_directory = options['keys-directory']
self.private_key = os.path.join(keys_directory,
hashlib.sha256(options['name']).hexdigest())
self.public_key = self.private_key + '.pub'
if os.path.exists(self.public_key):
with open(self.public_key) as key:
options['public-key-value'] = key.read()
else:
options['public-key-value'] = ''
def install(self):
requests_directory = self.options['request-directory']
request_file = os.path.join(requests_directory, self.options['name'])
request = dict(
private_key=self.private_key,
public_key=self.public_key,
)
if 'size' in self.options:
request.update(size=int(self.options['size'], 10))
if 'type' in self.options:
request.update(type=self.options['type'])
with open(request_file, 'w') as file_:
json.dump(request, file_)
public_key_link, private_key_link = (self.options['public-key'],
self.options['private-key'],
)
# XXX: Copy and past from certificate_authority/__init__.py:Request
# We should factorize that
for link in [public_key_link, private_key_link]:
if os.path.islink(link):
os.unlink(link)
elif os.path.exists(link):
raise OSError("%r should be a symbolic link." % link)
os.symlink(self.public_key, public_key_link)
os.symlink(self.private_key, private_key_link)
# end-XXX
wrapper = self.createPythonScript(
self.options['wrapper'],
'slapos.recipe.librecipe.execute.execute_wait',
[ [self.options['executable']],
[self.private_key, self.public_key] ])
return [request_file, wrapper, public_key_link, private_key_link]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment