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