Changeset 422


Ignore:
Timestamp:
10/06/05 18:10:08 (14 years ago)
Author:
pjkersha
Message:

AttrAuthority?: modified createAttrCert() to return the new attribute
certificate on success.

User: renamed from UserCredentials?. Added Login class from login.cgi.
Working version for getting a new proxy certificate from MyProxy? and
instantiating a wallet object.

Added reqAuthorisation to CredWallet? class to call AttrAuthority? WS to
request an Attribute Certificate.

X509: fix to parse method to make sure member variables are updated from
new M2Crypto X509 cert object.

xmlSigDoc: added asString() method to return file content as a string. -
Needs testing.

login.cgi: Login class moved into User package.

Location:
security/trunk/python
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • security/trunk/python/NDG.BAK/AttAuthority.py

    r420 r422  
    338338            attrCert.isValid(raiseExcep=True) 
    339339             
    340             # Write out certificate 
     340            # Write out certificate to keep a record of it for auditing 
    341341            attrCert.write() 
    342                  
     342 
     343            # Return the text to caller 
     344            return attrCert.asString() 
     345         
    343346        except AttrCertError, excep: 
    344347            raise AttrAuthorityError("New Attribute Certificate \"%s\": %s" %\ 
  • security/trunk/python/NDG.BAK/UserCredentials.py

    r418 r422  
    1414cvsID = '$Id$' 
    1515 
     16import sys 
     17import pdb 
     18 
     19# CGI for Login class 
     20import cgi 
     21 
    1622# SQLObject Database interface 
    1723from sqlobject import * 
    18 import sys 
    19 import pdb 
    2024 
    2125# Create unique name for certificate temporary file 
    2226import tempfile 
    2327 
     28# Authentication X.509 Certificate 
    2429from X509 import * 
     30 
     31# Authorisation - attribute certificate  
    2532from AttrCert import * 
    26  
    2733 
    2834 
     
    4147 
    4248 
     49 
     50#_____________________________________________________________________________ 
     51class Login: 
     52    """CGI for NDG Login""" 
     53     
     54    def __init__(self, userName='', passPhrase=''): 
     55        """Omit username and passphrase if running as CGI script""" 
     56         
     57        self.__userName = userName 
     58        self.__passPhrase = passPhrase 
     59 
     60        if userName == '': 
     61            self.__bCGI = True 
     62        else: 
     63            self.__bCGI = False 
     64             
     65         
     66    def cgi(self):         
     67        """Two stage process - login followed by authentication.  If 
     68        authentication fails re-call login.""" 
     69 
     70        if not self.__bCGI: 
     71            raise UserCredentialsError("Username and password have been set") 
     72         
     73        # Use userName field to flag authentication call         
     74        form = cgi.FieldStorage() 
     75        if form.has_key("userName") and form["userName"].value != "": 
     76 
     77            # Preceeding page was login form - proceed with authentication 
     78            self.__userName = form["userName"].value 
     79 
     80            if form.has_key("passPhrase"): 
     81                self.__passPhrase = form["passPhrase"].value 
     82            else: 
     83                self.__passPhrase = None 
     84 
     85            # Authenticate user and generate a proxy certificate for them   
     86            self.authenticate() 
     87             
     88        else: 
     89            # Initial login 
     90            self.showLogin() 
     91 
     92 
     93    def showLogin(self): 
     94        """Display initial NDG login form""" 
     95        print \ 
     96""" 
     97<HTML> 
     98<HEAD> 
     99<TITLE>NDG Login (Test)</TITLE> 
     100<SCRIPT LANGUAGE="JavaScript1.1"> 
     101<!-- 
     102function isblank(s) 
     103{ 
     104  for (var i=0; i < s.length; i++){ 
     105    var c=s.charAt(i) 
     106    if ((c != ' ') && (c = '\n') && (c != '/t')) return false; 
     107  } 
     108  return true; 
     109} 
     110 
     111function check_logon(f) 
     112{ 
     113  var empty_fields = 0; 
     114  var e = f._home; 
     115  if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
     116      empty_fields ++; 
     117  } 
     118  e = f._gohome; 
     119  if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
     120      empty_fields ++; 
     121  } 
     122  if (!empty_fields) { 
     123     f._md5.value = hex_md5 (f._gohome.value); 
     124//   ash f._gohome.value = "";       
     125     return true; 
     126  }    
     127   
     128  alert("\nLogin Invalid:\nYou must complete both User name and Password\n"); 
     129  return false; 
     130} 
     131// --> 
     132</SCRIPT> 
     133 
     134<script language="JavaScript" src="http://badc.nerc.ac.uk/javascript/md5.js"></script> 
     135</HEAD> 
     136<BODY BGCOLOR=#FFFFFF onLoad="document.forms[0]._home.focus()"> 
     137<H2>Login to the NERC Data Grid (Test only!)<BR clear=all></H2> 
     138<HR> 
     139<P> 
     140 
     141<!-- Database connection ok --> 
     142 
     143<FORM ACTION="../../cgi-bin/login.cgi" METHOD="POST"  
     144      onSubmit="return check_logon(this);"> 
     145 
     146<TABLE BGCOLOR=#ADD8E6 cellspacing=0 border=0 cellpadding=5> 
     147<TR><TD>User Name:</TD> <TD><INPUT TYPE=text NAME=userName value=""></TD></TR> 
     148<TR><TD>Password:</TD><TD><INPUT TYPE=password NAME=passPhrase></TD></TR> 
     149<TR><TD colspan="2" align="right"><INPUT TYPE=submit value="Login"></TD></TR> 
     150</TABLE> 
     151 
     152</FORM> 
     153<em>Problems logging on? Contact <a href="http://badc.nerc.ac.uk/help/contact.html">BADC support</a> for help. </em> 
     154</body></html> 
     155""" 
     156    # end of showLogin() 
     157     
     158     
     159     
     160    def authenticate(self): 
     161 
     162        """Authenticate username and passphrase input from preceeding login 
     163        form""" 
     164         
     165        try: 
     166            if self.__passPhrase is None: 
     167                raise "No passphrase input" 
     168             
     169            if self.__bCGI: 
     170                print "Content-type: text/html\n" 
     171                print "<Title>NDG User Authentication (Test)</Title>" 
     172 
     173            proxySrv = ProxyServer() 
     174            proxyCert = proxySrv.getProxyCert(self.__userName, 
     175                                              self.__passPhrase) 
     176 
     177            if self.__bCGI: 
     178                print "<p>User %s authenticated</p>" % self.__userName 
     179 
     180            # Create a new user session 
     181            return UserSession(proxyCert) 
     182 
     183        except Exception, e: 
     184                        
     185            # Re-display login screen 
     186            if self.__bCGI: 
     187                print "<p>Authentication failed for user %s</p>" % \ 
     188                      self.__userName 
     189                self.showLogin() 
     190             
     191            raise UserCredentialsError("Login failed: " + str(e)) 
     192 
     193 
     194 
     195 
    43196#_____________________________________________________________________________ 
    44197class UserSession: 
     
    49202 
    50203        try: 
    51             if not isintance(proxyCert, basestring): 
     204            if not isinstance(proxyCert, basestring): 
    52205                raise UserCredentialsError(\ 
    53206                    "Proxy Certificate must be input as a string") 
     
    64217        # Make a new credentials wallet - this holds authorisation 
    65218        # credentials for the current session 
    66         self.credWallet = CredWallet(dn) 
     219        # 
     220        # ! Make properties file path some kind of system resource e.g. 
     221        # env variable 
     222        propertiesFilePath = \ 
     223    '/home/users/pjkersha/Development/security/python/credReposProperties.xml' 
     224         
     225        self.credWallet = CredWallet(dn, 
     226                                     propertiesFilePath=propertiesFilePath) 
    67227 
    68228 
     
    77237    def __init__(self): 
    78238        """Initialise proxy certificate generation settings""" 
     239 
     240        # Transfer these to a properties file? 
    79241        self.__getProxyCertExe = \ 
    80242            "/usr/local/globus-3.9.5/bin/myproxy-get-delegation" 
     
    100262                                                    proxyCertFilePath) 
    101263             
    102             getProxyCertCmd = "%s %s" % (getProxyCertExe, getProxyCertArgs) 
     264            getProxyCertCmd = "%s %s" % (self.__getProxyCertExe, 
     265                                         getProxyCertArgs) 
    103266 
    104267 
     
    113276                sProxyCert = proxyCertFile.read() 
    114277                proxyCertFile.close() 
    115                 remove(proxyCertFilePath) 
     278                os.remove(proxyCertFilePath) 
    116279                 
    117280                return sProxyCert 
    118281            else: 
    119                 raise UserCredentialsError(\ 
    120                         "Error getting proxy certificate for %s" % userName) 
    121          
    122         except Exception, e: 
    123             try: remove(proxyCertFilePath) 
     282                raise UserCredentialsError("Command failed") 
     283         
     284        except Exception, e: 
     285            try: os.remove(proxyCertFilePath) 
    124286            except: pass 
    125287            raise UserCredentialsError(\ 
    126                 "Error getting proxy certificate for %s: %s" % \ 
    127                                                             (userName, str(e)) 
     288                "Error getting proxy certificate for user %s: %s" % \ 
     289                                                        (userName, str(e))) 
    128290 
    129291 
     
    133295    """Volatile store of user credentials associated with a user session""" 
    134296 
    135     def __init__(self, dn, credReposDbURI=None): 
     297    def __init__(self, dn, **credReposKeys): 
    136298        """Create store of user credentials for their current session 
    137299 
     
    143305                raise UserCredentialsError("User DN must be a valid string") 
    144306        except Exception, e: 
    145             raise UserCredentialsError("Input userName: " + str(e)) 
     307            raise UserCredentialsError("Input DN: " + str(e)) 
    146308 
    147309        self.__dn = dn 
    148310 
     311 
     312        # Make a connection to the Credentials Repository 
     313        try: 
     314            self.__credRepos = CredRepos(**credReposKeys) 
     315        except Exception, e: 
     316            raise "Error accessing credentials repository: " + str(e) 
     317         
    149318         
    150319        # List of credentials held in this wallet - each credential is an 
     
    153322 
    154323 
    155         # Look up user in the Credentials Repository db 
    156          
    157         # Connect and check for valid attribute certificates for the user 
     324        # Check for valid attribute certificates for the user 
     325        try: 
     326            userCred = self.__credRepos.getCredentials(dn) 
     327 
     328        except Exception, e: 
     329            raise UserCredentials( 
     330                "Error updating wallet with credentials from repository:" + \ 
     331                str(e)) 
     332 
     333        # Update wallet with attribute certificates from the repository 
     334        self.__attrCertList = [i.attrCert for i in userCred] 
     335         
     336        # Filter out expired certificates 
     337        self.audit() 
     338 
    158339         
    159340         
     
    162343        out of scope.""" 
    163344        self.updateCredRepos() 
     345 
     346 
    164347         
    165348         
     
    189372 
    190373 
     374 
     375 
    191376    def audit(self): 
    192377        """Check the credentials held in the wallet removing any that have 
     
    194379         
    195380        self.__attrCertList = filter(attrCert.isValid(), self.__attrCertList) 
     381 
     382 
    196383 
    197384                 
     
    214401    """Interface to Credentials Repository Database""" 
    215402 
    216     def __init__(self, dbURI=None): 
     403    def __init__(self, dbURI=None, propertiesFilePath=None): 
    217404        """Initialise Credentials Repository Database object. 
    218405 
    219         If the connection string is set a connection will be made 
    220  
    221         dbURI: '<db type>://<username>:<passwd>:<hostname>/dbname""" 
     406        If the connection string or properties file is set a connection 
     407        will be made 
     408 
     409        dbURI:              <db type>://<username>:<passwd>@<hostname>/dbname 
     410        propertiesFilePath: file path to properties file 
     411 
     412        Nb. propertiesFilePath setting overrides input dbURI 
     413        """ 
     414 
     415        if propertiesFilePath is not None and \ 
     416           not isinstance(propertiesFilePath, basestring): 
     417            raise UserCredentialsError("Input Properties file path " + \ 
     418                                       "must be a valid string.") 
     419             
     420        self.__propertiesFilePath = propertiesFilePath 
    222421        self.__con = None 
    223         if dbURI: self.setConnection(dbURI) 
     422        pdb.set_trace() 
     423        if self.__propertiesFilePath is not None: 
     424             
     425            # Read database URI set in file 
     426            dbURI = self.readPropertiesFile() 
     427 
     428        # Database URI may have been set as an input argument or via the 
     429        # properties file 
     430        if dbURI is not None: self.setConnection(dbURI) 
     431 
     432 
    224433 
    225434 
     
    238447        CredRepos.User._connection = self.__con 
    239448        CredRepos.UserCredential._connection = self.__con 
     449 
     450 
    240451             
    241452 
     
    257468                self.UserCredential.delete(cred.id) 
    258469                 
     470 
     471 
     472         
     473    def readPropertiesFile(self, propertiesFilePath=None): 
     474 
     475        """Read the configuration properties for the Attribute Authority 
     476 
     477        propertiesFilePath: file path to properties file 
     478        """ 
     479 
     480        if propertiesFilePath is not None: 
     481            if not isinstance(propertiesFilePath, basestring): 
     482                raise UserCredentialsError("Input Properties file path " + \ 
     483                      "must be a valid string.") 
     484             
     485            self.__propertiesFilePath = propertiesFilePath 
     486 
     487 
     488        try: 
     489            tree = ElementTree.parse(self.__propertiesFilePath) 
     490             
     491        except IOError, ioErr: 
     492            raise UserCredentialsError(\ 
     493                "Error parsing properties file \"%s\": %s" % \ 
     494                                (ioErr.filename, ioErr.strerror)) 
     495 
     496         
     497        aaProp = tree.getroot() 
     498 
     499        # Copy properties from file as member variables 
     500        properties = dict([(elem.tag, elem.text) for elem in aaProp]) 
     501         
     502        self.__dbURI = properties['dbURI'] 
     503 
     504 
     505 
     506 
     507    def getCredentials(self, dn): 
     508        """Get the list of credentials for a given user's DN""" 
     509 
     510        try: 
     511            return self.UserCredential.selectBy(dn=dn) 
     512             
     513        except Exception, e: 
     514            raise UserCredentialsError("Selecting credentials for %s: %s", 
     515                                       dn, str(e)) 
     516 
     517 
     518 
    259519         
    260520    def addCredentials(self, dn, attrCertList): 
     
    266526         
    267527        try: 
    268             userCred = self.UserCredential.selectBy(userName=userName) 
    269              
    270         except Exception, e: 
    271             raise UserCredentialsError("Selecting credentials for %s: %s", 
    272                                        dn, str(e)) 
     528            userCred = self.getCredentials(dn) 
     529             
     530        except Exception, e: 
     531            raise e 
    273532 
    274533 
  • security/trunk/python/NDG.BAK/X509.py

    r420 r422  
    1717 
    1818# Handle not before and not after strings 
    19 from datetime import * 
     19from time import strftime 
     20from time import strptime 
     21from datetime import datetime 
    2022 
    2123import M2Crypto 
     
    8890                                (self.__filePath, str(e))) 
    8991 
     92        # Update DN and validity times from M2Crypto X509 object just 
     93        # created 
     94        self.__setFromM2Crypto() 
     95 
     96 
     97 
     98         
     99    def parse(self, certTxt): 
     100        """Read a certificate input as a string""" 
     101 
     102        try: 
     103            certBIO = M2Crypto.BIO.MemoryBuffer(certTxt) 
     104            self.__m2CryptoX509 = M2Crypto.X509.load_cert_bio(certBIO) 
     105             
     106        except Exception, e: 
     107            raise X509CertError("Error loading certificate: %s" % str(e)) 
     108 
     109        # Update DN and validity times from M2Crypto X509 object just 
     110        # created 
     111        self.__setFromM2Crypto() 
     112 
     113 
     114         
     115         
     116    def __setFromM2Crypto(self): 
     117        """Private method allows class members to be updated from the 
     118        current M2Crypto object.  __m2CryptoX509 must have been set.""" 
     119         
    90120        # Get distinguished name 
    91121        m2CryptoX509Name = self.__m2CryptoX509.get_subject() 
     
    100130        # formatted strings and then parse them in order to create a datetime 
    101131        # type 
    102         datetimeRe = "([a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}).*" 
    103         datetimeFmt = "%b %d %H:%M:%S %Y" 
    104132         
    105133        try: 
    106             # Check for expected format - string may have trailing GMT - ingore             
    107             sNotBefore = re.findall(datetimeRe, 
    108                                     str(self.__m2CryptoX509.get_not_before()) 
    109             lNotBefore = strptime(sNotBefore, datetimeFmt)[0:5] 
    110  
    111             self.__dtNotBefore = datetime(lTime[0], lTime[1], lTime[2], 
    112                                           lTime[3], lTime[4], lTime[5]) 
     134            m2CryptoNotBefore = self.__m2CryptoX509.get_not_before() 
     135            self.__dtNotBefore=self.__m2CryptoUTC2datetime(m2CryptoNotBefore) 
     136                                         
     137        except Exception, e: 
     138            raise X509CertError("Not Before time: " + str(e)) 
     139 
     140         
     141        try: 
     142            m2CryptoNotAfter = self.__m2CryptoX509.get_not_after() 
     143            self.__dtNotAfter=self.__m2CryptoUTC2datetime(m2CryptoNotAfter) 
    113144                                     
    114145        except Exception, e: 
    115             raise X509CertError("Error parsing not before time: " + str(e)) 
    116  
    117          
    118         try: 
    119             # Check for expected format - string may have trailing GMT - ingore             
    120             sNotAfter = re.findall(datetimeRe, 
    121                                    str(self.__m2CryptoX509.get_not_before()) 
    122             lNotAfter = strptime(sNotAfter, datetimeFmt)[0:5] 
    123  
    124             self.__dtNotAfter = datetime(lTime[0], lTime[1], lTime[2], 
    125                                          lTime[3], lTime[4], lTime[5]) 
    126                                      
    127         except Exception, e: 
    128             raise X509CertError("Error parsing not after time: " + str(e)) 
    129  
    130  
    131  
    132          
    133     def parse(self, certTxt): 
    134         """Read a certificate input as a string""" 
    135  
    136         try: 
    137             certBIO = M2Crypto.BIO.MemoryBuffer(certTxt) 
    138             self.__m2CryptoX509 = M2Crypto.X509.load_cert_bio(certBIO) 
    139              
    140         except Exception, e: 
    141             raise X509CertError("Error loading certificate: %s" % str(e)) 
    142          
    143          
    144     def string(self, filePath=None): 
     146            raise X509CertError("Not After time: " + str(e)) 
     147 
     148 
     149 
     150         
     151    def asString(self, filePath=None): 
    145152        """Return certificate file content as a string""" 
    146153         
     
    226233        dtNow = datetime.utcnow() 
    227234        return dtNow > self.__dtNotBefore and dtNow < self.__dtNotAfter 
     235 
     236 
     237 
     238 
     239    def __m2CryptoUTC2datetime(self, m2CryptoUTC): 
     240        """Convert M2Crypto UTC time string as returned by get_not_before/ 
     241        get_not_after methods into datetime type""" 
     242         
     243        datetimeRe = "([a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}).*" 
     244 
     245        try: 
     246            # Convert into string 
     247            sM2CryptoUTC = str(m2CryptoUTC) 
     248             
     249            # Check for expected format - string may have trailing GMT - ignore 
     250            sTime = re.findall(datetimeRe, sM2CryptoUTC)[0] 
     251 
     252            # Convert into a tuple 
     253            lTime = strptime(sTime, "%b %d %H:%M:%S %Y")[0:6] 
     254 
     255            return datetime(lTime[0], lTime[1], lTime[2], 
     256                            lTime[3], lTime[4], lTime[5]) 
     257                                     
     258        except Exception, e: 
     259            raise X509CertError("Parsing M2Crypto UTC time: " + str(e)) 
    228260         
    229261 
  • security/trunk/python/NDG.BAK/login.cgi

    r418 r422  
    1515cvsID = '$Id$' 
    1616 
    17 import sys 
    18 import os 
    19 import cgi 
    20  
    21 # Temporary measure! 
    22 sys.path.append('/home/users/pjkersha/Development/security/python') 
    23 from UserCredentials import * 
    24  
    25  
    26 class Login: 
    27     """CGI for NDG Login""" 
    28      
    29     def __init__(self): 
    30          
    31         """Two stage process - login followed by authentication.  If 
    32         authentication fails re-call login.""" 
    33          
    34         # Use userName field to flag authentication call         
    35         form = cgi.FieldStorage() 
    36         if form.has_key("userName") and form["userName"].value != "": 
    37  
    38             # Preceeding page was login form - proceed with authentication 
    39             self.__userName = form["userName"].value 
    40  
    41             if form.has_key("passPhrase"): 
    42                 self.__passPhrase = form["passPhrase"].value 
    43             else: 
    44                 self.__passPhrase = None 
    45  
    46             # Authenticate user and generate a proxy certificate for them   
    47             self.authenticate() 
    48              
    49         else: 
    50             # Initial login 
    51             self.showLogin() 
    52  
    53  
    54     def showLogin(): 
    55         """Display initial NDG login form""" 
    56         print \ 
    57 """ 
    58 <HTML> 
    59 <HEAD> 
    60 <TITLE>NDG Login (Test)</TITLE> 
    61 <SCRIPT LANGUAGE="JavaScript1.1"> 
    62 <!-- 
    63 function isblank(s) 
    64 { 
    65   for (var i=0; i < s.length; i++){ 
    66     var c=s.charAt(i) 
    67     if ((c != ' ') && (c = '\n') && (c != '/t')) return false; 
    68   } 
    69   return true; 
    70 } 
    71  
    72 function check_logon(f) 
    73 { 
    74   var empty_fields = 0; 
    75   var e = f._home; 
    76   if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
    77       empty_fields ++; 
    78   } 
    79   e = f._gohome; 
    80   if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
    81       empty_fields ++; 
    82   } 
    83   if (!empty_fields) { 
    84      f._md5.value = hex_md5 (f._gohome.value); 
    85 //   ash f._gohome.value = "";       
    86      return true; 
    87   }    
    88    
    89   alert("\nLogin Invalid:\nYou must complete both User name and Password\n"); 
    90   return false; 
    91 } 
    92 // --> 
    93 </SCRIPT> 
    94  
    95 <script language="JavaScript" src="http://badc.nerc.ac.uk/javascript/md5.js"></script> 
    96 </HEAD> 
    97 <BODY BGCOLOR=#FFFFFF onLoad="document.forms[0]._home.focus()"> 
    98 <H2>Login to the NERC Data Grid (Test only!)<BR clear=all></H2> 
    99 <HR> 
    100 <P> 
    101  
    102 <!-- Database connection ok --> 
    103  
    104 <FORM ACTION="../../cgi-bin/login.cgi" METHOD="POST"  
    105       onSubmit="return check_logon(this);"> 
    106  
    107 <TABLE BGCOLOR=#ADD8E6 cellspacing=0 border=0 cellpadding=5> 
    108 <TR><TD>User Name:</TD> <TD><INPUT TYPE=text NAME=userName value=""></TD></TR> 
    109 <TR><TD>Password:</TD><TD><INPUT TYPE=password NAME=passPhrase></TD></TR> 
    110 <TR><TD colspan="2" align="right"><INPUT TYPE=submit value="Login"></TD></TR> 
    111 </TABLE> 
    112  
    113 </FORM> 
    114 <em>Problems logging on? Contact <a href="http://badc.nerc.ac.uk/help/contact.html">BADC support</a> for help. </em> 
    115 </body></html> 
    116 """ 
    117     # end of showLogin() 
    118      
    119      
    120      
    121     def authenticate(self): 
    122  
    123         """Authenticate username and passphrase input from preceeding login 
    124         form""" 
    125          
    126         try: 
    127             if self.__passPhrase is None: 
    128                 raise "No passphrase input" 
    129              
    130             print "Content-type: text/html\n" 
    131             print "<Title>NDG User Authentication (Test)</Title>" 
    132  
    133             proxySrv = ProxyServer(self.__userName, self.__passPhrase) 
    134             proxyCert = proxyCrv.getProxyCert() 
    135             print "<p>User %s authenticated</p>" % self.__userName 
    136  
    137             # Create a new user session 
    138         except Exception, e: 
    139              
    140             print "<p>Authentication failed for user %s</p>" % self.__userName 
    141             # Re-display login screen 
    142             self.showLogin() 
    143             raise "Login failed: %s" % str(e) 
    144  
    145  
     17from NDG.UserCredentials import * 
    14618 
    14719   
  • security/trunk/python/NDG.BAK/xmlSigDoc.py

    r417 r422  
    300300            self.__keysMngr.destroy() 
    301301            self.__bkeysMngrFreed = True 
     302 
     303 
     304 
     305 
     306    def asString(self, filePath=None): 
     307        """Return certificate file content as a string""" 
     308         
     309        # Check libxml2.xmlDoc object has been instantiated - if not call 
     310        # read method 
     311        if self.__libxml2Doc is None: 
     312            self.read(filePath) 
     313             
     314        return self.__libxml2Doc.dump() 
    302315 
    303316 
  • security/trunk/python/NDG/AttAuthority.py

    r420 r422  
    338338            attrCert.isValid(raiseExcep=True) 
    339339             
    340             # Write out certificate 
     340            # Write out certificate to keep a record of it for auditing 
    341341            attrCert.write() 
    342                  
     342 
     343            # Return the text to caller 
     344            return attrCert.asString() 
     345         
    343346        except AttrCertError, excep: 
    344347            raise AttrAuthorityError("New Attribute Certificate \"%s\": %s" %\ 
  • security/trunk/python/NDG/UserCredentials.py

    r418 r422  
    1414cvsID = '$Id$' 
    1515 
     16import sys 
     17import pdb 
     18 
     19# CGI for Login class 
     20import cgi 
     21 
    1622# SQLObject Database interface 
    1723from sqlobject import * 
    18 import sys 
    19 import pdb 
    2024 
    2125# Create unique name for certificate temporary file 
    2226import tempfile 
    2327 
     28# Authentication X.509 Certificate 
    2429from X509 import * 
     30 
     31# Authorisation - attribute certificate  
    2532from AttrCert import * 
    26  
    2733 
    2834 
     
    4147 
    4248 
     49 
     50#_____________________________________________________________________________ 
     51class Login: 
     52    """CGI for NDG Login""" 
     53     
     54    def __init__(self, userName='', passPhrase=''): 
     55        """Omit username and passphrase if running as CGI script""" 
     56         
     57        self.__userName = userName 
     58        self.__passPhrase = passPhrase 
     59 
     60        if userName == '': 
     61            self.__bCGI = True 
     62        else: 
     63            self.__bCGI = False 
     64             
     65         
     66    def cgi(self):         
     67        """Two stage process - login followed by authentication.  If 
     68        authentication fails re-call login.""" 
     69 
     70        if not self.__bCGI: 
     71            raise UserCredentialsError("Username and password have been set") 
     72         
     73        # Use userName field to flag authentication call         
     74        form = cgi.FieldStorage() 
     75        if form.has_key("userName") and form["userName"].value != "": 
     76 
     77            # Preceeding page was login form - proceed with authentication 
     78            self.__userName = form["userName"].value 
     79 
     80            if form.has_key("passPhrase"): 
     81                self.__passPhrase = form["passPhrase"].value 
     82            else: 
     83                self.__passPhrase = None 
     84 
     85            # Authenticate user and generate a proxy certificate for them   
     86            self.authenticate() 
     87             
     88        else: 
     89            # Initial login 
     90            self.showLogin() 
     91 
     92 
     93    def showLogin(self): 
     94        """Display initial NDG login form""" 
     95        print \ 
     96""" 
     97<HTML> 
     98<HEAD> 
     99<TITLE>NDG Login (Test)</TITLE> 
     100<SCRIPT LANGUAGE="JavaScript1.1"> 
     101<!-- 
     102function isblank(s) 
     103{ 
     104  for (var i=0; i < s.length; i++){ 
     105    var c=s.charAt(i) 
     106    if ((c != ' ') && (c = '\n') && (c != '/t')) return false; 
     107  } 
     108  return true; 
     109} 
     110 
     111function check_logon(f) 
     112{ 
     113  var empty_fields = 0; 
     114  var e = f._home; 
     115  if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
     116      empty_fields ++; 
     117  } 
     118  e = f._gohome; 
     119  if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
     120      empty_fields ++; 
     121  } 
     122  if (!empty_fields) { 
     123     f._md5.value = hex_md5 (f._gohome.value); 
     124//   ash f._gohome.value = "";       
     125     return true; 
     126  }    
     127   
     128  alert("\nLogin Invalid:\nYou must complete both User name and Password\n"); 
     129  return false; 
     130} 
     131// --> 
     132</SCRIPT> 
     133 
     134<script language="JavaScript" src="http://badc.nerc.ac.uk/javascript/md5.js"></script> 
     135</HEAD> 
     136<BODY BGCOLOR=#FFFFFF onLoad="document.forms[0]._home.focus()"> 
     137<H2>Login to the NERC Data Grid (Test only!)<BR clear=all></H2> 
     138<HR> 
     139<P> 
     140 
     141<!-- Database connection ok --> 
     142 
     143<FORM ACTION="../../cgi-bin/login.cgi" METHOD="POST"  
     144      onSubmit="return check_logon(this);"> 
     145 
     146<TABLE BGCOLOR=#ADD8E6 cellspacing=0 border=0 cellpadding=5> 
     147<TR><TD>User Name:</TD> <TD><INPUT TYPE=text NAME=userName value=""></TD></TR> 
     148<TR><TD>Password:</TD><TD><INPUT TYPE=password NAME=passPhrase></TD></TR> 
     149<TR><TD colspan="2" align="right"><INPUT TYPE=submit value="Login"></TD></TR> 
     150</TABLE> 
     151 
     152</FORM> 
     153<em>Problems logging on? Contact <a href="http://badc.nerc.ac.uk/help/contact.html">BADC support</a> for help. </em> 
     154</body></html> 
     155""" 
     156    # end of showLogin() 
     157     
     158     
     159     
     160    def authenticate(self): 
     161 
     162        """Authenticate username and passphrase input from preceeding login 
     163        form""" 
     164         
     165        try: 
     166            if self.__passPhrase is None: 
     167                raise "No passphrase input" 
     168             
     169            if self.__bCGI: 
     170                print "Content-type: text/html\n" 
     171                print "<Title>NDG User Authentication (Test)</Title>" 
     172 
     173            proxySrv = ProxyServer() 
     174            proxyCert = proxySrv.getProxyCert(self.__userName, 
     175                                              self.__passPhrase) 
     176 
     177            if self.__bCGI: 
     178                print "<p>User %s authenticated</p>" % self.__userName 
     179 
     180            # Create a new user session 
     181            return UserSession(proxyCert) 
     182 
     183        except Exception, e: 
     184                        
     185            # Re-display login screen 
     186            if self.__bCGI: 
     187                print "<p>Authentication failed for user %s</p>" % \ 
     188                      self.__userName 
     189                self.showLogin() 
     190             
     191            raise UserCredentialsError("Login failed: " + str(e)) 
     192 
     193 
     194 
     195 
    43196#_____________________________________________________________________________ 
    44197class UserSession: 
     
    49202 
    50203        try: 
    51             if not isintance(proxyCert, basestring): 
     204            if not isinstance(proxyCert, basestring): 
    52205                raise UserCredentialsError(\ 
    53206                    "Proxy Certificate must be input as a string") 
     
    64217        # Make a new credentials wallet - this holds authorisation 
    65218        # credentials for the current session 
    66         self.credWallet = CredWallet(dn) 
     219        # 
     220        # ! Make properties file path some kind of system resource e.g. 
     221        # env variable 
     222        propertiesFilePath = \ 
     223    '/home/users/pjkersha/Development/security/python/credReposProperties.xml' 
     224         
     225        self.credWallet = CredWallet(dn, 
     226                                     propertiesFilePath=propertiesFilePath) 
    67227 
    68228 
     
    77237    def __init__(self): 
    78238        """Initialise proxy certificate generation settings""" 
     239 
     240        # Transfer these to a properties file? 
    79241        self.__getProxyCertExe = \ 
    80242            "/usr/local/globus-3.9.5/bin/myproxy-get-delegation" 
     
    100262                                                    proxyCertFilePath) 
    101263             
    102             getProxyCertCmd = "%s %s" % (getProxyCertExe, getProxyCertArgs) 
     264            getProxyCertCmd = "%s %s" % (self.__getProxyCertExe, 
     265                                         getProxyCertArgs) 
    103266 
    104267 
     
    113276                sProxyCert = proxyCertFile.read() 
    114277                proxyCertFile.close() 
    115                 remove(proxyCertFilePath) 
     278                os.remove(proxyCertFilePath) 
    116279                 
    117280                return sProxyCert 
    118281            else: 
    119                 raise UserCredentialsError(\ 
    120                         "Error getting proxy certificate for %s" % userName) 
    121          
    122         except Exception, e: 
    123             try: remove(proxyCertFilePath) 
     282                raise UserCredentialsError("Command failed") 
     283         
     284        except Exception, e: 
     285            try: os.remove(proxyCertFilePath) 
    124286            except: pass 
    125287            raise UserCredentialsError(\ 
    126                 "Error getting proxy certificate for %s: %s" % \ 
    127                                                             (userName, str(e)) 
     288                "Error getting proxy certificate for user %s: %s" % \ 
     289                                                        (userName, str(e))) 
    128290 
    129291 
     
    133295    """Volatile store of user credentials associated with a user session""" 
    134296 
    135     def __init__(self, dn, credReposDbURI=None): 
     297    def __init__(self, dn, **credReposKeys): 
    136298        """Create store of user credentials for their current session 
    137299 
     
    143305                raise UserCredentialsError("User DN must be a valid string") 
    144306        except Exception, e: 
    145             raise UserCredentialsError("Input userName: " + str(e)) 
     307            raise UserCredentialsError("Input DN: " + str(e)) 
    146308 
    147309        self.__dn = dn 
    148310 
     311 
     312        # Make a connection to the Credentials Repository 
     313        try: 
     314            self.__credRepos = CredRepos(**credReposKeys) 
     315        except Exception, e: 
     316            raise "Error accessing credentials repository: " + str(e) 
     317         
    149318         
    150319        # List of credentials held in this wallet - each credential is an 
     
    153322 
    154323 
    155         # Look up user in the Credentials Repository db 
    156          
    157         # Connect and check for valid attribute certificates for the user 
     324        # Check for valid attribute certificates for the user 
     325        try: 
     326            userCred = self.__credRepos.getCredentials(dn) 
     327 
     328        except Exception, e: 
     329            raise UserCredentials( 
     330                "Error updating wallet with credentials from repository:" + \ 
     331                str(e)) 
     332 
     333        # Update wallet with attribute certificates from the repository 
     334        self.__attrCertList = [i.attrCert for i in userCred] 
     335         
     336        # Filter out expired certificates 
     337        self.audit() 
     338 
    158339         
    159340         
     
    162343        out of scope.""" 
    163344        self.updateCredRepos() 
     345 
     346 
    164347         
    165348         
     
    189372 
    190373 
     374 
     375 
    191376    def audit(self): 
    192377        """Check the credentials held in the wallet removing any that have 
     
    194379         
    195380        self.__attrCertList = filter(attrCert.isValid(), self.__attrCertList) 
     381 
     382 
    196383 
    197384                 
     
    214401    """Interface to Credentials Repository Database""" 
    215402 
    216     def __init__(self, dbURI=None): 
     403    def __init__(self, dbURI=None, propertiesFilePath=None): 
    217404        """Initialise Credentials Repository Database object. 
    218405 
    219         If the connection string is set a connection will be made 
    220  
    221         dbURI: '<db type>://<username>:<passwd>:<hostname>/dbname""" 
     406        If the connection string or properties file is set a connection 
     407        will be made 
     408 
     409        dbURI:              <db type>://<username>:<passwd>@<hostname>/dbname 
     410        propertiesFilePath: file path to properties file 
     411 
     412        Nb. propertiesFilePath setting overrides input dbURI 
     413        """ 
     414 
     415        if propertiesFilePath is not None and \ 
     416           not isinstance(propertiesFilePath, basestring): 
     417            raise UserCredentialsError("Input Properties file path " + \ 
     418                                       "must be a valid string.") 
     419             
     420        self.__propertiesFilePath = propertiesFilePath 
    222421        self.__con = None 
    223         if dbURI: self.setConnection(dbURI) 
     422        pdb.set_trace() 
     423        if self.__propertiesFilePath is not None: 
     424             
     425            # Read database URI set in file 
     426            dbURI = self.readPropertiesFile() 
     427 
     428        # Database URI may have been set as an input argument or via the 
     429        # properties file 
     430        if dbURI is not None: self.setConnection(dbURI) 
     431 
     432 
    224433 
    225434 
     
    238447        CredRepos.User._connection = self.__con 
    239448        CredRepos.UserCredential._connection = self.__con 
     449 
     450 
    240451             
    241452 
     
    257468                self.UserCredential.delete(cred.id) 
    258469                 
     470 
     471 
     472         
     473    def readPropertiesFile(self, propertiesFilePath=None): 
     474 
     475        """Read the configuration properties for the Attribute Authority 
     476 
     477        propertiesFilePath: file path to properties file 
     478        """ 
     479 
     480        if propertiesFilePath is not None: 
     481            if not isinstance(propertiesFilePath, basestring): 
     482                raise UserCredentialsError("Input Properties file path " + \ 
     483                      "must be a valid string.") 
     484             
     485            self.__propertiesFilePath = propertiesFilePath 
     486 
     487 
     488        try: 
     489            tree = ElementTree.parse(self.__propertiesFilePath) 
     490             
     491        except IOError, ioErr: 
     492            raise UserCredentialsError(\ 
     493                "Error parsing properties file \"%s\": %s" % \ 
     494                                (ioErr.filename, ioErr.strerror)) 
     495 
     496         
     497        aaProp = tree.getroot() 
     498 
     499        # Copy properties from file as member variables 
     500        properties = dict([(elem.tag, elem.text) for elem in aaProp]) 
     501         
     502        self.__dbURI = properties['dbURI'] 
     503 
     504 
     505 
     506 
     507    def getCredentials(self, dn): 
     508        """Get the list of credentials for a given user's DN""" 
     509 
     510        try: 
     511            return self.UserCredential.selectBy(dn=dn) 
     512             
     513        except Exception, e: 
     514            raise UserCredentialsError("Selecting credentials for %s: %s", 
     515                                       dn, str(e)) 
     516 
     517 
     518 
    259519         
    260520    def addCredentials(self, dn, attrCertList): 
     
    266526         
    267527        try: 
    268             userCred = self.UserCredential.selectBy(userName=userName) 
    269              
    270         except Exception, e: 
    271             raise UserCredentialsError("Selecting credentials for %s: %s", 
    272                                        dn, str(e)) 
     528            userCred = self.getCredentials(dn) 
     529             
     530        except Exception, e: 
     531            raise e 
    273532 
    274533 
  • security/trunk/python/NDG/X509.py

    r420 r422  
    1717 
    1818# Handle not before and not after strings 
    19 from datetime import * 
     19from time import strftime 
     20from time import strptime 
     21from datetime import datetime 
    2022 
    2123import M2Crypto 
     
    8890                                (self.__filePath, str(e))) 
    8991 
     92        # Update DN and validity times from M2Crypto X509 object just 
     93        # created 
     94        self.__setFromM2Crypto() 
     95 
     96 
     97 
     98         
     99    def parse(self, certTxt): 
     100        """Read a certificate input as a string""" 
     101 
     102        try: 
     103            certBIO = M2Crypto.BIO.MemoryBuffer(certTxt) 
     104            self.__m2CryptoX509 = M2Crypto.X509.load_cert_bio(certBIO) 
     105             
     106        except Exception, e: 
     107            raise X509CertError("Error loading certificate: %s" % str(e)) 
     108 
     109        # Update DN and validity times from M2Crypto X509 object just 
     110        # created 
     111        self.__setFromM2Crypto() 
     112 
     113 
     114         
     115         
     116    def __setFromM2Crypto(self): 
     117        """Private method allows class members to be updated from the 
     118        current M2Crypto object.  __m2CryptoX509 must have been set.""" 
     119         
    90120        # Get distinguished name 
    91121        m2CryptoX509Name = self.__m2CryptoX509.get_subject() 
     
    100130        # formatted strings and then parse them in order to create a datetime 
    101131        # type 
    102         datetimeRe = "([a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}).*" 
    103         datetimeFmt = "%b %d %H:%M:%S %Y" 
    104132         
    105133        try: 
    106             # Check for expected format - string may have trailing GMT - ingore             
    107             sNotBefore = re.findall(datetimeRe, 
    108                                     str(self.__m2CryptoX509.get_not_before()) 
    109             lNotBefore = strptime(sNotBefore, datetimeFmt)[0:5] 
    110  
    111             self.__dtNotBefore = datetime(lTime[0], lTime[1], lTime[2], 
    112                                           lTime[3], lTime[4], lTime[5]) 
     134            m2CryptoNotBefore = self.__m2CryptoX509.get_not_before() 
     135            self.__dtNotBefore=self.__m2CryptoUTC2datetime(m2CryptoNotBefore) 
     136                                         
     137        except Exception, e: 
     138            raise X509CertError("Not Before time: " + str(e)) 
     139 
     140         
     141        try: 
     142            m2CryptoNotAfter = self.__m2CryptoX509.get_not_after() 
     143            self.__dtNotAfter=self.__m2CryptoUTC2datetime(m2CryptoNotAfter) 
    113144                                     
    114145        except Exception, e: 
    115             raise X509CertError("Error parsing not before time: " + str(e)) 
    116  
    117          
    118         try: 
    119             # Check for expected format - string may have trailing GMT - ingore             
    120             sNotAfter = re.findall(datetimeRe, 
    121                                    str(self.__m2CryptoX509.get_not_before()) 
    122             lNotAfter = strptime(sNotAfter, datetimeFmt)[0:5] 
    123  
    124             self.__dtNotAfter = datetime(lTime[0], lTime[1], lTime[2], 
    125                                          lTime[3], lTime[4], lTime[5]) 
    126                                      
    127         except Exception, e: 
    128             raise X509CertError("Error parsing not after time: " + str(e)) 
    129  
    130  
    131  
    132          
    133     def parse(self, certTxt): 
    134         """Read a certificate input as a string""" 
    135  
    136         try: 
    137             certBIO = M2Crypto.BIO.MemoryBuffer(certTxt) 
    138             self.__m2CryptoX509 = M2Crypto.X509.load_cert_bio(certBIO) 
    139              
    140         except Exception, e: 
    141             raise X509CertError("Error loading certificate: %s" % str(e)) 
    142          
    143          
    144     def string(self, filePath=None): 
     146            raise X509CertError("Not After time: " + str(e)) 
     147 
     148 
     149 
     150         
     151    def asString(self, filePath=None): 
    145152        """Return certificate file content as a string""" 
    146153         
     
    226233        dtNow = datetime.utcnow() 
    227234        return dtNow > self.__dtNotBefore and dtNow < self.__dtNotAfter 
     235 
     236 
     237 
     238 
     239    def __m2CryptoUTC2datetime(self, m2CryptoUTC): 
     240        """Convert M2Crypto UTC time string as returned by get_not_before/ 
     241        get_not_after methods into datetime type""" 
     242         
     243        datetimeRe = "([a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}).*" 
     244 
     245        try: 
     246            # Convert into string 
     247            sM2CryptoUTC = str(m2CryptoUTC) 
     248             
     249            # Check for expected format - string may have trailing GMT - ignore 
     250            sTime = re.findall(datetimeRe, sM2CryptoUTC)[0] 
     251 
     252            # Convert into a tuple 
     253            lTime = strptime(sTime, "%b %d %H:%M:%S %Y")[0:6] 
     254 
     255            return datetime(lTime[0], lTime[1], lTime[2], 
     256                            lTime[3], lTime[4], lTime[5]) 
     257                                     
     258        except Exception, e: 
     259            raise X509CertError("Parsing M2Crypto UTC time: " + str(e)) 
    228260         
    229261 
  • security/trunk/python/NDG/XMLSecDoc.py

    r417 r422  
    300300            self.__keysMngr.destroy() 
    301301            self.__bkeysMngrFreed = True 
     302 
     303 
     304 
     305 
     306    def asString(self, filePath=None): 
     307        """Return certificate file content as a string""" 
     308         
     309        # Check libxml2.xmlDoc object has been instantiated - if not call 
     310        # read method 
     311        if self.__libxml2Doc is None: 
     312            self.read(filePath) 
     313             
     314        return self.__libxml2Doc.dump() 
    302315 
    303316 
  • security/trunk/python/NDG/login.cgi

    r418 r422  
    1515cvsID = '$Id$' 
    1616 
    17 import sys 
    18 import os 
    19 import cgi 
    20  
    21 # Temporary measure! 
    22 sys.path.append('/home/users/pjkersha/Development/security/python') 
    23 from UserCredentials import * 
    24  
    25  
    26 class Login: 
    27     """CGI for NDG Login""" 
    28      
    29     def __init__(self): 
    30          
    31         """Two stage process - login followed by authentication.  If 
    32         authentication fails re-call login.""" 
    33          
    34         # Use userName field to flag authentication call         
    35         form = cgi.FieldStorage() 
    36         if form.has_key("userName") and form["userName"].value != "": 
    37  
    38             # Preceeding page was login form - proceed with authentication 
    39             self.__userName = form["userName"].value 
    40  
    41             if form.has_key("passPhrase"): 
    42                 self.__passPhrase = form["passPhrase"].value 
    43             else: 
    44                 self.__passPhrase = None 
    45  
    46             # Authenticate user and generate a proxy certificate for them   
    47             self.authenticate() 
    48              
    49         else: 
    50             # Initial login 
    51             self.showLogin() 
    52  
    53  
    54     def showLogin(): 
    55         """Display initial NDG login form""" 
    56         print \ 
    57 """ 
    58 <HTML> 
    59 <HEAD> 
    60 <TITLE>NDG Login (Test)</TITLE> 
    61 <SCRIPT LANGUAGE="JavaScript1.1"> 
    62 <!-- 
    63 function isblank(s) 
    64 { 
    65   for (var i=0; i < s.length; i++){ 
    66     var c=s.charAt(i) 
    67     if ((c != ' ') && (c = '\n') && (c != '/t')) return false; 
    68   } 
    69   return true; 
    70 } 
    71  
    72 function check_logon(f) 
    73 { 
    74   var empty_fields = 0; 
    75   var e = f._home; 
    76   if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
    77       empty_fields ++; 
    78   } 
    79   e = f._gohome; 
    80   if ((e.value == null) || (e.value == "") || isblank(e.value)) { 
    81       empty_fields ++; 
    82   } 
    83   if (!empty_fields) { 
    84      f._md5.value = hex_md5 (f._gohome.value); 
    85 //   ash f._gohome.value = "";       
    86      return true; 
    87   }    
    88    
    89   alert("\nLogin Invalid:\nYou must complete both User name and Password\n"); 
    90   return false; 
    91 } 
    92 // --> 
    93 </SCRIPT> 
    94  
    95 <script language="JavaScript" src="http://badc.nerc.ac.uk/javascript/md5.js"></script> 
    96 </HEAD> 
    97 <BODY BGCOLOR=#FFFFFF onLoad="document.forms[0]._home.focus()"> 
    98 <H2>Login to the NERC Data Grid (Test only!)<BR clear=all></H2> 
    99 <HR> 
    100 <P> 
    101  
    102 <!-- Database connection ok --> 
    103  
    104 <FORM ACTION="../../cgi-bin/login.cgi" METHOD="POST"  
    105       onSubmit="return check_logon(this);"> 
    106  
    107 <TABLE BGCOLOR=#ADD8E6 cellspacing=0 border=0 cellpadding=5> 
    108 <TR><TD>User Name:</TD> <TD><INPUT TYPE=text NAME=userName value=""></TD></TR> 
    109 <TR><TD>Password:</TD><TD><INPUT TYPE=password NAME=passPhrase></TD></TR> 
    110 <TR><TD colspan="2" align="right"><INPUT TYPE=submit value="Login"></TD></TR> 
    111 </TABLE> 
    112  
    113 </FORM> 
    114 <em>Problems logging on? Contact <a href="http://badc.nerc.ac.uk/help/contact.html">BADC support</a> for help. </em> 
    115 </body></html> 
    116 """ 
    117     # end of showLogin() 
    118      
    119      
    120      
    121     def authenticate(self): 
    122  
    123         """Authenticate username and passphrase input from preceeding login 
    124         form""" 
    125          
    126         try: 
    127             if self.__passPhrase is None: 
    128                 raise "No passphrase input" 
    129              
    130             print "Content-type: text/html\n" 
    131             print "<Title>NDG User Authentication (Test)</Title>" 
    132  
    133             proxySrv = ProxyServer(self.__userName, self.__passPhrase) 
    134             proxyCert = proxyCrv.getProxyCert() 
    135             print "<p>User %s authenticated</p>" % self.__userName 
    136  
    137             # Create a new user session 
    138         except Exception, e: 
    139              
    140             print "<p>Authentication failed for user %s</p>" % self.__userName 
    141             # Re-display login screen 
    142             self.showLogin() 
    143             raise "Login failed: %s" % str(e) 
    144  
    145  
     17from NDG.UserCredentials import * 
    14618 
    14719   
Note: See TracChangeset for help on using the changeset viewer.