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.
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
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"
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_OBJECT
)
50 swfdec_sandbox_mark (SwfdecGcObject
*object
)
52 SwfdecSandbox
*sandbox
= SWFDEC_SANDBOX (object
);
54 swfdec_gc_object_mark (sandbox
->Function
);
55 swfdec_gc_object_mark (sandbox
->Function_prototype
);
56 swfdec_gc_object_mark (sandbox
->Object
);
57 swfdec_gc_object_mark (sandbox
->Object_prototype
);
58 swfdec_gc_object_mark (sandbox
->MovieClip
);
59 swfdec_gc_object_mark (sandbox
->Video
);
61 SWFDEC_GC_OBJECT_CLASS (swfdec_sandbox_parent_class
)->mark (object
);
65 swfdec_sandbox_dispose (GObject
*object
)
67 SwfdecSandbox
*sandbox
= SWFDEC_SANDBOX (object
);
69 swfdec_url_free (sandbox
->url
);
71 G_OBJECT_CLASS (swfdec_sandbox_parent_class
)->dispose (object
);
75 swfdec_sandbox_class_init (SwfdecSandboxClass
*klass
)
77 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
78 SwfdecGcObjectClass
*gc_class
= SWFDEC_GC_OBJECT_CLASS (klass
);
80 object_class
->dispose
= swfdec_sandbox_dispose
;
82 gc_class
->mark
= swfdec_sandbox_mark
;
86 swfdec_sandbox_init (SwfdecSandbox
*sandbox
)
88 sandbox
->type
= SWFDEC_SANDBOX_NONE
;
92 swfdec_sandbox_initialize (SwfdecSandbox
*sandbox
, guint version
)
94 SwfdecAsContext
*context
= swfdec_gc_object_get_context (sandbox
);
95 SwfdecPlayer
*player
= SWFDEC_PLAYER (context
);
97 swfdec_sandbox_use (sandbox
);
98 if (context
->state
== SWFDEC_AS_CONTEXT_RUNNING
)
99 context
->state
= SWFDEC_AS_CONTEXT_NEW
;
100 swfdec_as_context_startup (context
);
101 /* reset state for initialization */
102 /* FIXME: have a better way to do this */
103 context
->state
= SWFDEC_AS_CONTEXT_NEW
;
104 swfdec_sprite_movie_init_context (player
);
105 swfdec_video_movie_init_context (player
);
106 swfdec_net_stream_init_context (player
);
108 swfdec_as_context_run_init_script (context
, swfdec_initialize
,
109 sizeof (swfdec_initialize
), version
);
111 sandbox
->Function
= context
->Function
;
112 sandbox
->Function_prototype
= context
->Function_prototype
;
113 sandbox
->Object
= context
->Object
;
114 sandbox
->Object_prototype
= context
->Object_prototype
;
116 if (context
->state
== SWFDEC_AS_CONTEXT_NEW
)
117 context
->state
= SWFDEC_AS_CONTEXT_RUNNING
;
118 swfdec_sandbox_unuse (sandbox
);
122 * swfdec_sandbox_set_allow_network:
123 * @sandbox: a #SwfdecSandbox
124 * @network: %TRUE if network access is possible
126 * Checks if the given sandbox may be loaded and if so initializes its type.
127 * This function should be called on every new sandbox.
129 * Returns: %TRUE if the sandbox initialization could be finished as requested,
130 * %FALSE if not and it shouldn't be used.
133 swfdec_sandbox_set_allow_network (SwfdecSandbox
*sandbox
, gboolean network
)
135 g_return_val_if_fail (SWFDEC_IS_SANDBOX (sandbox
), FALSE
);
137 switch (sandbox
->type
) {
138 case SWFDEC_SANDBOX_REMOTE
:
140 case SWFDEC_SANDBOX_LOCAL_FILE
:
142 case SWFDEC_SANDBOX_LOCAL_NETWORK
:
144 case SWFDEC_SANDBOX_LOCAL_TRUSTED
:
146 case SWFDEC_SANDBOX_NONE
:
149 g_assert_not_reached ();
153 if (swfdec_url_is_local (sandbox
->url
)) {
154 sandbox
->type
= network
? SWFDEC_SANDBOX_LOCAL_NETWORK
: SWFDEC_SANDBOX_LOCAL_FILE
;
156 sandbox
->type
= SWFDEC_SANDBOX_REMOTE
;
163 * swfdec_sandbox_get_for_url:
164 * @player: a #SwfdecPlayer
165 * @url: the URL this player refers to
166 * @flash_version: The Flash version for looking up the sandbox
167 * @allow_network: %TRUE to allow network access, %FALSE to only allow local
168 * file access. See the documentation of the use_network flag
169 * of the SWF FileAttributes tag for what that means.
171 * Checks if a sandbox is already in use for a given URL and if so, returns it.
172 * Otherwise a new sandbox is created, initialized and returned.
173 * Note that the given url must be a HTTP, HTTPS or a FILE url.
175 * Returns: the sandbox corresponding to the given URL or %NULL if no such
176 * sandbox is allowed.
179 swfdec_sandbox_get_for_url (SwfdecPlayer
*player
, const SwfdecURL
*url
,
180 guint flash_version
, gboolean allow_network
)
182 SwfdecPlayerPrivate
*priv
;
183 SwfdecSandbox
*sandbox
;
188 g_return_val_if_fail (SWFDEC_IS_PLAYER (player
), NULL
);
189 g_return_val_if_fail (url
!= NULL
, NULL
);
192 real
= swfdec_url_new_components (swfdec_url_get_protocol (url
),
193 swfdec_url_get_host (url
), swfdec_url_get_port (url
), NULL
, NULL
);
194 as_version
= flash_version
< 7 ? 1 : 2;
196 for (walk
= priv
->sandboxes
; walk
; walk
= walk
->next
) {
197 sandbox
= walk
->data
;
198 if (sandbox
->as_version
== as_version
&&
199 swfdec_url_equal (sandbox
->url
, real
))
204 swfdec_url_free (real
);
206 if (!swfdec_sandbox_set_allow_network (sandbox
, allow_network
))
209 SwfdecAsContext
*context
= SWFDEC_AS_CONTEXT (player
);
211 sandbox
= g_object_new (SWFDEC_TYPE_SANDBOX
, "context", context
, NULL
);
213 sandbox
->as_version
= as_version
;
214 priv
->sandboxes
= g_slist_append (priv
->sandboxes
, sandbox
);
216 if (!swfdec_sandbox_set_allow_network (sandbox
, allow_network
))
219 swfdec_sandbox_initialize (sandbox
, flash_version
);
227 * swfdec_sandbox_use:
228 * @sandbox: the sandbox to use when executing scripts
230 * Sets @sandbox to be used for scripts that are going to be executed next. No
231 * sandbox may be set yet. You must unset the sandbox with
232 * swfdec_sandbox_unuse() after calling your script.
235 swfdec_sandbox_use (SwfdecSandbox
*sandbox
)
237 SwfdecAsContext
*context
;
238 SwfdecPlayerPrivate
*priv
;
240 g_return_if_fail (SWFDEC_IS_SANDBOX (sandbox
));
241 g_return_if_fail (sandbox
->type
!= SWFDEC_SANDBOX_NONE
);
242 g_return_if_fail (swfdec_gc_object_get_context (sandbox
)->global
== NULL
);
244 context
= swfdec_gc_object_get_context (sandbox
);
245 priv
= SWFDEC_PLAYER (context
)->priv
;
246 context
->global
= SWFDEC_AS_OBJECT (sandbox
);
248 context
->Function
= sandbox
->Function
;
249 context
->Function_prototype
= sandbox
->Function_prototype
;
250 context
->Object
= sandbox
->Object
;
251 context
->Object_prototype
= sandbox
->Object_prototype
;
255 * swfdec_sandbox_try_use:
256 * @sandbox: the sandbox to use
258 * Makes sure a sandbox is in use. If no sandbox is in use currently, use the
259 * given @sandbox. This function is intended for cases where code can be called
260 * from both inside scripts with a sandbox already set or outside with no
263 * Returns: %TRUE if the new sandbox will be used. You need to call
264 * swfdec_sandbox_unuse() afterwards. %FALSE if a sandbox is already in
268 swfdec_sandbox_try_use (SwfdecSandbox
*sandbox
)
270 g_return_val_if_fail (SWFDEC_IS_SANDBOX (sandbox
), FALSE
);
271 g_return_val_if_fail (sandbox
->type
!= SWFDEC_SANDBOX_NONE
, FALSE
);
273 if (swfdec_gc_object_get_context (sandbox
)->global
)
276 swfdec_sandbox_use (sandbox
);
281 * swfdec_sandbox_unuse:
282 * @sandbox: a #SwfdecSandbox
284 * Unsets the sandbox as the current sandbox for executing scripts.
287 swfdec_sandbox_unuse (SwfdecSandbox
*sandbox
)
289 SwfdecAsContext
*context
;
291 g_return_if_fail (SWFDEC_IS_SANDBOX (sandbox
));
292 g_return_if_fail (swfdec_gc_object_get_context (sandbox
)->global
== SWFDEC_AS_OBJECT (sandbox
));
294 context
= swfdec_gc_object_get_context (sandbox
);
295 context
->global
= NULL
;
296 context
->Function
= NULL
;
297 context
->Function_prototype
= NULL
;
298 context
->Object
= NULL
;
299 context
->Object_prototype
= NULL
;