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: &lt;lib:AuthnRequest&gt;
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