fix build for --disable-gtk-doc
[swfdec.git] / swfdec / swfdec_sandbox.c
blobc605f1a0a411e9316dd89b3a2a5120149a58fa15
1 /* Swfdec
2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "swfdec_sandbox.h"
25 #include "swfdec_as_internal.h"
26 #include "swfdec_debug.h"
27 #include "swfdec_initialize.h"
28 #include "swfdec_internal.h"
29 #include "swfdec_player_internal.h"
31 /*** GTK-DOC ***/
33 /**
34 * SECTION:SwfdecSandbox
35 * @title: SwfdecSandbox
36 * @short_description: global object used for security
38 * The SwfdecSandbox object is a garbage-collected script object that does two
39 * things. The simple thing is its use as the global object while code is
40 * executed in a #SwfdecPlayer. So you can always assume that the global object
41 * is a #SwfdecSandbox. The second task it fulfills is acting as the security
42 * mechanism used by native functions to determine if a given action should be
43 * allowed or not. This is easy, because script functions can always refer to
44 * it as the global object.
47 G_DEFINE_TYPE (SwfdecSandbox, swfdec_sandbox, SWFDEC_TYPE_AS_RELAY)
49 static void
50 swfdec_sandbox_dispose (GObject *object)
52 SwfdecSandbox *sandbox = SWFDEC_SANDBOX (object);
54 swfdec_url_free (sandbox->url);
56 G_OBJECT_CLASS (swfdec_sandbox_parent_class)->dispose (object);
59 static void
60 swfdec_sandbox_class_init (SwfdecSandboxClass *klass)
62 GObjectClass *object_class = G_OBJECT_CLASS (klass);
64 object_class->dispose = swfdec_sandbox_dispose;
67 static void
68 swfdec_sandbox_init (SwfdecSandbox *sandbox)
70 sandbox->type = SWFDEC_SANDBOX_NONE;
73 static void
74 swfdec_sandbox_initialize (SwfdecSandbox *sandbox, guint version)
76 SwfdecAsContext *context = swfdec_gc_object_get_context (sandbox);
77 SwfdecPlayer *player = SWFDEC_PLAYER (context);
79 swfdec_sandbox_use (sandbox);
80 if (context->state == SWFDEC_AS_CONTEXT_RUNNING)
81 context->state = SWFDEC_AS_CONTEXT_NEW;
82 swfdec_as_context_startup (context);
83 /* reset state for initialization */
84 /* FIXME: have a better way to do this */
85 context->state = SWFDEC_AS_CONTEXT_NEW;
86 swfdec_net_stream_init_context (player);
88 swfdec_as_context_run_init_script (context, swfdec_initialize,
89 sizeof (swfdec_initialize), version);
91 if (context->state == SWFDEC_AS_CONTEXT_NEW)
92 context->state = SWFDEC_AS_CONTEXT_RUNNING;
93 swfdec_sandbox_unuse (sandbox);
96 /**
97 * swfdec_sandbox_set_allow_network:
98 * @sandbox: a #SwfdecSandbox
99 * @network: %TRUE if network access is possible
101 * Checks if the given sandbox may be loaded and if so initializes its type.
102 * This function should be called on every new sandbox.
104 * Returns: %TRUE if the sandbox initialization could be finished as requested,
105 * %FALSE if not and it shouldn't be used.
107 static gboolean
108 swfdec_sandbox_set_allow_network (SwfdecSandbox *sandbox, gboolean network)
110 g_return_val_if_fail (SWFDEC_IS_SANDBOX (sandbox), FALSE);
112 switch (sandbox->type) {
113 case SWFDEC_SANDBOX_REMOTE:
114 return TRUE;
115 case SWFDEC_SANDBOX_LOCAL_FILE:
116 return !network;
117 case SWFDEC_SANDBOX_LOCAL_NETWORK:
118 return network;
119 case SWFDEC_SANDBOX_LOCAL_TRUSTED:
120 return TRUE;
121 case SWFDEC_SANDBOX_NONE:
122 break;
123 default:
124 g_assert_not_reached ();
125 break;
128 if (swfdec_url_is_local (sandbox->url)) {
129 sandbox->type = network ? SWFDEC_SANDBOX_LOCAL_NETWORK : SWFDEC_SANDBOX_LOCAL_FILE;
130 } else {
131 sandbox->type = SWFDEC_SANDBOX_REMOTE;
134 return TRUE;
138 * swfdec_sandbox_get_for_url:
139 * @player: a #SwfdecPlayer
140 * @url: the URL this player refers to
141 * @flash_version: The Flash version for looking up the sandbox
142 * @allow_network: %TRUE to allow network access, %FALSE to only allow local
143 * file access. See the documentation of the use_network flag
144 * of the SWF FileAttributes tag for what that means.
146 * Checks if a sandbox is already in use for a given URL and if so, returns it.
147 * Otherwise a new sandbox is created, initialized and returned.
148 * Note that the given url must be a HTTP, HTTPS or a FILE url.
150 * Returns: the sandbox corresponding to the given URL or %NULL if no such
151 * sandbox is allowed.
153 SwfdecSandbox *
154 swfdec_sandbox_get_for_url (SwfdecPlayer *player, const SwfdecURL *url,
155 guint flash_version, gboolean allow_network)
157 SwfdecPlayerPrivate *priv;
158 SwfdecSandbox *sandbox;
159 SwfdecURL *real;
160 guint as_version;
161 GSList *walk;
163 g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
164 g_return_val_if_fail (url != NULL, NULL);
166 priv = player->priv;
167 real = swfdec_url_new_components (swfdec_url_get_protocol (url),
168 swfdec_url_get_host (url), swfdec_url_get_port (url), NULL, NULL);
169 as_version = flash_version < 7 ? 1 : 2;
171 for (walk = priv->sandboxes; walk; walk = walk->next) {
172 sandbox = walk->data;
173 if (sandbox->as_version == as_version &&
174 swfdec_url_equal (sandbox->url, real))
175 break;
178 if (walk) {
179 swfdec_url_free (real);
181 if (!swfdec_sandbox_set_allow_network (sandbox, allow_network))
182 return NULL;
183 } else {
184 SwfdecAsContext *context = SWFDEC_AS_CONTEXT (player);
185 SwfdecAsObject *object;
187 sandbox = g_object_new (SWFDEC_TYPE_SANDBOX, "context", context, NULL);
188 sandbox->url = real;
189 sandbox->as_version = as_version;
190 priv->sandboxes = g_slist_append (priv->sandboxes, sandbox);
192 if (!swfdec_sandbox_set_allow_network (sandbox, allow_network))
193 return NULL;
195 object = swfdec_as_object_new_empty (context);
196 swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (sandbox));
198 swfdec_sandbox_initialize (sandbox, flash_version);
201 return sandbox;
205 * swfdec_sandbox_get:
206 * @player: a SwfdecPlayer
208 * Gets the currently in-use sandbox.
210 * Returns: A #SwfdecSandbox
212 SwfdecSandbox *
213 swfdec_sandbox_get (SwfdecPlayer *player)
215 g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
216 g_return_val_if_fail (SWFDEC_AS_CONTEXT (player)->global != NULL, NULL);
217 g_return_val_if_fail (SWFDEC_IS_SANDBOX (SWFDEC_AS_CONTEXT (player)->global->relay), NULL);
219 return SWFDEC_SANDBOX (SWFDEC_AS_CONTEXT (player)->global->relay);
223 * swfdec_sandbox_use:
224 * @sandbox: the sandbox to use when executing scripts
226 * Sets @sandbox to be used for scripts that are going to be executed next. No
227 * sandbox may be set yet. You must unset the sandbox with
228 * swfdec_sandbox_unuse() after calling your script.
230 void
231 swfdec_sandbox_use (SwfdecSandbox *sandbox)
233 SwfdecAsContext *context;
234 SwfdecPlayerPrivate *priv;
236 g_return_if_fail (SWFDEC_IS_SANDBOX (sandbox));
237 g_return_if_fail (sandbox->type != SWFDEC_SANDBOX_NONE);
238 g_return_if_fail (swfdec_gc_object_get_context (sandbox)->global == NULL);
240 context = swfdec_gc_object_get_context (sandbox);
241 priv = SWFDEC_PLAYER (context)->priv;
242 context->global = swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sandbox));
246 * swfdec_sandbox_try_use:
247 * @sandbox: the sandbox to use
249 * Makes sure a sandbox is in use. If no sandbox is in use currently, use the
250 * given @sandbox. This function is intended for cases where code can be called
251 * from both inside scripts with a sandbox already set or outside with no
252 * sandbox in use.
254 * Returns: %TRUE if the new sandbox will be used. You need to call
255 * swfdec_sandbox_unuse() afterwards. %FALSE if a sandbox is already in
256 * use.
258 gboolean
259 swfdec_sandbox_try_use (SwfdecSandbox *sandbox)
261 g_return_val_if_fail (SWFDEC_IS_SANDBOX (sandbox), FALSE);
262 g_return_val_if_fail (sandbox->type != SWFDEC_SANDBOX_NONE, FALSE);
264 if (swfdec_gc_object_get_context (sandbox)->global)
265 return FALSE;
267 swfdec_sandbox_use (sandbox);
268 return TRUE;
272 * swfdec_sandbox_unuse:
273 * @sandbox: a #SwfdecSandbox
275 * Unsets the sandbox as the current sandbox for executing scripts.
277 void
278 swfdec_sandbox_unuse (SwfdecSandbox *sandbox)
280 SwfdecAsContext *context;
282 g_return_if_fail (SWFDEC_IS_SANDBOX (sandbox));
283 g_return_if_fail (swfdec_gc_object_get_context (sandbox)->global != NULL);
284 g_return_if_fail (swfdec_gc_object_get_context (sandbox)->global->relay == SWFDEC_AS_RELAY (sandbox));
286 context = swfdec_gc_object_get_context (sandbox);
287 context->global = NULL;
290 gboolean
291 swfdec_sandbox_allow (SwfdecSandbox *sandbox, SwfdecSandbox *other)
293 g_return_val_if_fail (SWFDEC_IS_SANDBOX (sandbox), FALSE);
294 g_return_val_if_fail (SWFDEC_IS_SANDBOX (other), FALSE);
296 SWFDEC_FIXME ("implement script sandbox interaction");
297 return TRUE;