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
24 /**
25 * SECTION:federation
26 * @short_description: Principal federation between two providers
27 *
28 * A #LassoFederation represents the an identifier shared by two provider, usually an identity
29 * provider and a service provider. Instance of this class are usually never accessed directly.
30 **/
31
32 #include "../utils.h"
33 #include "../xml/private.h"
34 #include "federation.h"
35 #include "provider.h"
36
37 #include "../xml/saml-2.0/saml2_name_id.h"
38
39 struct _LassoFederationPrivate
40 {
41 gboolean dispose_has_run;
42 };
43
44 /*****************************************************************************/
45 /* static methods/functions */
46 /*****************************************************************************/
47
48 static LassoNode*
lasso_federation_build_name_identifier(const gchar * nameQualifier,const gchar * format,const gchar * content)49 lasso_federation_build_name_identifier(const gchar *nameQualifier,
50 const gchar *format, const gchar *content)
51 {
52 LassoSamlNameIdentifier *nameIdentifier;
53
54 nameIdentifier = LASSO_SAML_NAME_IDENTIFIER(lasso_saml_name_identifier_new());
55 if (content == NULL) {
56 nameIdentifier->content = lasso_build_unique_id(32);
57 } else {
58 nameIdentifier->content = g_strdup(content);
59 }
60 nameIdentifier->NameQualifier = g_strdup(nameQualifier);
61 nameIdentifier->Format = g_strdup(format);
62
63 return LASSO_NODE(nameIdentifier);
64 }
65
66 /*****************************************************************************/
67 /* public methods */
68 /*****************************************************************************/
69
70 /**
71 * lasso_federation_build_local_name_identifier:
72 * @federation: a #LassoFederation
73 * @nameQualifier: the name identifier qualifier
74 * @format: the name identifier format
75 * @content: the name identifier content
76 *
77 * Builds federation local name identifier.
78 **/
79 void
lasso_federation_build_local_name_identifier(LassoFederation * federation,const gchar * nameQualifier,const gchar * format,const gchar * content)80 lasso_federation_build_local_name_identifier(LassoFederation *federation,
81 const gchar *nameQualifier,
82 const gchar *format,
83 const gchar *content)
84 {
85 federation->local_nameIdentifier = lasso_federation_build_name_identifier(
86 nameQualifier, format, content);
87 }
88
89 /**
90 * lasso_federation_destroy:
91 * @federation: a #LassoFederation
92 *
93 * Destroys a federation.
94 **/
95 void
lasso_federation_destroy(LassoFederation * federation)96 lasso_federation_destroy(LassoFederation *federation)
97 {
98 lasso_node_destroy(LASSO_NODE(federation));
99 }
100
101 /**
102 * lasso_federation_verify_name_identifier:
103 * @federation: a #LassoFederation
104 * @name_identifier: the #LassoSamlNameIdentifier
105 *
106 * Checks whether federation is for @name_identifier.
107 *
108 * Return value: %TRUE if the federation is for @name_identifier.
109 **/
110 gboolean
lasso_federation_verify_name_identifier(LassoFederation * federation,LassoNode * name_identifier)111 lasso_federation_verify_name_identifier(LassoFederation *federation,
112 LassoNode *name_identifier)
113 {
114 LassoProtocolConformance conformance;
115 char *s, *content;
116
117 g_return_val_if_fail(LASSO_IS_FEDERATION(federation), FALSE);
118 g_return_val_if_fail(LASSO_IS_NODE(name_identifier), FALSE);
119
120 if (LASSO_IS_SAML_NAME_IDENTIFIER(name_identifier)) {
121 conformance = LASSO_PROTOCOL_LIBERTY_1_2;
122 content = LASSO_SAML_NAME_IDENTIFIER(name_identifier)->content;
123 } else if (LASSO_IS_SAML2_NAME_ID(name_identifier)) {
124 conformance = LASSO_PROTOCOL_SAML_2_0;
125 content = LASSO_SAML2_NAME_ID(name_identifier)->content;
126 } else {
127 return FALSE;
128 }
129
130 /* verify local name identifier */
131 if (federation->local_nameIdentifier != NULL) {
132 if (conformance == LASSO_PROTOCOL_LIBERTY_1_2) {
133 s = LASSO_SAML_NAME_IDENTIFIER(federation->local_nameIdentifier)->content;
134 } else {
135 s = LASSO_SAML2_NAME_ID(federation->local_nameIdentifier)->content;
136 }
137 if (strcmp(s, content) == 0) {
138 return TRUE;
139 }
140 }
141
142 /* verify remote name identifier */
143 if (federation->remote_nameIdentifier != NULL) {
144 if (conformance == LASSO_PROTOCOL_LIBERTY_1_2) {
145 s = LASSO_SAML_NAME_IDENTIFIER(federation->remote_nameIdentifier)->content;
146 } else {
147 s = LASSO_SAML2_NAME_ID(federation->remote_nameIdentifier)->content;
148 }
149 if (strcmp(s, content) == 0) {
150 return TRUE;
151 }
152 }
153
154 return FALSE;
155 }
156
157
158 /*****************************************************************************/
159 /* private methods */
160 /*****************************************************************************/
161
162 static struct XmlSnippet schema_snippets[] = {
163 { "LocalNameIdentifier", SNIPPET_NODE_IN_CHILD,
164 G_STRUCT_OFFSET(LassoFederation, local_nameIdentifier), NULL, NULL, NULL},
165 { "RemoteNameIdentifier", SNIPPET_NODE_IN_CHILD,
166 G_STRUCT_OFFSET(LassoFederation, remote_nameIdentifier), NULL, NULL, NULL},
167 { "RemoteProviderID", SNIPPET_ATTRIBUTE,
168 G_STRUCT_OFFSET(LassoFederation, remote_providerID), NULL, NULL, NULL},
169 { "FederationDumpVersion", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL },
170 {NULL, 0, 0, NULL, NULL, NULL}
171 };
172
173 static LassoNodeClass *parent_class = NULL;
174
175 static xmlNode*
get_xmlNode(LassoNode * node,gboolean lasso_dump)176 get_xmlNode(LassoNode *node, gboolean lasso_dump)
177 {
178 xmlNode *xmlnode;
179
180 xmlnode = parent_class->get_xmlNode(node, lasso_dump);
181 xmlSetProp(xmlnode, (xmlChar*)"FederationDumpVersion", (xmlChar*)"2");
182
183 return xmlnode;
184 }
185
186 static int
init_from_xml(LassoNode * node,xmlNode * xmlnode)187 init_from_xml(LassoNode *node, xmlNode *xmlnode)
188 {
189 return parent_class->init_from_xml(node, xmlnode);
190 }
191
192 /*****************************************************************************/
193 /* overridden parent class methods */
194 /*****************************************************************************/
195
196 static void
dispose(GObject * object)197 dispose(GObject *object)
198 {
199 LassoFederation *federation = LASSO_FEDERATION(object);
200 if (federation->private_data->dispose_has_run) {
201 return;
202 }
203 federation->private_data->dispose_has_run = TRUE;
204
205 G_OBJECT_CLASS(parent_class)->dispose(object);
206 }
207
208 static void
finalize(GObject * object)209 finalize(GObject *object)
210 {
211 LassoFederation *federation = LASSO_FEDERATION(object);
212 lasso_release(federation->private_data);
213 G_OBJECT_CLASS(parent_class)->finalize(object);
214 }
215
216 /*****************************************************************************/
217 /* instance and class init functions */
218 /*****************************************************************************/
219
220 static void
instance_init(LassoFederation * federation)221 instance_init(LassoFederation *federation)
222 {
223 federation->private_data = g_new0(LassoFederationPrivate, 1);
224 federation->private_data->dispose_has_run = FALSE;
225
226 federation->remote_providerID = NULL;
227 federation->local_nameIdentifier = NULL;
228 federation->remote_nameIdentifier = NULL;
229 }
230
231 static void
class_init(LassoFederationClass * klass,void * unused G_GNUC_UNUSED)232 class_init(LassoFederationClass *klass, void *unused G_GNUC_UNUSED)
233 {
234 LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
235
236 parent_class = g_type_class_peek_parent(klass);
237 nclass->get_xmlNode = get_xmlNode;
238 nclass->init_from_xml = init_from_xml;
239 nclass->node_data = g_new0(LassoNodeClassData, 1);
240 lasso_node_class_set_nodename(nclass, "Federation");
241 lasso_node_class_set_ns(nclass, LASSO_LASSO_HREF, LASSO_LASSO_PREFIX);
242 lasso_node_class_add_snippets(nclass, schema_snippets);
243
244 G_OBJECT_CLASS(klass)->dispose = dispose;
245 G_OBJECT_CLASS(klass)->finalize = finalize;
246 }
247
248 GType
lasso_federation_get_type()249 lasso_federation_get_type()
250 {
251 static GType this_type = 0;
252
253 if (!this_type) {
254 static const GTypeInfo this_info = {
255 sizeof (LassoFederationClass),
256 NULL,
257 NULL,
258 (GClassInitFunc) class_init,
259 NULL,
260 NULL,
261 sizeof(LassoFederation),
262 0,
263 (GInstanceInitFunc) instance_init,
264 NULL
265 };
266
267 this_type = g_type_register_static(LASSO_TYPE_NODE,
268 "LassoFederation", &this_info, 0);
269 }
270 return this_type;
271 }
272
273 /**
274 * lasso_federation_new:
275 * @remote_providerID: remote Provider ID
276 *
277 * Creates a new #LassoFederation with the remote provider.
278 *
279 * Return value: a newly created #LassoFederation
280 **/
281 LassoFederation*
lasso_federation_new(const gchar * remote_providerID)282 lasso_federation_new(const gchar *remote_providerID)
283 {
284 LassoFederation *federation;
285
286 g_return_val_if_fail(remote_providerID != NULL, NULL);
287
288 federation = LASSO_FEDERATION(g_object_new(LASSO_TYPE_FEDERATION, NULL));
289 federation->remote_providerID = g_strdup(remote_providerID);
290
291 return federation;
292 }
293