Changeset 353db8c for fedd/federation


Ignore:
Timestamp:
Nov 23, 2010 5:00:48 PM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master
Children:
6e63513
Parents:
3ff5e2a
Message:

Vairous ABAC tweaks, mostly concerned with making key splitting less visible.

Location:
fedd/federation
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • fedd/federation/authorizer.py

    r3ff5e2a r353db8c  
    1111from remote_service import service_caller
    1212from service_error import service_error
     13from util import abac_pem_type, abac_split_cert
    1314
    1415
     
    192193    attribute_error = authorizer_base.attribute_error
    193194    class no_file(RuntimeError): pass
    194 
    195     def __init__(self, certs=None, me=None, key=None, load=None):
     195    class bad_cert(RuntimeError): pass
     196
     197    def __init__(self, certs=None, me=None, key=None, load=None, save=None):
    196198        self.creddy = '/usr/local/bin/creddy'
    197199        self.globals = set()
    198200        self.lock = Lock()
    199201        self.me = me
    200         self.key = key
     202        self.save_dir = load or save
     203        # If the me parameter is a combination certificate, split it into the
     204        # abac_authorizer save directory (if any) for use with creddy.
     205        if abac_pem_type(self.me) == 'both':
     206            if self.save_dir:
     207                self.key, self.me = abac_split_cert(self.me,
     208                        keyfile="%s/key.pem" % self.save_dir,
     209                        certfile = "%s/cert.pem" % self.save_dir)
     210            else:
     211                raise abac_authorizer.bad_cert("Combination certificate " + \
     212                        "and nowhere to split it");
     213        else:
     214            self.key = key
    201215        self.context = ABAC.Context()
    202216        if me:
     
    216230
    217231        if load:
    218             self.save_dir = load
    219232            self.load(load)
    220         else:
    221             self.save_dir = None
    222233
    223234    @staticmethod
     
    453464                st = pickle.load(f)
    454465                f.close()
    455                 # Cpoy the useful attributes from the pickled state
     466                # Copy the useful attributes from the pickled state
    456467                for a in ('globals', 'key', 'me', 'cert', 'fedid'):
    457468                    setattr(self, a, getattr(st, a, None))
  • fedd/federation/util.py

    r3ff5e2a r353db8c  
    22
    33import re
     4import os
    45import string
    56import logging
     
    262263            return base
    263264
     265def abac_pem_type(cert):
     266    key_re = re.compile('\s*-----BEGIN RSA PRIVATE KEY-----$')
     267    cert_re = re.compile('\s*-----BEGIN CERTIFICATE-----$')
     268    type = None
     269    f = open(cert, 'r')
     270    for line in f:
     271        if key_re.match(line):
     272            if type is None: type = 'key'
     273            elif type == 'cert': type = 'both'
     274        elif cert_re.match(line):
     275            if type is None: type = 'cert'
     276            elif type == 'key': type = 'both'
     277        if type == 'both': break
     278    f.close()
     279    return type
     280
     281def abac_split_cert(cert, keyfile=None, certfile=None):
     282    """
     283    Split the certificate file in cert into a certificate file and a key file
     284    in cf and kf respectively.  The ABAC tools generally cannot handle combined
     285    certificates/keys.  If kf anc cf are given, they are used, otherwise tmp
     286    files are created.  Created tmp files must be deleted.  Problems opening or
     287    writing files will cause exceptions.
     288    """
     289    class diversion:
     290        '''
     291        Wraps up the reqular expression to start and end a diversion, as well as
     292        the open file that gets the lines.
     293        '''
     294        def __init__(self, start, end, fn):
     295            self.start = re.compile(start)
     296            self.end = re.compile(end)
     297            # Open the file securely with minimal permissions. NB file cannot
     298            # exist before this call.
     299            self.f = os.fdopen(os.open(fn,
     300                (os.O_WRONLY | os.O_CREAT | os.O_TRUNC | os.O_EXCL), 0600),
     301                'w')
     302
     303        def close(self):
     304            self.f.close()
     305
     306    if not keyfile:
     307        f, keyfile = mkstemp(suffix=".pem")
     308        os.close(f);
     309    if not certfile:
     310        f, certfile = mkstemp(suffix=".pem")
     311        os.close(f);
     312
     313    # Initialize the diversions
     314    divs = [diversion(s, e, fn) for s, e,fn in (
     315        ('\s*-----BEGIN RSA PRIVATE KEY-----$',
     316            '\s*-----END RSA PRIVATE KEY-----$',
     317            keyfile),
     318        ('\s*-----BEGIN CERTIFICATE-----$',
     319            '\s*-----END CERTIFICATE-----$',
     320            certfile))]
     321
     322    # walk through the file, beginning a diversion when a start regexp
     323    # matches until the end regexp matches.  While in the two regexps,
     324    # print each line to the open diversion file (including the two
     325    # matches).
     326    active = None
     327    f = open(cert, 'r')
     328    for l in f:
     329        if active:
     330            if active.end.match(l):
     331                print >>active.f, l,
     332                active = None
     333        else:
     334            for d in divs:
     335                if d.start.match(l):
     336                    active = d
     337                    break
     338        if active: print >>active.f, l,
     339
     340    # This is probably unnecessary.  Close all the diversion files.
     341    for d in divs: d.close()
     342    return keyfile, certfile
     343
    264344def find_pickle_problem(o, st=None):
    265345    """
Note: See TracChangeset for help on using the changeset viewer.