export SwfdecPlayer structure
[swfdec.git] / libswfdec / swfdec_policy_loader.c
blob6d04c75efa45aeecc322837e2ecbdfb8265083d2
1 /* Swfdec
2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
3 * 2007 Pekka Lampila <pekka.lampila@iki.fi>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include <string.h>
27 #include "swfdec_policy_loader.h"
28 #include "swfdec_flash_security.h"
29 #include "swfdec_resource.h"
30 #include "swfdec_as_strings.h"
31 #include "swfdec_debug.h"
32 #include "swfdec_loader_internal.h"
33 #include "swfdec_player_internal.h"
34 #include "swfdec_xml.h"
35 #include "swfdec_xml_node.h"
37 /*** SWFDEC_LOADER_TARGET ***/
39 static SwfdecPlayer *
40 swfdec_policy_loader_target_get_player (SwfdecLoaderTarget *target)
42 return SWFDEC_POLICY_LOADER (target)->sec->player;
45 static void
46 swfdec_policy_loader_target_error (SwfdecLoaderTarget *target,
47 SwfdecLoader *loader)
49 SwfdecPolicyLoader *policy_loader = SWFDEC_POLICY_LOADER (target);
51 policy_loader->func (policy_loader, FALSE);
54 static gboolean
55 swfdec_policy_loader_check (SwfdecAsContext *context, const char *text,
56 const char *host)
58 SwfdecXml *xml;
59 gint32 i, j;
60 char *host_lower;
62 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
63 g_return_val_if_fail (text != NULL, FALSE);
65 xml = swfdec_xml_new_no_properties (context, text, TRUE);
67 if (xml == NULL) {
68 SWFDEC_ERROR ("failed to create an XML object for crossdomain policy");
69 return FALSE;
72 if (SWFDEC_XML_NODE (xml)->type != SWFDEC_XML_NODE_ELEMENT) {
73 SWFDEC_LOG ("empty crossdomain policy file");
74 return FALSE;
77 if (host != NULL) {
78 host_lower = g_ascii_strdown (host, -1);
79 } else {
80 host_lower = NULL;
83 for (i = 0; i < swfdec_xml_node_num_children (SWFDEC_XML_NODE (xml)); i++) {
84 SwfdecXmlNode *node_cdp =
85 swfdec_xml_node_get_child (SWFDEC_XML_NODE (xml), i);
87 if (node_cdp->type != SWFDEC_XML_NODE_ELEMENT)
88 continue;
90 if (g_ascii_strcasecmp (node_cdp->name, "cross-domain-policy") != 0)
91 continue;
93 for (j = 0; j < swfdec_xml_node_num_children (node_cdp); j++) {
94 SwfdecXmlNode *node_aaf = swfdec_xml_node_get_child (node_cdp, j);
95 const char *value;
96 GPatternSpec *pattern;
97 char *value_lower;
99 if (node_aaf->type != SWFDEC_XML_NODE_ELEMENT)
100 continue;
102 if (g_ascii_strcasecmp (node_aaf->name, "allow-access-from") != 0)
103 continue;
105 // FIXME: secure attribute?
107 value = swfdec_xml_node_get_attribute (node_aaf, SWFDEC_AS_STR_domain);
108 if (value == NULL)
109 continue;
111 if (host != NULL) {
112 // GPatternSpec uses ? as a wildcard character, but we won't
113 // And there can't be a host that has ? character
114 if (strchr (value, '?') != NULL)
115 continue;
117 value_lower = g_ascii_strdown (value, -1);
118 pattern = g_pattern_spec_new (value_lower);
119 g_free (value_lower);
121 if (g_pattern_match_string (pattern, host_lower)) {
122 g_free (host_lower);
123 g_pattern_spec_free (pattern);
124 return TRUE;
127 g_pattern_spec_free (pattern);
128 } else {
129 // in case we don't have a host name, only match asterisks
130 if (value[strspn (value, "*")] == '\0')
131 return TRUE;
136 g_free (host_lower);
138 return FALSE;
141 static void
142 swfdec_policy_loader_target_eof (SwfdecLoaderTarget *target,
143 SwfdecLoader *loader)
145 SwfdecPolicyLoader *policy_loader = SWFDEC_POLICY_LOADER (target);
146 gboolean allow;
147 char *text;
149 text = swfdec_loader_get_text (policy_loader->loader, 8);
151 if (text == NULL) {
152 SWFDEC_ERROR ("couldn't get text from crossdomain policy");
153 allow = FALSE;
154 } else {
155 allow = swfdec_policy_loader_check (
156 SWFDEC_AS_CONTEXT (policy_loader->sec->player), text,
157 swfdec_url_get_host (policy_loader->sec->url));
160 g_free (text);
162 SWFDEC_LOG ("crossdomain policy %s access from %s to %s",
163 (allow ? "allows" : "doesn't allow"),
164 swfdec_url_get_host (policy_loader->sec->url), policy_loader->host);
166 policy_loader->func (policy_loader, allow);
169 static void
170 swfdec_policy_loader_loader_target_init (SwfdecLoaderTargetInterface *iface)
172 iface->get_player = swfdec_policy_loader_target_get_player;
173 iface->eof = swfdec_policy_loader_target_eof;
174 iface->error = swfdec_policy_loader_target_error;
177 /*** SWFDEC_POLICY_LOADER ***/
179 G_DEFINE_TYPE_WITH_CODE (SwfdecPolicyLoader, swfdec_policy_loader, G_TYPE_OBJECT,
180 G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_policy_loader_loader_target_init))
182 static void
183 swfdec_policy_loader_dispose (GObject *object)
185 SwfdecPolicyLoader *policy_loader = SWFDEC_POLICY_LOADER (object);
187 g_assert (policy_loader->loader);
188 swfdec_loader_set_target (policy_loader->loader, NULL);
189 g_object_unref (policy_loader->loader);
190 policy_loader->loader = NULL;
192 g_assert (policy_loader->host);
193 g_free (policy_loader->host);
195 G_OBJECT_CLASS (swfdec_policy_loader_parent_class)->dispose (object);
198 static void
199 swfdec_policy_loader_class_init (SwfdecPolicyLoaderClass *klass)
201 GObjectClass *object_class = G_OBJECT_CLASS (klass);
203 object_class->dispose = swfdec_policy_loader_dispose;
206 static void
207 swfdec_policy_loader_init (SwfdecPolicyLoader *policy_loader)
211 SwfdecPolicyLoader *
212 swfdec_policy_loader_new (SwfdecFlashSecurity *sec, const char *host,
213 SwfdecPolicyLoaderFunc func)
215 SwfdecPolicyLoader *policy_loader;
216 SwfdecURL *url;
217 char *url_str;
219 g_return_val_if_fail (SWFDEC_IS_FLASH_SECURITY (sec), NULL);
220 g_return_val_if_fail (host != NULL, NULL);
221 g_return_val_if_fail (func != NULL, NULL);
223 policy_loader = SWFDEC_POLICY_LOADER (g_object_new (
224 SWFDEC_TYPE_POLICY_LOADER, NULL));
226 url_str = g_strdup_printf ("http://%s/crossdomain.xml", host);
227 url = swfdec_url_new (url_str);
228 g_free (url_str);
229 policy_loader->loader = swfdec_loader_load (sec->player->priv->resource->loader,
230 url, SWFDEC_LOADER_REQUEST_DEFAULT, NULL, 0);
231 swfdec_url_free (url);
233 if (!policy_loader->loader) {
234 g_free (policy_loader);
235 return NULL;
238 policy_loader->sec = sec;
239 policy_loader->host = g_strdup (host);
240 policy_loader->func = func;
242 swfdec_loader_set_target (policy_loader->loader,
243 SWFDEC_LOADER_TARGET (policy_loader));
244 swfdec_loader_set_data_type (policy_loader->loader, SWFDEC_LOADER_DATA_TEXT);
246 return policy_loader;
249 void
250 swfdec_policy_loader_free (SwfdecPolicyLoader *policy_loader)
252 g_return_if_fail (SWFDEC_IS_POLICY_LOADER (policy_loader));
254 g_object_unref (policy_loader);