Changeset 1096 for TI12-security


Ignore:
Timestamp:
05/06/06 17:38:09 (14 years ago)
Author:
pjkersha
Message:

Expanded SecurityCGI to include handling for Attribute Certificate requests to an AA. - Incomplete + needs
testing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/NDG/SecurityCGI.py

    r1035 r1096  
    7979         
    8080        self.smWSDL = smWSDL 
     81        self.smClnt = None 
    8182        self.aaWSDL = aaWSDL 
     83        self.aaClnt = None 
    8284         
    8385        self.userName = userName 
     
    102104        # Work out expiry time offset from the time this script is run 
    103105        self.dtCookieExpiry = datetime.utcnow() + \ 
    104                                 timedelta(seconds=self.cookieLifetimeHrs*60*60) 
     106                            timedelta(seconds=self.cookieLifetimeHrs*60*60) 
    105107 
    106108        self.__wsDebug = False 
    107109        self._authorisationMethod = None 
     110 
     111        self.attCert = None 
     112         
    108113         
    109114        cgi.FieldStorage.__init__(self, **cgiFieldStorageKwArgs) 
     
    114119        """Call appropriate actions according to the fields set""" 
    115120 
     121        bAuthorise = "authorise" in self 
     122         
    116123        if 'requestURI' in self: 
    117124            # Request credentials from user's home site 
     
    132139 
    133140        elif 'authenticate' in self: 
    134             # User has logged on at home site and a cookie is now set - 
    135             # next step is processCredsRequest() below 
     141            # User has entered login details - now authenticate using the  
     142            # Session Manager WS 
    136143            sessCookie = self.authenticate() 
    137144             
     145            if bAuthorise: 
     146 
     147                # Authorisation and authentication arguments were set 
     148                # - Call authentication first 
     149                cookie = self.authenticate(setCookie=False) 
     150 
     151                # Call authorisation passing the session ID for authorise to 
     152                # set the cookie 
     153                self.getAttCert(cookie) 
     154             
    138155            if 'returnURI' in self: 
    139                 # Authentication is required following a redirect from 
    140                 # another site - redirect back to the remote site returning 
    141                 # the cookie information 
     156                # The authentication process is as a result of a redirect  
     157                # request from another site - redirect back to the remote site 
     158                # returning the credentials contained in the NDG security 
    142159                self.processCredsRequest(sessCookie=sessCookie, 
    143160                                         setCookie=True,  
    144161                                         **kwargs) 
    145162                 
     163        elif bAuthorise: 
     164            self.getAttCert() 
     165                     
    146166        elif 'returnURI' in self: 
    147167            # Home site receives request from remote site for credentials and 
     
    248268        #_________________________________________________________________________ 
    249269    def processCredsRequest(self, 
    250                             returnURI=None,  
     270                            returnURI=None, 
     271                            bAuthorise=False,  
    251272                            sessCookie=None,  
    252273                            **returnCredsKwArgs): 
     
    279300            # this script with '?authenticate=1&returnURI=<...>' 
    280301            self.showLogin(returnURI=returnURI, 
    281                            setCookie=True, 
    282                            contentTypeHdr=True, 
    283                            pageTitle="NDG Login", 
    284                            htmlTag=True, 
    285                            bodyTag=True) 
     302                           bAuthorise=bAuthorise,  
     303                           pageTitle="NDG Login") 
    286304 
    287305     
     
    358376            self.passPhrase = self['passPhrase'].value 
    359377             
     378        if 'returnURI' in self: 
     379            returnURI = self['returnURI'].value 
     380        else: 
     381            returnURI = None 
     382             
    360383             
    361384        if self.userName is None: 
    362             self.showLogin(returnURI=self['returnURI'].value, 
    363                            setCookie=True, 
    364                            contentTypeHdr=True, 
    365                            pageTitle="NDG Login", 
    366                            htmlTag=True, 
    367                            bodyTag=True) 
    368             raise SecurityCGIError("no username set for authentication") 
     385            self.showLogin(returnURI=returnURI, 
     386                           bAuthorise=bAuthorise, 
     387                           pageTitle="Login - error no username set") 
     388            raise SecurityCGIError, "no username set for authentication" 
    369389 
    370390        if self.passPhrase is None: 
    371             self.showLogin(returnURI=self['returnURI'].value, 
    372                            setCookie=True, 
    373                            contentTypeHdr=True, 
    374                            pageTitle="NDG Login", 
    375                            htmlTag=True, 
    376                            bodyTag=True) 
    377             raise SecurityCGIError("no pass-phrase set for authentication") 
     391            self.showLogin(returnURI=returnURI, 
     392                           bAuthorise=bAuthorise, 
     393                           pageTitle="Login - error no pass-phrase set") 
     394            raise SecurityCGIError, "no pass-phrase set for authentication" 
    378395 
    379396 
    380397        # Instantiate WS proxy and request connection 
    381398        try: 
    382             smClnt = SessionClient(smWSDL=self.smWSDL, 
     399            if not self.smClnt: 
     400                self.smClnt = SessionClient(smWSDL=self.smWSDL, 
    383401                                   smPubKeyFilePath=self.smPubKeyFilePath, 
    384402                                   clntPubKeyFilePath=self.clntPubKeyFilePath, 
     
    386404                                   traceFile=traceFile) 
    387405 
    388             sSessCookie = smClnt.connect(userName=self.userName, 
     406            sSessCookie = self.smClnt.connect(userName=self.userName, 
    389407                                         pPhrase=self.passPhrase, 
    390408                                         clntPriKeyPwd=self.clntPriKeyPwd) 
     
    393411 
    394412        except Exception, e: 
    395             self.showLogin(returnURI=self['returnURI'].value, 
    396                            setCookie=True, 
    397                            contentTypeHdr=True, 
    398                            pageTitle="NDG Login", 
    399                            htmlTag=True, 
    400                            bodyTag=True) 
    401             raise SecurityCGIError("Session client: " + str(e)) 
    402              
     413            self.showLogin(returnURI=returnURI, 
     414                           bAuthorise=bAuthorise, 
     415                           pageTitle="Login - internal error") 
     416            raise SecurityCGIError, "Session client: " + str(e) 
     417 
     418 
     419    #_________________________________________________________________________ 
     420    def getAttCert(self, sessCookie=None, reqRole=None): 
     421        """Contact Attribute Authority to get Attribute Certificate for data 
     422        access 
     423 
     424        sessCookie:     NDG security session cookie 
     425        reqRole:        specify the required role to get authorisation.  Set 
     426                        this to optimise the process for getting the required 
     427                        AC from a trusted host in order to perform mapping""" 
     428 
     429        if self.__wsDebug: 
     430            traceFile = sys.stderr 
     431        else: 
     432            traceFile = None 
     433 
     434 
     435        # Check for session cookie input 
     436        if not sessCookie: 
     437            # No cookie set as input argument check for environment variable 
     438            if 'HTTP_COOKIE' in os.environ: 
     439                sessCookie = SimpleCookie(os.environ['HTTP_COOKIE'])     
     440            else: 
     441                raise SecurityCGIError, \ 
     442                    "Attribute certificate request requires a security cookie" 
     443 
     444        # Check cookie is valid 
     445        try: 
     446            UserSession.isValidSecurityCookie(sessCookie, raiseExcep=True) 
     447             
     448        except UserSessionError, e: 
     449            raise SecurityCGIError, 'Checking existing session cookie: %s' % e 
     450 
     451 
     452        # Configure flags for attribute certificate request.  This determines 
     453        # whether mapping of certificates from trusted hosts is allowed 
     454        if self._authorisationMethod == 'allowMapping': 
     455            bMapFromTrustedHosts = True 
     456            bRtnExtAttCertList = False 
     457 
     458        elif self._authorisationMethod == 'allowMappingWithPrompt': 
     459            bMapFromTrustedHosts = False 
     460            bRtnExtAttCertList = True 
     461        else: 
     462            bMapFromTrustedHosts = False 
     463            bRtnExtAttCertList = False 
     464 
     465 
     466        # Instantiate WS proxy and request authorisation 
     467        try: 
     468            if not self.smClnt: 
     469                self.smClnt = SessionClient( 
     470                                smWSDL=self.smWSDL, 
     471                                smPubKeyFilePath=self.smPubKeyFilePath, 
     472                                clntPubKeyFilePath=self.clntPubKeyFilePath, 
     473                                clntPriKeyFilePath=self.clntPriKeyFilePath, 
     474                                traceFile=traceFile) 
     475 
     476            resp = self.smClnt.reqAuthorisation(sessCookie=sessCookie, 
     477                                aaWSDL=self.aaWSDL, 
     478                                aaPubKey=self.aaPubKey, 
     479                                reqRole=reqRole, 
     480                                mapFromTrustedHosts=bMapFromTrustedHosts, 
     481                                rtnExtAttCertList=bRtnExtAttCertList, 
     482                                clntPriKeyPwd=self.clntPriKeyPwd) 
     483        except Exception, e: 
     484            # Socket error returns tuple - reformat to just give msg 
     485            raise SecurityCGIError, "Session client: " + str(e) 
     486 
     487 
     488        if resp['statCode'] == 'AccessGranted': 
     489            self.handleAttCertGranted(resp['attCert']) 
     490         
     491        elif resp['statCode'] == 'AccessDenied': 
     492            self.handleAttCertDenied(resp['extAttCertList'], resp['errMsg']) 
     493             
     494        elif resp['statCode'] == 'AccessError': 
     495            raise SecurityCGIError, resp['errMsg'] 
     496             
     497     
     498    #_________________________________________________________________________ 
     499    def handleAttCertGranted(self, attCert): 
     500        """Callback invoked by getAttCert - handle case where an Attribute 
     501        Authority has granted a new attribute certificate to the user.  Derive 
     502        from this class and override this method as required. 
     503        """ 
     504        pass 
     505     
     506     
     507    #_________________________________________________________________________ 
     508    def handleAttCertDenied(self, extAttCertList, errMsg): 
     509        """Callback invoked by getAttCert - handle case where an Attribute 
     510        Authority has denied an attribute certificate to the user.  Derive 
     511        from this class and override this method as required. 
     512         
     513        extAttCertList:    a list of attribute certificates from trusted 
     514                           hosts.  Any of these could be selected and  
     515                           presented back to the target AA in order to get 
     516                           a mapped certificate.  This list may be None if  
     517                           no ACs could be obtained or if the  
     518                           mapFromTrustedHosts flag in the call to the Session 
     519                           Manager WS reqAuthorisation method was set to  
     520                           False. 
     521                            
     522        errMsg:            the error message returned from the call to the 
     523                           AA to get an AC.""" 
     524         
     525        if not extAttCertList: 
     526            self.showLogin(pageTitle="Access denied by Attribute Authority") 
     527            raise SecurityCGIError, errMsg 
     528         
     529        else: 
     530            # Display list of attCerts to choose from 
     531            if contentTypeHdr: 
     532                print "Content-type: text/html\n\n" 
     533                     
     534            if htmlTag: 
     535                print "<html>\n" 
     536     
     537            if hdrTag:             
     538                if not hdrTxt: 
     539                    hdrTxt = """    <style type=\"text/css\"> 
     540<!-- 
     541.al { 
     542text-align: justify 
     543} 
     544a{ 
     545text-decoration:none; 
     546} 
     547a:hover{ 
     548color:#0000FF; 
     549} 
     550    body { font-family: Verdana, sans-serif; font-size: 11} 
     551    table { font-family: Verdana, sans-serif; font-size: 11} 
     552--> 
     553</style>""" 
     554 
     555                print """<head> 
     556             
     557    <title>%s</title> 
     558    %s 
     559</head>""" % (pageTitle, hdrTxt) 
     560     
     561     
     562                if bodyTag: 
     563                    print "<body>\n" 
     564                 
     565                print """ 
     566    <form action="%s" method="POST"> 
     567    <table bgcolor=#ADD8E6 cellspacing=0 border=0 cellpadding=5> 
     568    <tbody>""" 
     569                for attCert in extAttCertList: 
     570                    print \ 
     571"""    <tr> 
     572        <td>%s</td> 
     573    </tr>""" % attCert['issuer'] 
     574                 
     575                print \ 
     576"""    </tbody> 
     577    </table> 
     578    </form>""" 
     579 
     580                if bodyTag: 
     581                    print "</body>\n" 
     582         
     583                if htmlTag: 
     584                    print "</html>\n" 
     585     
     586        # end of handleAttCertDenied() 
     587 
    403588     
    404589    #_________________________________________________________________________ 
    405590    def showLogin(self, 
    406591                  returnURI=None, 
    407                   contentTypeHdr=False, 
    408                   htmlTag=False, 
     592                  contentTypeHdr=True, 
     593                  htmlTag=True, 
    409594                  pageTitle='', 
    410595                  hdrTxt='', 
    411                   headTag=False, 
    412                   bodyTag=False, 
     596                  headTag=True, 
     597                  bodyTag=True, 
    413598                  bAuthorise=False): 
    414599        """Display initial NDG login form""" 
     
    658843 
    659844        try: 
    660             aaClnt = AttAuthorityClient(aaWSDL=self.aaWSDL, 
     845            if not self.aaClnt: 
     846                self.aaClnt = AttAuthorityClient(aaWSDL=self.aaWSDL, 
    661847                                aaPubKeyFilePath=self.aaPubKeyFilePath, 
    662848                                clntPubKeyFilePath=self.clntPubKeyFilePath, 
     
    664850                                traceFile=traceFile) 
    665851             
    666             self.trustedHostInfo = aaClnt.getTrustedHostInfo( 
     852            self.trustedHostInfo = self.aaClnt.getTrustedHostInfo( 
    667853                                           clntPriKeyPwd=self.clntPriKeyPwd) 
    668854        except Exception, e: 
    669             raise SecurityCGIError("Attribute Authority client: " + str(e)) 
     855            raise SecurityCGIError, "Attribute Authority client: " + str(e) 
Note: See TracChangeset for help on using the changeset viewer.