merging with geni-api branch
[sfa.git] / sfa / trust / auth.py
index b1db32a..470dc5e 100644 (file)
@@ -1,20 +1,21 @@
 #
 #
-# GeniAPI authentication 
+# SfaAPI authentication 
 #
 ### $Id$
 ### $URL$
 #
 
 #
 ### $Id$
 ### $URL$
 #
 
-import time
 
 from sfa.trust.credential import Credential
 from sfa.trust.trustedroot import TrustedRootList
 
 from sfa.trust.credential import Credential
 from sfa.trust.trustedroot import TrustedRootList
-from sfa.trust.rights import RightList
 from sfa.util.faults import *
 from sfa.trust.hierarchy import Hierarchy
 from sfa.util.config import *
 from sfa.util.faults import *
 from sfa.trust.hierarchy import Hierarchy
 from sfa.util.config import *
-from sfa.util.misc import *
-from sfa.trust.gid import GID
+from sfa.util.namespace import *
+from sfa.util.sfaticket import *
+from sfa.util.sfalogging import logger
+
+import sys
 
 class Auth:
     """
 
 class Auth:
     """
@@ -26,10 +27,31 @@ class Auth:
         self.hierarchy = Hierarchy()
         if not config:
             self.config = Config()
         self.hierarchy = Hierarchy()
         if not config:
             self.config = Config()
-        self.trusted_cert_list = TrustedRootList(self.config.get_trustedroots_dir()).get_list()
+        self.load_trusted_certs()
 
 
+    def load_trusted_certs(self):
+        self.trusted_cert_list = TrustedRootList(self.config.get_trustedroots_dir()).get_list()
+        self.trusted_cert_file_list = TrustedRootList(self.config.get_trustedroots_dir()).get_file_list()
 
 
-    def check(self, cred, operation):
+        
+        
+    def checkCredentials(self, creds, operation, hrn = None):
+        valid = []
+        for cred in creds:
+            try:
+                self.check(cred, operation, hrn)
+                valid.append(cred)
+            except:
+                error = sys.exc_info()[:2]
+                continue
+            
+        if not len(valid):
+            raise InsufficientRights('Access denied: %s -- %s' % (error[0],error[1]))
+        
+        return valid
+        
+        
+    def check(self, cred, operation, hrn = None):
         """
         Check the credential against the peer cert (callerGID included 
         in the credential matches the caller that is connected to the 
         """
         Check the credential against the peer cert (callerGID included 
         in the credential matches the caller that is connected to the 
@@ -55,27 +77,35 @@ class Auth:
                 raise InsufficientRights(operation)
 
         if self.trusted_cert_list:
                 raise InsufficientRights(operation)
 
         if self.trusted_cert_list:
-            self.client_cred.verify_chain(self.trusted_cert_list)
-            if self.client_gid:
-                self.client_gid.verify_chain(self.trusted_cert_list)
-            if self.object_gid:
-                self.object_gid.verify_chain(self.trusted_cert_list)
-
+            self.client_cred.verify(self.trusted_cert_file_list)
+        else:
+           raise MissingTrustedRoots(self.config.get_trustedroots_dir())
+       
+        # Make sure the credential's target matches the specified hrn. 
+        # This check does not apply to trusted peers 
+        trusted_peers = [gid.get_hrn() for gid in self.trusted_cert_list]
+        if hrn and self.client_gid.get_hrn() not in trusted_peers:
+            if not hrn == self.object_gid.get_hrn():
+                raise PermissionError("Target hrn: %s doesn't match specified hrn: %s " % \
+                                       (self.object_gid.get_hrn(), hrn) )       
         return True
 
         return True
 
-    def verifyPeerCert(self, cert, gid):
-        # make sure the client_gid matches client's certificate
-        if not cert:
-            peer_cert = self.peer_cert
+    def check_ticket(self, ticket):
+        """
+        Check if the tickt was signed by a trusted cert
+        """
+        if self.trusted_cert_list:
+            client_ticket = SfaTicket(string=ticket)
+            client_ticket.verify_chain(self.trusted_cert_list)
         else:
         else:
-            peer_cert = cert
+           raise MissingTrustedRoots(self.config.get_trustedroots_dir())
 
 
-        if not gid:
-            peer_gid = self.client_gid
-        else:
-            peer_gid = gid
-        if not peer_cert.is_pubkey(peer_gid.get_pubkey()):
-            raise ConnectionKeyGIDMismatch(peer_gid.get_subject())            
+        return True 
+
+    def verifyPeerCert(self, cert, gid):
+        # make sure the client_gid matches client's certificate
+        if not cert.is_pubkey(gid.get_pubkey()):
+            raise ConnectionKeyGIDMismatch(gid.get_subject()+":"+cert.get_subject())            
 
     def verifyGidRequestHash(self, gid, hash, arglist):
         key = gid.get_pubkey()
 
     def verifyGidRequestHash(self, gid, hash, arglist):
         key = gid.get_pubkey()
@@ -92,13 +122,7 @@ class Auth:
 
     def validateCred(self, cred):
         if self.trusted_cert_list:
 
     def validateCred(self, cred):
         if self.trusted_cert_list:
-            cred.verify_chain(self.trusted_cert_list)
-            caller_gid = cred.get_gid_caller()
-            object_gid = cred.get_gid_object()
-            if caller_gid:
-                caller_gid.verify_chain(self.trusted_cert_list)
-            if object_gid:
-                object_gid.verify_chain(self.trusted_cert_list)
+            cred.verify(self.trusted_cert_file_list)
 
     def authenticateGid(self, gidStr, argList, requestHash=None):
         gid = GID(string = gidStr)
 
     def authenticateGid(self, gidStr, argList, requestHash=None):
         gid = GID(string = gidStr)
@@ -134,7 +158,7 @@ class Auth:
         caller_gid = cred.get_gid_caller()
         caller_hrn = caller_gid.get_hrn()
         if caller_hrn != self.config.SFA_INTERFACE_HRN:
         caller_gid = cred.get_gid_caller()
         caller_hrn = caller_gid.get_hrn()
         if caller_hrn != self.config.SFA_INTERFACE_HRN:
-            raise GeniPermissionError(self.config.SFA_INTEFACE_HRN)
+            raise SfaPermissionDenied(self.config.SFA_INTEFACE_HRN)
 
         return   
         
 
         return   
         
@@ -214,9 +238,11 @@ class Auth:
         rl = RightList()
         type = record['type']
 
         rl = RightList()
         type = record['type']
 
+
         if type=="slice":
             researchers = record.get("researcher", [])
         if type=="slice":
             researchers = record.get("researcher", [])
-            if (caller_hrn in researchers):
+            pis = record.get("PI", [])
+            if (caller_hrn in researchers + pis):
                 rl.add("refresh")
                 rl.add("embed")
                 rl.add("bind")
                 rl.add("refresh")
                 rl.add("embed")
                 rl.add("bind")
@@ -227,19 +253,23 @@ class Auth:
             pis = record.get("PI", [])
             operators = record.get("operator", [])
             if (caller_hrn == self.config.SFA_INTERFACE_HRN):
             pis = record.get("PI", [])
             operators = record.get("operator", [])
             if (caller_hrn == self.config.SFA_INTERFACE_HRN):
-                rl.add("authority,sa,ma",)
+                rl.add("authority")
+                rl.add("sa")
+                rl.add("ma")
             if (caller_hrn in pis):
             if (caller_hrn in pis):
-                rl.add("authority,sa")
+                rl.add("authority")
+                rl.add("sa")
             if (caller_hrn in operators):
             if (caller_hrn in operators):
-                rl.add("authority,ma")
+                rl.add("authority")
+                rl.add("ma")
 
         elif type == "user":
             rl.add("refresh")
             rl.add("resolve")
             rl.add("info")
 
 
         elif type == "user":
             rl.add("refresh")
             rl.add("resolve")
             rl.add("info")
 
-        elif type == "component":
-            r1.add("operator")
+        elif type == "node":
+            rl.add("operator")
 
         return rl
 
 
         return rl