1 /*
2 * Copyright (C) 2009 Martin Robinson, Jan Michael C. Alonzo
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 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 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21 #include "webkitsecurityorigin.h"
22
23 #include "DatabaseTracker.h"
24 #include "PlatformString.h"
25 #include "webkitglobalsprivate.h"
26 #include "webkitsecurityoriginprivate.h"
27 #include <glib/gi18n-lib.h>
28 #include <wtf/text/CString.h>
29
30 /**
31 * SECTION:webkitsecurityorigin
32 * @short_description: A security boundary for web sites
33 *
34 * #WebKitSecurityOrigin is a representation of a security domain defined
35 * by web sites. An origin consists of a host name, a protocol, and a port
36 * number. Web sites with the same security origin can access each other's
37 * resources for client-side scripting or database access.
38 *
39 * Use #webkit_web_frame_get_security_origin to get the security origin of a
40 * #WebKitWebFrame.
41 *
42 * Database quotas and usages are also defined per security origin. The
43 * cumulative disk usage of an origin's databases may be retrieved with
44 * #webkit_security_origin_get_web_database_usage. An origin's quota can be
45 * adjusted with #webkit_security_origin_set_web_database_quota.
46 */
47
48 using namespace WebKit;
49
50 enum {
51 PROP_0,
52
53 PROP_PROTOCOL,
54 PROP_HOST,
55 PROP_PORT,
56 PROP_DATABASE_USAGE,
57 PROP_DATABASE_QUOTA
58 };
59
G_DEFINE_TYPE(WebKitSecurityOrigin,webkit_security_origin,G_TYPE_OBJECT)60 G_DEFINE_TYPE(WebKitSecurityOrigin, webkit_security_origin, G_TYPE_OBJECT)
61
62 static void webkit_security_origin_finalize(GObject* object)
63 {
64 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
65 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
66
67 g_free(priv->protocol);
68 g_free(priv->host);
69
70 G_OBJECT_CLASS(webkit_security_origin_parent_class)->finalize(object);
71 }
72
webkit_security_origin_dispose(GObject * object)73 static void webkit_security_origin_dispose(GObject* object)
74 {
75 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
76 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
77
78 if (!priv->disposed) {
79 priv->coreOrigin->deref();
80 g_hash_table_destroy(priv->webDatabases);
81 priv->disposed = true;
82 }
83
84 G_OBJECT_CLASS(webkit_security_origin_parent_class)->dispose(object);
85 }
86
webkit_security_origin_set_property(GObject * object,guint propId,const GValue * value,GParamSpec * pspec)87 static void webkit_security_origin_set_property(GObject* object, guint propId, const GValue* value, GParamSpec* pspec)
88 {
89 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
90
91 switch (propId) {
92 case PROP_DATABASE_QUOTA:
93 webkit_security_origin_set_web_database_quota(securityOrigin, g_value_get_uint64(value));
94 break;
95 default:
96 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
97 break;
98 }
99 }
100
webkit_security_origin_get_property(GObject * object,guint propId,GValue * value,GParamSpec * pspec)101 static void webkit_security_origin_get_property(GObject* object, guint propId, GValue* value, GParamSpec* pspec)
102 {
103 WebKitSecurityOrigin* securityOrigin = WEBKIT_SECURITY_ORIGIN(object);
104
105 switch (propId) {
106 case PROP_PROTOCOL:
107 g_value_set_string(value, webkit_security_origin_get_protocol(securityOrigin));
108 break;
109 case PROP_HOST:
110 g_value_set_string(value, webkit_security_origin_get_host(securityOrigin));
111 break;
112 case PROP_PORT:
113 g_value_set_uint(value, webkit_security_origin_get_port(securityOrigin));
114 break;
115 case PROP_DATABASE_USAGE:
116 g_value_set_uint64(value, webkit_security_origin_get_web_database_usage(securityOrigin));
117 break;
118 case PROP_DATABASE_QUOTA:
119 g_value_set_uint64(value, webkit_security_origin_get_web_database_quota(securityOrigin));
120 break;
121 default:
122 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
123 break;
124 }
125 }
126
webkit_security_origins()127 static GHashTable* webkit_security_origins()
128 {
129 static GHashTable* securityOrigins = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
130 return securityOrigins;
131 }
132
webkit_security_origin_class_init(WebKitSecurityOriginClass * klass)133 static void webkit_security_origin_class_init(WebKitSecurityOriginClass* klass)
134 {
135 GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
136 gobjectClass->dispose = webkit_security_origin_dispose;
137 gobjectClass->finalize = webkit_security_origin_finalize;
138 gobjectClass->set_property = webkit_security_origin_set_property;
139 gobjectClass->get_property = webkit_security_origin_get_property;
140
141 /**
142 * WebKitSecurityOrigin:protocol:
143 *
144 * The protocol of the security origin.
145 *
146 * Since: 1.1.14
147 */
148 g_object_class_install_property(gobjectClass, PROP_PROTOCOL,
149 g_param_spec_string("protocol",
150 _("Protocol"),
151 _("The protocol of the security origin"),
152 NULL,
153 WEBKIT_PARAM_READABLE));
154
155 /**
156 * WebKitSecurityOrigin:host:
157 *
158 * The host of the security origin.
159 *
160 * Since: 1.1.14
161 */
162 g_object_class_install_property(gobjectClass, PROP_HOST,
163 g_param_spec_string("host",
164 _("Host"),
165 _("The host of the security origin"),
166 NULL,
167 WEBKIT_PARAM_READABLE));
168
169 /**
170 * WebKitSecurityOrigin:port:
171 *
172 * The port of the security origin.
173 *
174 * Since: 1.1.14
175 */
176 g_object_class_install_property(gobjectClass, PROP_PORT,
177 g_param_spec_uint("port",
178 _("Port"),
179 _("The port of the security origin"),
180 0, G_MAXUSHORT, 0,
181 WEBKIT_PARAM_READABLE));
182
183 /**
184 * WebKitSecurityOrigin:web-database-usage:
185 *
186 * The cumulative size of all web databases in the security origin in bytes.
187 *
188 * Since: 1.1.14
189 */
190 g_object_class_install_property(gobjectClass, PROP_DATABASE_USAGE,
191 g_param_spec_uint64("web-database-usage",
192 _("Web Database Usage"),
193 _("The cumulative size of all web databases in the security origin"),
194 0, G_MAXUINT64, 0,
195 WEBKIT_PARAM_READABLE));
196 /**
197 * WebKitSecurityOrigin:web-database-quota:
198 *
199 * The web database qouta of the security origin in bytes.
200 *
201 * Since: 1.1.14
202 */
203 g_object_class_install_property(gobjectClass, PROP_DATABASE_QUOTA,
204 g_param_spec_uint64("web-database-quota",
205 _("Web Database Quota"),
206 _("The web database quota of the security origin in bytes"),
207 0, G_MAXUINT64, 0,
208 WEBKIT_PARAM_READWRITE));
209
210 g_type_class_add_private(klass, sizeof(WebKitSecurityOriginPrivate));
211 }
212
webkit_security_origin_init(WebKitSecurityOrigin * securityOrigin)213 static void webkit_security_origin_init(WebKitSecurityOrigin* securityOrigin)
214 {
215 WebKitSecurityOriginPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(securityOrigin, WEBKIT_TYPE_SECURITY_ORIGIN, WebKitSecurityOriginPrivate);
216 priv->webDatabases = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
217 securityOrigin->priv = priv;
218 }
219
220 /**
221 * webkit_security_origin_get_protocol:
222 * @securityOrigin: a #WebKitSecurityOrigin
223 *
224 * Returns the protocol for the security origin.
225 *
226 * Returns: the protocol for the security origin
227 *
228 * Since: 1.1.14
229 **/
webkit_security_origin_get_protocol(WebKitSecurityOrigin * securityOrigin)230 G_CONST_RETURN gchar* webkit_security_origin_get_protocol(WebKitSecurityOrigin* securityOrigin)
231 {
232 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
233
234 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
235 WTF::String protocol = priv->coreOrigin->protocol();
236
237 if (!priv->protocol)
238 priv->protocol = g_strdup(protocol.utf8().data());
239
240 return priv->protocol;
241 }
242
243 /**
244 * webkit_security_origin_get_host:
245 * @securityOrigin: a #WebKitSecurityOrigin
246 *
247 * Returns the hostname for the security origin.
248 *
249 * Returns: the hostname for the security origin
250 *
251 * Since: 1.1.14
252 **/
webkit_security_origin_get_host(WebKitSecurityOrigin * securityOrigin)253 G_CONST_RETURN gchar* webkit_security_origin_get_host(WebKitSecurityOrigin* securityOrigin)
254 {
255 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
256
257 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
258 WTF::String host = priv->coreOrigin->host();
259
260 if (!priv->host)
261 priv->host = g_strdup(host.utf8().data());
262
263 return priv->host;
264 }
265
266 /**
267 * webkit_security_origin_get_port:
268 * @securityOrigin: a #WebKitSecurityOrigin
269 *
270 * Returns the port for the security origin.
271 *
272 * Returns: the port for the security origin
273 *
274 * Since: 1.1.14
275 **/
webkit_security_origin_get_port(WebKitSecurityOrigin * securityOrigin)276 guint webkit_security_origin_get_port(WebKitSecurityOrigin* securityOrigin)
277 {
278 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), 0);
279
280 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
281 return coreOrigin->port();
282 }
283
284 /**
285 * webkit_security_origin_get_web_database_usage:
286 * @securityOrigin: a #WebKitSecurityOrigin
287 *
288 * Returns the cumulative size of all Web Database database's in the origin
289 * in bytes.
290 *
291 * Returns: the cumulative size of all databases
292 *
293 * Since: 1.1.14
294 **/
webkit_security_origin_get_web_database_usage(WebKitSecurityOrigin * securityOrigin)295 guint64 webkit_security_origin_get_web_database_usage(WebKitSecurityOrigin* securityOrigin)
296 {
297 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), 0);
298
299 #if ENABLE(DATABASE)
300 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
301 return WebCore::DatabaseTracker::tracker().usageForOrigin(coreOrigin);
302 #else
303 return 0;
304 #endif
305 }
306
307 /**
308 * webkit_security_origin_get_web_database_quota:
309 * @securityOrigin: a #WebKitSecurityOrigin
310 *
311 * Returns the quota for Web Database storage of the security origin
312 * in bytes.
313 *
314 * Returns: the Web Database quota
315 *
316 * Since: 1.1.14
317 **/
webkit_security_origin_get_web_database_quota(WebKitSecurityOrigin * securityOrigin)318 guint64 webkit_security_origin_get_web_database_quota(WebKitSecurityOrigin* securityOrigin)
319 {
320 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), 0);
321
322 #if ENABLE(DATABASE)
323 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
324 return WebCore::DatabaseTracker::tracker().quotaForOrigin(coreOrigin);
325 #else
326 return 0;
327 #endif
328 }
329
330 /**
331 * webkit_security_origin_set_web_database_quota:
332 * @securityOrigin: a #WebKitSecurityOrigin
333 * @quota: a new Web Database quota in bytes
334 *
335 * Adjust the quota for Web Database storage of the security origin
336 *
337 * Since: 1.1.14
338 **/
webkit_security_origin_set_web_database_quota(WebKitSecurityOrigin * securityOrigin,guint64 quota)339 void webkit_security_origin_set_web_database_quota(WebKitSecurityOrigin* securityOrigin, guint64 quota)
340 {
341 g_return_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin));
342
343 #if ENABLE(DATABASE)
344 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
345 WebCore::DatabaseTracker::tracker().setQuota(coreOrigin, quota);
346 #endif
347 }
348
349 /**
350 * webkit_security_origin_get_all_web_databases:
351 * @securityOrigin: a #WebKitSecurityOrigin
352 *
353 * Returns a list of all Web Databases in the security origin.
354 *
355 * Returns: (transfer container) (element-type WebKitWebDatabase): a
356 * #GList of databases in the security origin.
357 *
358 * Since: 1.1.14
359 **/
webkit_security_origin_get_all_web_databases(WebKitSecurityOrigin * securityOrigin)360 GList* webkit_security_origin_get_all_web_databases(WebKitSecurityOrigin* securityOrigin)
361 {
362 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
363 GList* databases = NULL;
364
365 #if ENABLE(DATABASE)
366 WebCore::SecurityOrigin* coreOrigin = core(securityOrigin);
367 Vector<WTF::String> databaseNames;
368
369 if (!WebCore::DatabaseTracker::tracker().databaseNamesForOrigin(coreOrigin, databaseNames))
370 return NULL;
371
372 for (unsigned i = 0; i < databaseNames.size(); ++i) {
373 WebKitWebDatabase* database = webkit_security_origin_get_web_database(securityOrigin, databaseNames[i].utf8().data());
374 databases = g_list_append(databases, database);
375 }
376 #endif
377
378 return databases;
379 }
380
webkit_security_origin_get_web_database(WebKitSecurityOrigin * securityOrigin,const gchar * databaseName)381 WebKitWebDatabase* webkit_security_origin_get_web_database(WebKitSecurityOrigin* securityOrigin, const gchar* databaseName)
382 {
383 g_return_val_if_fail(WEBKIT_IS_SECURITY_ORIGIN(securityOrigin), NULL);
384
385 WebKitSecurityOriginPrivate* priv = securityOrigin->priv;
386 GHashTable* databaseHash = priv->webDatabases;
387 WebKitWebDatabase* database = (WebKitWebDatabase*) g_hash_table_lookup(databaseHash, databaseName);
388
389 if (!database) {
390 database = WEBKIT_WEB_DATABASE(g_object_new(WEBKIT_TYPE_WEB_DATABASE,
391 "security-origin", securityOrigin,
392 "name", databaseName,
393 NULL));
394 g_hash_table_insert(databaseHash, g_strdup(databaseName), database);
395 }
396
397 return database;
398 }
399
400 namespace WebKit {
401
core(WebKitSecurityOrigin * securityOrigin)402 WebCore::SecurityOrigin* core(WebKitSecurityOrigin* securityOrigin)
403 {
404 ASSERT(securityOrigin);
405
406 return securityOrigin->priv->coreOrigin.get();
407 }
408
kit(WebCore::SecurityOrigin * coreOrigin)409 WebKitSecurityOrigin* kit(WebCore::SecurityOrigin* coreOrigin)
410 {
411 ASSERT(coreOrigin);
412
413 GHashTable* table = webkit_security_origins();
414 WebKitSecurityOrigin* origin = (WebKitSecurityOrigin*) g_hash_table_lookup(table, coreOrigin);
415
416 if (!origin) {
417 origin = WEBKIT_SECURITY_ORIGIN(g_object_new(WEBKIT_TYPE_SECURITY_ORIGIN, NULL));
418 origin->priv->coreOrigin = coreOrigin;
419 g_hash_table_insert(table, coreOrigin, origin);
420 }
421
422 return origin;
423 }
424
425 }
426