1 /* $id: lib_authn_request.c,v 1.18 2004/11/26 14:13:02 fpeters Exp $
2 *
3 * Lasso - A free implementation of the Liberty Alliance specifications.
4 *
5 * Copyright (C) 2004-2007 Entr'ouvert
6 * http://lasso.entrouvert.org
7 *
8 * Authors: See AUTHORS file in top-level directory.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "private.h"
25 #include "lib_authn_request.h"
26 #include <libxml/uri.h>
27 #include "../utils.h"
28
29 /**
30 * SECTION:lib_authn_request
31 * @short_description: <lib:AuthnRequest>
32 * @see_also: #LassoLogin
33 *
34 * Authentication requests are sent from a service provider to an identity
35 * provider.
36 *
37 * <blockquote>
38 * The lib:AuthnRequest is defined as an extension of samlp:RequestAbstractType.
39 * The RequestID attribute in samlp:RequestAbstractType has uniqueness
40 * requirements placed on it by [SAMLCore11], which require it to have the
41 * properties of a nonce.
42 * </blockquote>
43 *
44 * <figure><title>Schema fragment for lib:AuthnRequest</title>
45 * <programlisting><![CDATA[
46 * <xs:element name="AuthnRequest" type="AuthnRequestType" />
47 * <xs:complexType name="AuthnRequestType">
48 * <xs:complexContent>
49 * <xs:extension base="samlp:RequestAbstractType">
50 * <xs:sequence>
51 * <xs:element ref="Extension" minOccurs="0" maxOccurs="unbounded"/>
52 * <xs:element ref="ProviderID"/>
53 * <xs:element ref="AffiliationID" minOccurs="0"/>
54 * <xs:element ref="NameIDPolicy" minOccurs="0"/>
55 * <xs:element name="ForceAuthn" type="xs:boolean" minOccurs="0"/>
56 * <xs:element name="IsPassive" type="xs:boolean "minOccurs="0"/>
57 * <xs:element ref="ProtocolProfile" minOccurs="0"/>
58 * <xs:element name="AssertionConsumerServiceID" type="xs:string" minOccurs="0"/>
59 * <xs:element ref="RequestAuthnContext" minOccurs="0"/>
60 * <xs:element ref="RelayState" minOccurs="0"/>
61 * <xs:element ref="Scoping" minOccurs="0 "/>
62 * </xs:sequence>
63 * <xs:attribute ref="consent" use="optional"/>
64 * </xs:extension>
65 * </xs:complexContent>
66 * </xs:complexType>
67 *
68 * <xs:element name="ProviderID" type="md:entityIDType"/>
69 * <xs:element name="AffiliationID" type="md:entityIDType"/>
70 *
71 * <xs:element name="NameIDPolicy" type="NameIDPolicyType"/>
72 * <xs:simpleType name="NameIDPolicyType">
73 * <xs:restriction base="xs:string">
74 * <xs:enumeration value="none"/>
75 * <xs:enumeration value="onetime"/>
76 * <xs:enumeration value="federated"/>
77 * <xs:enumeration value="any"/ >
78 * </xs:restriction>
79 * </xs:simpleType>
80 *
81 * <xs:element name="ProtocolProfile" type="xs:anyURI"/>
82 * <xs:element name="RelayState" type="xs:string"/>
83 * ]]></programlisting>
84 * </figure>
85 */
86
87
88 /*****************************************************************************/
89 /* private methods */
90 /*****************************************************************************/
91
92 static struct XmlSnippet schema_snippets[] = {
93 { "Extension", SNIPPET_EXTENSION, G_STRUCT_OFFSET(LassoLibAuthnRequest, Extension), NULL, NULL, NULL},
94 { "ProviderID", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLibAuthnRequest, ProviderID), NULL, NULL, NULL},
95 { "AffiliationID", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLibAuthnRequest, AffiliationID), NULL, NULL, NULL},
96 { "NameIDPolicy", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLibAuthnRequest, NameIDPolicy), NULL, NULL, NULL},
97 { "ForceAuthn", SNIPPET_CONTENT | SNIPPET_BOOLEAN,
98 G_STRUCT_OFFSET(LassoLibAuthnRequest, ForceAuthn), NULL, NULL, NULL},
99 { "IsPassive", SNIPPET_CONTENT | SNIPPET_BOOLEAN,
100 G_STRUCT_OFFSET(LassoLibAuthnRequest, IsPassive), NULL, NULL, NULL},
101 { "ProtocolProfile", SNIPPET_CONTENT,
102 G_STRUCT_OFFSET(LassoLibAuthnRequest, ProtocolProfile), NULL, NULL, NULL},
103 { "AssertionConsumerServiceID", SNIPPET_CONTENT,
104 G_STRUCT_OFFSET(LassoLibAuthnRequest, AssertionConsumerServiceID), NULL, NULL, NULL},
105 { "RequestAuthnContext", SNIPPET_NODE,
106 G_STRUCT_OFFSET(LassoLibAuthnRequest, RequestAuthnContext), NULL, NULL, NULL},
107 { "RelayState", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLibAuthnRequest, RelayState), NULL, NULL, NULL},
108 { "Scoping", SNIPPET_NODE, G_STRUCT_OFFSET(LassoLibAuthnRequest, Scoping), NULL, NULL, NULL},
109 { "consent", SNIPPET_ATTRIBUTE, G_STRUCT_OFFSET(LassoLibAuthnRequest, consent), NULL, NULL, NULL},
110 {NULL, 0, 0, NULL, NULL, NULL}
111 };
112
113 static struct QuerySnippet query_snippets[] = {
114 { "RequestID", NULL },
115 { "MajorVersion", NULL },
116 { "MinorVersion", NULL },
117 { "IssueInstant", NULL },
118 { "ProviderID", NULL },
119 { "AffiliationID", NULL },
120 { "ForceAuthn", NULL },
121 { "IsPassive", NULL },
122 { "NameIDPolicy", NULL },
123 { "ProtocolProfile", NULL },
124 { "AssertionConsumerServiceID", NULL },
125 { "RequestAuthnContext/AuthnContextStatementRef", "AuthnContextStatementRef" },
126 { "RequestAuthnContext/AuthnContextClassRef", "AuthnContextClassRef" },
127 { "RequestAuthnContext/AuthnContextComparison", "AuthnContextComparison" },
128 { "RelayState", NULL },
129 { "Scoping/ProxyCount", "ProxyCount" },
130 { "Scoping/IDPList/IDPEntries", "IDPEntries" },
131 { "Scoping/IDPList/GetComplete", "GetComplete" },
132 { "consent", NULL },
133 { "Extension", NULL },
134 { NULL, NULL }
135 };
136
137 static LassoNodeClass *parent_class = NULL;
138
139 static gboolean
init_from_query(LassoNode * node,char ** query_fields)140 init_from_query(LassoNode *node, char **query_fields)
141 {
142 LassoLibAuthnRequest *request = LASSO_LIB_AUTHN_REQUEST(node);
143 gboolean rc;
144
145 request->RequestAuthnContext = lasso_lib_request_authn_context_new();
146 /* XXX needs code for Scoping, IDPList, IDPEntries... */
147 rc = parent_class->init_from_query(node, query_fields);
148
149 if (request->RequestAuthnContext->AuthnContextClassRef == NULL &&
150 request->RequestAuthnContext->AuthnContextStatementRef == NULL &&
151 request->RequestAuthnContext->AuthnContextComparison == NULL) {
152 lasso_release_gobject(request->RequestAuthnContext);
153 }
154
155 if (request->ProviderID == NULL)
156 return FALSE;
157
158 return rc;
159 }
160
161
162 /*****************************************************************************/
163 /* instance and class init functions */
164 /*****************************************************************************/
165
166 static void
instance_init(LassoLibAuthnRequest * node)167 instance_init(LassoLibAuthnRequest *node)
168 {
169 node->IsPassive = TRUE;
170 }
171
172 static void
class_init(LassoLibAuthnRequestClass * klass,void * unused G_GNUC_UNUSED)173 class_init(LassoLibAuthnRequestClass *klass, void *unused G_GNUC_UNUSED)
174 {
175 LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
176
177 parent_class = g_type_class_peek_parent(klass);
178 nclass->init_from_query = init_from_query;
179 nclass->node_data = g_new0(LassoNodeClassData, 1);
180 lasso_node_class_set_nodename(nclass, "AuthnRequest");
181 lasso_node_class_set_ns(nclass, LASSO_LIB_HREF, LASSO_LIB_PREFIX);
182 lasso_node_class_add_snippets(nclass, schema_snippets);
183 lasso_node_class_add_query_snippets(nclass, query_snippets);
184 }
185
186 GType
lasso_lib_authn_request_get_type()187 lasso_lib_authn_request_get_type()
188 {
189 static GType this_type = 0;
190
191 if (!this_type) {
192 static const GTypeInfo this_info = {
193 sizeof (LassoLibAuthnRequestClass),
194 NULL,
195 NULL,
196 (GClassInitFunc) class_init,
197 NULL,
198 NULL,
199 sizeof(LassoLibAuthnRequest),
200 0,
201 (GInstanceInitFunc) instance_init,
202 NULL
203 };
204
205 this_type = g_type_register_static(LASSO_TYPE_SAMLP_REQUEST_ABSTRACT,
206 "LassoLibAuthnRequest", &this_info, 0);
207 }
208 return this_type;
209 }
210
211 /**
212 * lasso_lib_authn_request_new:
213 *
214 * Creates a new #LassoLibAuthnRequest object.
215 *
216 * Return value: a newly created #LassoLibAuthnRequest object
217 **/
218 LassoLibAuthnRequest*
lasso_lib_authn_request_new()219 lasso_lib_authn_request_new()
220 {
221 return g_object_new(LASSO_TYPE_LIB_AUTHN_REQUEST, NULL);
222 }
223