Branch data Line data Source code
1 : : /* zxidcdc.c - Handwritten functions for Common Domain Cookie handling at SP
2 : : * Copyright (c) 2010 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
3 : : * Copyright (c) 2006-2008 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: zxidcdc.c,v 1.5 2008-10-08 03:56:55 sampo Exp $
10 : : *
11 : : * 12.8.2006, created --Sampo
12 : : * 16.1.2007, split from zxidlib.c --Sampo
13 : : * 7.10.2008, added documentation --Sampo
14 : : */
15 : :
16 : : #include <string.h>
17 : : #include <stdio.h>
18 : : #include <stdlib.h>
19 : :
20 : : #include "errmac.h"
21 : : #include "zxid.h"
22 : : #include "zxidutil.h"
23 : : #include "zxidconf.h"
24 : :
25 : : /* ============== CDC ============== */
26 : :
27 : : /*() Read Common Domain Cookie and formulate HTTP redirection to pass it back.
28 : : *
29 : : * Limitations:: In its current form (2008) this function only works for CGI scripts. (*** fix me)
30 : : *
31 : : * The SAML CDC is a standards based method for SSO IdP discovery. */
32 : :
33 : : /* Called by: covimp_test, main x2, zxid_simple_no_ses_cf */
34 : : int zxid_cdc_read(zxid_conf* cf, zxid_cgi* cgi)
35 : 2 : {
36 : : char* p;
37 : 2 : char* cdc = 0;
38 : 2 : char* cookie = getenv("HTTP_COOKIE");
39 : 2 : char* host = getenv("HTTP_HOST");
40 [ + + ]: 2 : if (cookie) {
41 [ - + # # ]: 1 : D("CDC(%s) host(%s)", cookie, host);
42 : 1 : cdc = strstr(cookie, "_saml_idp");
43 [ + - ]: 1 : if (!cdc)
44 : 1 : cdc = strstr(cookie, "_liberty_idp");
45 [ + - ]: 1 : if (cdc) {
46 : 1 : cdc = strchr(cdc, '=');
47 [ + - ]: 1 : if (cdc) {
48 [ - + # # ]: 1 : D("cdc(%s)", cdc);
49 [ + - ]: 1 : if (cdc[1] == '"') {
50 : 1 : cdc += 2;
51 : 1 : p = strchr(cdc, '"');
52 [ + - ]: 1 : if (p)
53 : 1 : *p = 0;
54 : : else
55 : 0 : cdc = 0;
56 : : } else
57 : 0 : ++cdc;
58 : : }
59 : : } else {
60 : 0 : ERR("Malformed CDC(%s)", cookie);
61 : : }
62 : : } else {
63 [ + - - + : 1 : D("No CDC _saml_idp in CGI environment host(%s)", STRNULLCHK(host));
- + ]
64 : : }
65 [ + + - + : 2 : D("Location: %s?o=E&c=%s\r\n\r\n", cf->url, cdc?cdc:"(missing)");
- + ]
66 [ + + ]: 2 : printf("Location: %s?o=E&c=%s\r\n\r\n", cf->url, cdc?cdc:""); /* *** Generalize this to non CGI situation */
67 : : /* *** should prepare AuthnReq and redirect directly to the IdP (if any). */
68 : 2 : return 0;
69 : : }
70 : :
71 : : /*() Process second part of Common Domain Cookie redirection.
72 : : * See zxid_cdc_read() for first part.
73 : : *
74 : : * The SAML CDC is a standards based method for SSO IdP discovery. */
75 : :
76 : : /* Called by: covimp_test, main x2, zxid_simple_no_ses_cf */
77 : : int zxid_cdc_check(zxid_conf* cf, zxid_cgi* cgi)
78 : 6 : {
79 : : int len;
80 : : zxid_entity* ent;
81 : : char* p;
82 : : char* q;
83 : : char eid[ZXID_MAX_EID];
84 : : #if 0
85 : : char* idp_eid;
86 : : if (!cgi->cdc) return 0;
87 : : for (idp_eid = strtok(cgi->cdc, " "); idp_eid; idp_eid = strtok(0, " ")) {
88 : : if (!(ent = zxid_get_ent(cf, idp_eid)))
89 : : continue;
90 : : switch (cf->cdc_choice) {
91 : : case ZXID_CDC_CHOICE_ALWAYS_FIRST: /* Do not offer UI, always pick first on CDC list. */
92 : : break;
93 : : case ZXID_CDC_CHOICE_ALWAYS_LAST: /* Do not offer UI, always pick last on CDC list. */
94 : : /* *** How to detect "lastness" in strtok() list? */
95 : : break;
96 : : case ZXID_CDC_CHOICE_ALWAYS_ONLY: /* If CDC has only one IdP, always pick it. */
97 : : /* *** How to detect "onlyness" in strtok() list? */
98 : : break;
99 : : case ZXID_CDC_CHOICE_UI_PREF: /* Offer UI with the CDC designated IdPs first. */
100 : : /* *** */
101 : : break;
102 : : case ZXID_CDC_CHOICE_UI_NOPREF: /* Offer UI. Do not give preference to CDC IdPs. */
103 : : /* *** */
104 : : break;
105 : : default: NEVER("Bad CDC choice(%d)\n", cf->cdc_choice);
106 : : }
107 : : }
108 : : #else
109 : :
110 [ - + + + ]: 7 : for (q = cgi->cdc; q; q = p ? p+1 : 0) {
111 : 1 : p = strchr(q, ' ');
112 [ - + ]: 1 : len = p ? p-q : strlen(q);
113 : :
114 [ - + ]: 1 : if (SIMPLE_BASE64_PESSIMISTIC_DECODE_LEN(len) > sizeof(eid)-1) {
115 : 0 : ERR("EntityID len=%d larger than built in limit=%d. Base64 len=%d", SIMPLE_BASE64_PESSIMISTIC_DECODE_LEN(len), sizeof(eid)-1, len);
116 : 0 : continue;
117 : : }
118 : 1 : q = unbase64_raw(q, q + len, eid, zx_std_index_64);
119 : 1 : *q = 0;
120 : :
121 : 1 : ent = zxid_get_ent(cf, eid);
122 [ + - ]: 1 : if (!ent) {
123 : 1 : ERR("eid(%s) not in CoT", eid); /* *** Change this to offer login button anyway so new IdP can join CoT using WKL */
124 : 1 : continue;
125 : : }
126 [ # # # # ]: 0 : D("Adding entity(%s) to cgi->idp_list", eid);
127 : 0 : ent->n_cdc = cgi->idp_list;
128 : 0 : cgi->idp_list = ent;
129 : : }
130 : : #endif
131 : 6 : return 0;
132 : : }
133 : :
134 : : /* EOF -- zxidcdc.c */
|