1 /* $Id$
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 #include "../utils.h"
24 #include "private.h"
25 #include "lib_federation_termination_notification.h"
26 #include <libxml/uri.h>
27 
28 /**
29  * SECTION:lib_federation_termination_notification
30  * @short_description: &lt;lib:FederationTerminationNotification&gt;
31  *
32  * <figure><title>Schema fragment for lib:FederationTerminationNotification</title>
33  * <programlisting><![CDATA[
34  * <xs:element name="FederationTerminationNotification"
35  *     type="FederationTerminationNotificationType"/>
36  *   <xs:complexType name="FederationTerminationNotificationType">
37  *     <xs:complexContent>
38  *       <xs:extension base="samlp:RequestAbstractType">
39  *         <xs:sequence>
40  *           <xs:element ref="Extension" minOccurs="0" maxOccurs="unbounded"/>
41  *           <xs:element ref="ProviderID"/>
42  *           <xs:element ref="saml:NameIdentifier"/>
43  *         </xs:sequence>
44  *       <xs:attribute ref="consent" use="optional"/>
45  *     </xs:extension>
46  *   </xs:complexContent>
47  * </xs:complexType>
48  *
49  * <xs:element name="ProviderID" type="md:entityIDType"/>
50  * ]]></programlisting>
51  * </figure>
52  */
53 
54 /*****************************************************************************/
55 /* private methods                                                           */
56 /*****************************************************************************/
57 
58 static struct XmlSnippet schema_snippets[] = {
59 	{ "Extension", SNIPPET_EXTENSION,
60 		G_STRUCT_OFFSET(LassoLibFederationTerminationNotification, Extension), NULL, NULL,
61 		NULL},
62 	{ "ProviderID", SNIPPET_CONTENT,
63 		G_STRUCT_OFFSET(LassoLibFederationTerminationNotification, ProviderID), NULL, NULL,
64 		NULL},
65 	{ "NameIdentifier", SNIPPET_NODE,
66 		G_STRUCT_OFFSET(LassoLibFederationTerminationNotification, NameIdentifier), NULL,
67 		LASSO_SAML_ASSERTION_PREFIX, LASSO_SAML_ASSERTION_HREF},
68 	{ "consent", SNIPPET_ATTRIBUTE,
69 		G_STRUCT_OFFSET(LassoLibFederationTerminationNotification, consent), NULL, NULL,
70 		NULL},
71 	{NULL, 0, 0, NULL, NULL, NULL}
72 };
73 
74 static struct QuerySnippet query_snippets[] = {
75 	{ "RequestID", NULL },
76 	{ "MajorVersion", NULL },
77 	{ "MinorVersion", NULL },
78 	{ "IssueInstant", NULL },
79 	{ "ProviderID", NULL },
80 	{ "NameIdentifier/NameQualifier", "NameQualifier" },
81 	{ "NameIdentifier/Format", "NameFormat" },
82 	{ "NameIdentifier/content", "NameIdentifier" },
83 	{ "consent", NULL },
84 	{ NULL, NULL }
85 };
86 
87 static LassoNodeClass *parent_class = NULL;
88 
89 static gchar*
build_query(LassoNode * node)90 build_query(LassoNode *node)
91 {
92 	LassoLibFederationTerminationNotification *request;
93 	char *s, *query;
94 	xmlChar *t;
95 
96 	request = LASSO_LIB_FEDERATION_TERMINATION_NOTIFICATION(node);
97 
98 	query = lasso_node_build_query_from_snippets(node);
99 
100 	if (request->RelayState) {
101 		t = xmlURIEscapeStr((xmlChar*)request->RelayState, NULL);
102 		s = g_strdup_printf((char*)t, "%s&RelayState=%s", query, request->RelayState);
103 		xmlFree(t);
104 		lasso_release(query);
105 		query = s;
106 	}
107 
108 	return query;
109 }
110 
111 static gboolean
init_from_query(LassoNode * node,char ** query_fields)112 init_from_query(LassoNode *node, char **query_fields)
113 {
114 	LassoLibFederationTerminationNotification *request;
115 	gboolean rc;
116 
117 	request = LASSO_LIB_FEDERATION_TERMINATION_NOTIFICATION(node);
118 	request->NameIdentifier = lasso_saml_name_identifier_new();
119 
120 	rc = parent_class->init_from_query(node, query_fields);
121 
122 	if (request->ProviderID == NULL ||
123 			request->NameIdentifier->content == NULL ||
124 			request->NameIdentifier->Format == NULL) {
125 		lasso_node_destroy(LASSO_NODE(request->NameIdentifier));
126 		request->NameIdentifier = NULL;
127 		return FALSE;
128 	}
129 
130 	return rc;
131 }
132 
133 
134 
135 
136 /*****************************************************************************/
137 /* instance and class init functions                                         */
138 /*****************************************************************************/
139 
140 
141 static void
class_init(LassoLibFederationTerminationNotificationClass * klass,void * unused G_GNUC_UNUSED)142 class_init(LassoLibFederationTerminationNotificationClass *klass,
143 	   void *unused G_GNUC_UNUSED)
144 {
145 	LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
146 
147 	parent_class = g_type_class_peek_parent(klass);
148 	nclass->build_query = build_query;
149 	nclass->init_from_query = init_from_query;
150 	nclass->node_data = g_new0(LassoNodeClassData, 1);
151 	lasso_node_class_set_nodename(nclass, "FederationTerminationNotification");
152 	lasso_node_class_set_ns(nclass, LASSO_LIB_HREF, LASSO_LIB_PREFIX);
153 	lasso_node_class_add_snippets(nclass, schema_snippets);
154 	lasso_node_class_add_query_snippets(nclass, query_snippets);
155 }
156 
157 GType
lasso_lib_federation_termination_notification_get_type()158 lasso_lib_federation_termination_notification_get_type()
159 {
160 	static GType this_type = 0;
161 
162 	if (!this_type) {
163 		static const GTypeInfo this_info = {
164 			sizeof (LassoLibFederationTerminationNotificationClass),
165 			NULL,
166 			NULL,
167 			(GClassInitFunc) class_init,
168 			NULL,
169 			NULL,
170 			sizeof(LassoLibFederationTerminationNotification),
171 			0,
172 			NULL,
173 			NULL
174 		};
175 
176 		this_type = g_type_register_static(LASSO_TYPE_SAMLP_REQUEST_ABSTRACT,
177 				"LassoLibFederationTerminationNotification", &this_info, 0);
178 	}
179 	return this_type;
180 }
181 
182 /**
183  * lasso_lib_federation_termination_notification_new:
184  *
185  * Creates a new #LassoLibFederationTerminationNotification object.
186  *
187  * Return value: a newly created #LassoLibFederationTerminationNotification
188  *     object
189  **/
190 LassoNode*
lasso_lib_federation_termination_notification_new()191 lasso_lib_federation_termination_notification_new()
192 {
193 	return g_object_new(LASSO_TYPE_LIB_FEDERATION_TERMINATION_NOTIFICATION, NULL);
194 }
195 
196 
197 /**
198  * lasso_lib_federation_termination_notification_new_full:
199  * @providerID: the provider ID doing the notification
200  * @nameIdentifier: the name identifier for the federation to terminate.
201  * @sign_type: a #LassoSignatureType value
202  * @sign_method: a #LassoSignatureMethod value
203  *
204  * Creates a new #LassoLibFederationTerminationNotification object and
205  * initializes it with the parameters.
206  *
207  * Return value: a newly created #LassoLibFederationTerminationNotification
208  *     object
209  **/
210 LassoNode*
lasso_lib_federation_termination_notification_new_full(char * providerID,LassoSamlNameIdentifier * nameIdentifier,LassoSignatureType sign_type,LassoSignatureMethod sign_method)211 lasso_lib_federation_termination_notification_new_full(char *providerID,
212 		LassoSamlNameIdentifier *nameIdentifier,
213 		LassoSignatureType sign_type, LassoSignatureMethod sign_method)
214 {
215 	LassoSamlpRequestAbstract *request;
216 
217 	request = g_object_new(LASSO_TYPE_LIB_FEDERATION_TERMINATION_NOTIFICATION, NULL);
218 
219 	request->RequestID = lasso_build_unique_id(32);
220 	request->MajorVersion = LASSO_LIB_MAJOR_VERSION_N;
221 	request->MinorVersion = LASSO_LIB_MINOR_VERSION_N;
222 	request->IssueInstant = lasso_get_current_time();
223 	request->sign_type = sign_type;
224 	request->sign_method = sign_method;
225 
226 	LASSO_LIB_FEDERATION_TERMINATION_NOTIFICATION(request)->ProviderID = g_strdup(providerID);
227 	LASSO_LIB_FEDERATION_TERMINATION_NOTIFICATION(request)->NameIdentifier =
228 		g_object_ref(nameIdentifier);
229 
230 	return LASSO_NODE(request);
231 }
232