Changeset 387


Ignore:
Timestamp:
15/11/04 17:04:02 (15 years ago)
Author:
lawrence
Message:

Now supports XML input and output. Next step will be to provide web
service interfac, and address signing and checking of signatures.

Location:
security/trunk/python
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • security/trunk/python/AccessToken.py

    r381 r387  
    33#    Q Public License, version 1.0 or later 
    44# 
    5 # Version 0.1 BNL November 12, 2004 
     5# Version 0.2 BNL November 12, 2004 
    66 
    77from X500DN import X500DN 
     8import libxml2 
     9import StringIO 
     10from UserDict import UserDict 
    811 
    9 class Validity: 
    10   def __init__(self,start=(0,0,0,0,0),finish=(0,0,0,0,0)): 
    11     self.start=start 
    12     self.finish=finish 
    13   def checkvalid(now=None): 
    14     valid=0 
    15     if now is None: 
    16       pass 
    17       #really what we should do is get the current time 
    18     else: 
    19       valid=1 
    20       #for i in range(5): 
    21       #  if now[i]<self.start[i] or now[i]>self.finish[i]:valid=0 
    22     return valid 
    23  
    24 class AccessToken(Validity): 
     12class AccessToken(UserDict): 
    2513  ''' Handle an NDG token 
    26       Version 0.1, BNL, November 12, 2004 ''' 
     14      Version 0.2, BNL, November 12, 2004 ''' 
    2715 
    2816  def __init__(self,holder=None,issuer=None,dpat=None): 
    29     self.holder=X500DN() 
    30     self.issuer=X500DN() 
    31     self.signature='' 
    32     self.attributes=[] 
    33     Validity.__init__(self) 
     17    UserDict.__init__(self) 
     18    self['holder']=X500DN() 
     19    self['issuer']=X500DN() 
     20    self['signatureAlgorithm']='' 
     21    self['attributes']=[] 
     22    self['notBefore']=(0,0,0,0,0) 
     23    self['notAfter']=(0,0,0,0,0) 
    3424    if dpat!=None: 
    3525      self.xmlset(dpat) 
    3626    else: 
    3727      self.set(holder,issuer) 
     28    self['issuerName']='' 
     29    self['issuerSerialNumber']=0 
    3830 
    3931  def set(self,holder=None,issuer=None): 
    40     if holder is not None: self.holder.update(holder) 
    41     if issuer is not None: self.issuer.update(issuer) 
     32    if holder is not None: self['holder'].update(holder) 
     33    if issuer is not None: self['issuer'].update(issuer) 
    4234 
    43  
    44   def sign(self): 
     35  def sign(self,pemfile): 
    4536    pass    # for now  
    4637 
    47   def checkSig(self): 
     38  def checkSig(self,pemfile): 
    4839    return 1  #for now 
    4940     
    5041  def add(self,args): 
    51     self.attributes.extend(args) 
     42    self['attributes'].extend(args) 
    5243 
    5344  def show(self): 
    5445    lines='___________________' 
    5546    print lines,'  Holder  ',lines 
    56     for i in self.holder.keys(): 
    57       if self.holder[i] !='': print i,self.holder[i] 
     47    for i in self['holder'].keys(): 
     48      if self['holder'][i] !='': print i,self['holder'][i] 
    5849    print lines,'  Issuer  ', lines 
    59     for i in self.issuer.keys(): 
    60       if self.issuer[i] !='': print i,self.issuer[i] 
     50    for i in self['issuer'].keys(): 
     51      if self['issuer'][i] !='': print i,self['issuer'][i] 
    6152    print lines,'  Validity  ',lines[:-2] 
    62     print 'Valid from :', self.start,' to ',self.finish 
     53    print 'Valid from :', self['notBefore'],' to ',self['notAfter'] 
    6354 
    6455  def xmlset(self,dpat): 
    6556    ''' This piece of code parses an XML CLRC Data Portal Access Token 
    66     and sets this Access Token accordingly''' 
     57    and sets this Access Token accordingly. It is assumed that the 
     58    dpat is passed a string argument ''' 
     59    #note, choosing to use libxml2 here since we use it for the signatures 
     60    #anyway ... I might have chosen another parser otherwise. 
     61    doc=libxml2.parseDoc(dpat) 
     62    #check we can understand this certificate 
     63    #start by loading up a dictionary of the elements ... 
     64    ctxt=doc.xpathNewContext() 
     65    a=ctxt.xpathEval("/attributeCertificate/acInfo")[0] 
     66    # nb, this next statement produces a few nested elements that 
     67    # we can't use simply, but the bottom level ones (which 
     68    # are the ones we want) are done very quickly ... 
     69    token=dict([(i.name,i.content) for i in a]) 
     70    #ok, now go ahead and load up ... 
     71    #print token.keys() 
     72    if token['version'] != '1.0': 
     73      raise 'Access Token Version not recognised' 
     74    for i in ['version','signatureAlgorithm', 
     75              'notBefore','notAfter']: self[i]=token[i] 
     76    self.set(holder=token['holder'],issuer=token['issuer'])     
     77    #the C things need to be explicitly dereferenced I think 
     78    doc.freeDoc() 
     79    ctxt.xpathFreeContext() 
     80 
     81  def xml(self): 
     82    ''' This piece of code write a CCLRC Data Portal Access Token encoded in 
     83    XML ''' 
     84    s='<attributeCertificate><acInfo><version>1.0 </version>' 
     85    for i in ('holder','issuer'): 
     86      s+='<'+i+'>'+self[i].serialise()+'</'+i+'>' 
     87    s+=self.xmlkey('issuerName','issuerSerialNumber','signatureAlgorithm') 
     88    s+='<validity>'+self.xmlkey('notBefore','notAfter')+'</validity>' 
     89    s+='<attributes>' 
     90    for i in self['attributes']:s+=i+',' 
     91    s=s[:-1]+'</attributes></acinfo>' 
     92    s+='SignatureGoesHere'  # we'll do this properly when we know how 
     93    s+='</attributeCertificate>' 
     94    return s 
    6795    pass 
    6896 
    69   def xmlout(self): 
    70     ''' This piece of code write a CCLRC Data Portal Access Token encoded in 
    71     XML ''' 
    72     dpat='' 
    73     return dpat 
    74     pass 
     97  def xmlkey(self,*arglist): 
     98    s='' 
     99    for i in arglist: 
     100      s+='%s%s%s%s%s%s%s'%('<',str(i),'>',str(self[i]),'</',str(i),'>') 
     101    return s 
    75102 
    76103if __name__=='__main__': 
    77104  print 'demonstrate use of Access Token' 
    78   holder=X500DN({'DN':'Bryan Lawrence','O':'NERC DataGrid','C':'UK'}) 
    79   issuer=X500DN({'DN':'NDG Data Provider','O':'BADC','C':'UK'}) 
     105  holder=X500DN({'CN':'Bryan Lawrence','O':'NERC DataGrid','C':'UK'}) 
     106  issuer=X500DN({'CN':'NDG Data Provider','O':'BADC','C':'UK'}) 
    80107  at=AccessToken(holder=holder,issuer=issuer) 
    81108  at.show() 
     109  # 
     110  f=open('../ws.cred','r') 
     111  dpat=f.read() 
     112  at=AccessToken(dpat=dpat) 
     113  y=at.xml() 
     114  print y 
  • security/trunk/python/X500DN.py

    r381 r387  
    33#    Q Public License, version 1.0 or later 
    44# 
    5 # Version 0.1 BNL November 12, 2004 
     5# Version 0.2 BNL November 15, 2004 
    66# 
    77from UserDict import UserDict 
     
    1515                   'O':'Organisation', 
    1616                   'C':'CountryName', 
    17                    'EMAIL':'Email Address', 
     17                   'EMAILADDRESS':'Email Address', 
    1818                   'L':'localityName', 
    1919                   'ST':'stateOrProvinceName', 
     
    2121                   'UID':'userid'} 
    2222    UserDict.__init__(self,self.longNames) 
    23   
    2423    self._clear() 
    2524    if argdict is not None: 
    26       for i in argdict: self.data[i]=argdict[i] 
    27  
     25      self.update(argdict) 
     26         
    2827  def _clear(self): 
    2928    for i in self.keys(): self.data[i]='' 
     
    3332 
    3433  def __setitem__(self,key,item): 
    35     if key not in self.data.keys(): 
     34    if key not in self.longNames.keys(): 
    3635      raise 'Key '+key+' not known in X500DN ' 
    3736    self.data[key]=item 
     37 
     38  def update(self,dict): 
     39    #check and see if it is a dict, if not, deserialise 
     40    if dict.__class__() == '': 
     41      self.deserialise(dict) 
     42    else: 
     43      for k,i in dict.items(): 
     44        k=k.join(k.split()) 
     45        self.__setitem__(k,i) 
    3846 
    3947  def serialise(self): 
     
    5159    list=s.split(',') 
    5260    self._clear() 
    53     for item in list: 
    54       key,value=item.split('=') 
    55       self.data[key]=value 
     61    print list 
     62    argdict=dict([ item.split('=') for item in list]) 
     63    self.update(argdict) 
     64    #for item in list: 
     65    # key,value=item.split('=') 
     66    # self.data[key]=value 
    5667 
    5768if __name__=='__main__': 
     
    6677  print 'show the serialisation' 
    6778  print y.serialise() 
    68   y.deserialise('DN = Another Bryan, C = Another place') 
     79  print 'show use of deserialising for instantiation' 
     80  y=X500DN('CN = Another Bryan, C = Another place') 
    6981  print y 
    70  
    71   y['ABC']='bnl' #should break 
     82  print 'Next statement should break with a key error!' 
     83  y=X500DN('ABC=bnl') 
    7284   
Note: See TracChangeset for help on using the changeset viewer.