1 /* zxidpdp.c  -  Handwritten functions for Local Policy Decision Point (PDP)
2  * Copyright (c) 2010-2011 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
3  * Copyright (c) 2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
4  * Author: Sampo Kellomaki (sampo@iki.fi)
5  * This is confidential unpublished proprietary source code of the author.
6  * NO WARRANTY, not even implied warranties. Contains trade secrets.
7  * Distribution prohibited unless authorized in writing.
8  * Licensed under Apache License 2.0, see file COPYING.
9  * $Id: zxidpep.c,v 1.10 2010-01-08 02:10:09 sampo Exp $
10  *
11  * 24.8.2009, created --Sampo
12  * 10.10.2009, added zxid_az() family --Sampo
13  * 12.2.2010,  added locking to lazy loading --Sampo
14  * 31.5.2010,  generalized to several PEPs model --Sampo
15  * 18.7.2011,  improved debug prints --Sampo
16  */
17 
18 #include "platform.h"  /* needed on Win32 for pthread_mutex_lock() et al. */
19 #include "errmac.h"
20 #include "zxid.h"
21 #include "zxidpriv.h"
22 #include "zxidconf.h"
23 #include "saml2.h"
24 #include "c/zx-const.h"
25 #include "c/zx-ns.h"
26 #include "c/zx-data.h"
27 #include "c/zx-e-data.h"
28 
29 /* ------------ Attribute Broker and PEP ------------ */
30 
31 /*() Local Policy Decision Point - decide on role and idpnid.
32  * Return: 0 for Deny and 1 for Permit.  */
33 
34 /* Called by:  zxid_query_ctlpt_pdp, zxid_simple_ab_pep */
zxid_localpdp(zxid_conf * cf,zxid_ses * ses)35 int zxid_localpdp(zxid_conf* cf, zxid_ses* ses)
36 {
37   struct zxid_attr* at = 0;
38 
39   if (cf->localpdp_role_permit || cf->localpdp_role_deny) {
40     at = zxid_find_at(ses->at, "role");
41     if (cf->localpdp_role_permit) {  /* whitelist of roles: not on list means deny */
42       if (!at) {
43 	INFO("DENY due to no role attribute (whitelist) nid(%s)", STRNULLCHK(ses?ses->nid:0));
44 	return 0;
45       }
46       /* Permit if any of the attribute values matches any of the whitelisted roles. */
47       if (!zxid_find_at_multival_on_cstr_list(cf->localpdp_role_permit, at)) {
48 	INFO("DENY: role(%s) not on whitelist nid(%s)", at->val, STRNULLCHK(ses?ses->nid:0));
49 	return 0;
50       }
51     }
52     if (cf->localpdp_role_deny) {    /* blacklist of roles: on list means deny */
53       /* Deny if any of the attribute values matches any of the blacklisted roles. */
54       if (at && zxid_find_at_multival_on_cstr_list(cf->localpdp_role_deny, at)) {
55 	INFO("DENY: role(%s) or other multivalue on blacklist nid(%s)", at->val, STRNULLCHK(ses?ses->nid:0));
56 	return 0;
57       }
58     }
59   }
60 
61   if (cf->localpdp_idpnid_permit || cf->localpdp_idpnid_deny) {
62     at = zxid_find_at(ses->at, "idpnid");
63     if (cf->localpdp_idpnid_permit) {  /* whitelist of idpnids: not on list means deny */
64       if (!at) {
65 	INFO("DENY due to no idpnid attribute (whitelist) nid(%s)", STRNULLCHK(ses?ses->nid:0));
66 	return 0;
67       }
68       if (!zxid_find_cstr_list(cf->localpdp_idpnid_permit, at->val)) {
69 	INFO("DENY: idpnid(%s) not on whitelist nid(%s)", at->val, STRNULLCHK(ses?ses->nid:0));
70 	return 0;
71       }
72     }
73     if (cf->localpdp_idpnid_deny) {    /* blacklist of idpnids: on list means deny */
74       if (at && zxid_find_cstr_list(cf->localpdp_idpnid_deny, at->val)) {
75 	INFO("DENY: idpnid(%s) on blacklist nid(%s)", at->val, STRNULLCHK(ses?ses->nid:0));
76 	return 0;
77       }
78     }
79   }
80 
81   INFO("PERMIT by local PDP val(%s) nid(%s)",STRNULLCHK(at?at->val:0),STRNULLCHK(ses?ses->nid:0));
82   return 1;
83 }
84 
85 /*(i) Postprocessing of SSO: Attribute Broker handles attributes and PEP/PDP
86  * decide on authorization. */
87 
88 /* Called by:  chkuid, zxid_mini_httpd_sso, zxid_show_protected_content_setcookie, zxid_simple_cf_ses, zxid_simple_no_ses_cf, zxid_simple_ses_active_cf */
zxid_simple_ab_pep(zxid_conf * cf,zxid_ses * ses,int * res_len,int auto_flags)89 char* zxid_simple_ab_pep(zxid_conf* cf, zxid_ses* ses, int* res_len, int auto_flags)
90 {
91   char* res;
92   struct zx_str* ss;
93   D_INDENT("ab_pep: ");
94   DD("ab_pep %d", 0);
95   zxid_ses_to_pool(cf, ses);  /* Process SSO a7n, applying NEED, WANT, and INMAP */
96 
97   if (!zxid_localpdp(cf, ses)) {
98     DD("Deny by local PDP %d",0);
99     D_DEDENT("ab_pep: ");
100     return "z";
101   }
102 
103   if (cf->pdp_url && *cf->pdp_url) {
104     //zxid_add_attr_to_ses(cf, ses, "Action", zx_dup_str(cf->ctx, "access"));
105     //zxid_add_attr_to_ses(cf, ses, "URL", zx_dup_str(cf->ctx, ses->rs));
106     if (!zxid_pep_az_soap_pepmap(cf, 0, ses, cf->pdp_url, cf->pepmap, "sso az")) {
107       INFO("DENY by remote PDP %d", 0);
108       D_DEDENT("ab_pep: ");
109       return "z";
110     }
111   }
112 
113   switch (auto_flags & (ZXID_AUTO_FMTQ | ZXID_AUTO_FMTJ)) {
114   case ZXID_AUTO_FMTQ|ZXID_AUTO_FMTJ: ss = zx_dup_str(cf->ctx, ""); break; /* No output */
115   case ZXID_AUTO_FMTQ:  ss = zxid_ses_to_qs(cf, ses); break;
116   case ZXID_AUTO_FMTJ:  ss = zxid_ses_to_json(cf, ses); break;
117   default: ERR("Unsupported output format bits %x", auto_flags & (ZXID_AUTO_FMTQ|ZXID_AUTO_FMTJ));
118   case 0:               ss = zxid_ses_to_ldif(cf, ses); break;
119   }
120   if (errmac_debug & ERRMAC_INOUT)
121     INFO("LDIF(%.*s)", ss?ss->len:1, ss?ss->s:"-");
122   if (cf->log_level > 0)
123     zxlog(cf, 0,0,0,0,0,0, ZX_GET_CONTENT(ses->nameid), "N", "K", "SHOWPC", ses->sid, 0);
124   res = ss->s;
125   if (res_len)
126     *res_len = ss->len;
127   ZX_FREE(cf->ctx, ss);
128   D_DEDENT("ab_pep: ");
129   return res;
130 }
131 
132 /* EOF  --  zxidpdp.c */
133