Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/core/main/client/lib/evercookie.js
1154 views
1
//
2
// Copyright (c) 2006-2025 Wade Alcorn - [email protected]
3
// Browser Exploitation Framework (BeEF) - https://beefproject.com
4
// See the file 'doc/COPYING' for copying permission
5
//
6
7
/*
8
* evercookie 0.4 (10/13/2010) -- extremely persistent cookies
9
*
10
* by samy kamkar : [email protected] : http://samy.pl
11
*
12
* this api attempts to produce several types of persistent data
13
* to essentially make a cookie virtually irrevocable from a system
14
*
15
* specifically it uses:
16
* - standard http cookies
17
* - flash cookies (local shared objects)
18
* - silverlight isolated storage
19
* - png generation w/forced cache and html5 canvas pixel reading
20
* - http etags
21
* - http cache
22
* - window.name
23
* - IE userData
24
* - html5 session cookies
25
* - html5 local storage
26
* - html5 global storage
27
* - html5 database storage via sqlite
28
* - css history scanning
29
*
30
* if any cookie is found, it's then reset to all the other locations
31
* for example, if someone deletes all but one type of cookie, once
32
* that cookie is re-discovered, all of the other cookie types get reset
33
*
34
* !!! SOME OF THESE ARE CROSS-ORIGIN COOKIES, THIS MEANS
35
* OTHER SITES WILL BE ABLE TO READ SOME OF THESE COOKIES !!!
36
*
37
* USAGE:
38
39
var ec = new evercookie();
40
41
// set a cookie "id" to "12345"
42
// usage: ec.set(key, value)
43
ec.set("id", "12345");
44
45
// retrieve a cookie called "id" (simply)
46
ec.get("id", function(value) { alert("Cookie value is " + value) });
47
48
// or use a more advanced callback function for getting our cookie
49
// the cookie value is the first param
50
// an object containing the different storage methods
51
// and returned cookie values is the second parameter
52
function getCookie(best_candidate, all_candidates)
53
{
54
alert("The retrieved cookie is: " + best_candidate + "\n" +
55
"You can see what each storage mechanism returned " +
56
"by looping through the all_candidates object.");
57
58
for (var item in all_candidates)
59
document.write("Storage mechanism " + item +
60
" returned " + all_candidates[item] + " votes<br>");
61
}
62
ec.get("id", getCookie);
63
64
// we look for "candidates" based off the number of "cookies" that
65
// come back matching since it's possible for mismatching cookies.
66
// the best candidate is very-very-likely the correct one
67
68
*/
69
70
/* to turn off CSS history knocking, set _ec_history to 0 */
71
var _ec_history = 1; // CSS history knocking or not .. can be network intensive
72
var _ec_tests = 10;//1000;
73
var _ec_debug = 0;
74
75
function _ec_dump(arr, level)
76
{
77
var dumped_text = "";
78
if(!level) level = 0;
79
80
//The padding given at the beginning of the line.
81
var level_padding = "";
82
for(var j=0;j<level+1;j++) level_padding += " ";
83
84
if(typeof(arr) == 'object') { //Array/Hashes/Objects
85
for(var item in arr) {
86
var value = arr[item];
87
88
if(typeof(value) == 'object') { //If it is an array,
89
dumped_text += level_padding + "'" + item + "' ...\n";
90
dumped_text += _ec_dump(value,level+1);
91
} else {
92
dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
93
}
94
}
95
} else { //Stings/Chars/Numbers etc.
96
dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
97
}
98
return dumped_text;
99
}
100
101
function _ec_replace(str, key, value)
102
{
103
if (str.indexOf('&' + key + '=') > -1 || str.indexOf(key + '=') == 0)
104
{
105
// find start
106
var idx = str.indexOf('&' + key + '=');
107
if (idx == -1)
108
idx = str.indexOf(key + '=');
109
110
// find end
111
var end = str.indexOf('&', idx + 1);
112
var newstr;
113
if (end != -1)
114
newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + '&' + key + '=' + value;
115
else
116
newstr = str.substr(0, idx) + '&' + key + '=' + value;
117
118
return newstr;
119
}
120
else
121
return str + '&' + key + '=' + value;
122
}
123
124
125
// necessary for flash to communicate with js...
126
// please implement a better way
127
var _global_lso;
128
function _evercookie_flash_var(cookie)
129
{
130
_global_lso = cookie;
131
132
// remove the flash object now
133
var swf = $('#myswf');
134
if (swf && swf.parentNode)
135
swf.parentNode.removeChild(swf);
136
}
137
138
var evercookie = (function () {
139
this._class = function() {
140
141
var self = this;
142
// private property
143
_baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
144
this._ec = {};
145
var no_color = -1;
146
147
this.get = function(name, cb, dont_reset)
148
{
149
$(document).ready(function() {
150
self._evercookie(name, cb, undefined, undefined, dont_reset);
151
});
152
};
153
154
this.set = function(name, value)
155
{
156
$(document).ready(function() {
157
self._evercookie(name, function() { }, value);
158
});
159
};
160
161
this._evercookie = function(name, cb, value, i, dont_reset)
162
{
163
if (typeof self._evercookie == 'undefined')
164
self = this;
165
166
if (typeof i == 'undefined')
167
i = 0;
168
169
// first run
170
if (i == 0)
171
{
172
self.evercookie_database_storage(name, value);
173
self.evercookie_png(name, value);
174
self.evercookie_etag(name, value);
175
self.evercookie_cache(name, value);
176
self.evercookie_lso(name, value);
177
self.evercookie_silverlight(name, value);
178
179
self._ec.userData = self.evercookie_userdata(name, value);
180
self._ec.cookieData = self.evercookie_cookie(name, value);
181
self._ec.localData = self.evercookie_local_storage(name, value);
182
self._ec.globalData = self.evercookie_global_storage(name, value);
183
self._ec.sessionData = self.evercookie_session_storage(name, value);
184
self._ec.windowData = self.evercookie_window(name, value);
185
186
if (_ec_history)
187
self._ec.historyData = self.evercookie_history(name, value);
188
}
189
190
// when writing data, we need to make sure lso and silverlight object is there
191
if (typeof value != 'undefined')
192
{
193
if (
194
(
195
(typeof _global_lso == 'undefined') ||
196
(typeof _global_isolated == 'undefined')
197
)
198
&& i++ < _ec_tests
199
)
200
setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
201
}
202
203
// when reading data, we need to wait for swf, db, silverlight and png
204
else
205
{
206
if (
207
(
208
// we support local db and haven't read data in yet
209
(window.openDatabase && typeof self._ec.dbData == 'undefined') ||
210
(typeof _global_lso == 'undefined') ||
211
(typeof self._ec.etagData == 'undefined') ||
212
(typeof self._ec.cacheData == 'undefined') ||
213
(document.createElement('canvas').getContext && (typeof self._ec.pngData == 'undefined' || self._ec.pngData == '')) ||
214
(typeof _global_isolated == 'undefined')
215
)
216
&&
217
i++ < _ec_tests
218
)
219
{
220
setTimeout(function() { self._evercookie(name, cb, value, i, dont_reset) }, 300);
221
}
222
223
// we hit our max wait time or got all our data
224
else
225
{
226
// get just the piece of data we need from swf
227
self._ec.lsoData = self.getFromStr(name, _global_lso);
228
_global_lso = undefined;
229
230
// get just the piece of data we need from silverlight
231
self._ec.slData = self.getFromStr(name, _global_isolated);
232
_global_isolated = undefined;
233
234
var tmpec = self._ec;
235
self._ec = {};
236
237
// figure out which is the best candidate
238
var candidates = new Array();
239
var bestnum = 0;
240
var candidate;
241
for (var item in tmpec)
242
{
243
if (typeof tmpec[item] != 'undefined' && typeof tmpec[item] != 'null' && tmpec[item] != '' &&
244
tmpec[item] != 'null' && tmpec[item] != 'undefined' && tmpec[item] != null)
245
{
246
candidates[tmpec[item]] = typeof candidates[tmpec[item]] == 'undefined' ? 1 : candidates[tmpec[item]] + 1;
247
}
248
}
249
250
for (var item in candidates)
251
{
252
if (candidates[item] > bestnum)
253
{
254
bestnum = candidates[item];
255
candidate = item;
256
}
257
}
258
259
// reset cookie everywhere
260
if (typeof dont_reset == "undefined" || dont_reset != 1)
261
self.set(name, candidate);
262
263
if (typeof cb == 'function')
264
cb(candidate, tmpec);
265
}
266
}
267
};
268
269
this.evercookie_window = function(name, value)
270
{
271
try {
272
if (typeof(value) != "undefined")
273
window.name = _ec_replace(window.name, name, value);
274
else
275
return this.getFromStr(name, window.name);
276
} catch(e) { }
277
};
278
279
this.evercookie_userdata = function(name, value)
280
{
281
try {
282
var elm = this.createElem('div', 'userdata_el', 1);
283
elm.style.behavior = "url(#default#userData)";
284
285
if (typeof(value) != "undefined")
286
{
287
elm.setAttribute(name, value);
288
elm.save(name);
289
}
290
else
291
{
292
elm.load(name);
293
return elm.getAttribute(name);
294
}
295
} catch(e) { }
296
};
297
298
this.evercookie_cache = function(name, value)
299
{
300
if (typeof(value) != "undefined")
301
{
302
// make sure we have evercookie session defined first
303
document.cookie = 'evercookie_cache=' + value;
304
305
// evercookie_cache.php handles caching
306
var img = new Image();
307
img.style.visibility = 'hidden';
308
img.style.position = 'absolute';
309
img.src = 'evercookie_cache.php?name=' + name;
310
}
311
else
312
{
313
// interestingly enough, we want to erase our evercookie
314
// http cookie so the php will force a cached response
315
var origvalue = this.getFromStr('evercookie_cache', document.cookie);
316
self._ec.cacheData = undefined;
317
document.cookie = 'evercookie_cache=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
318
319
$.ajax({
320
url: 'evercookie_cache.php?name=' + name,
321
success: function(data) {
322
// put our cookie back
323
document.cookie = 'evercookie_cache=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
324
325
self._ec.cacheData = data;
326
}
327
});
328
}
329
};
330
331
this.evercookie_etag = function(name, value)
332
{
333
if (typeof(value) != "undefined")
334
{
335
// make sure we have evercookie session defined first
336
document.cookie = 'evercookie_etag=' + value;
337
338
// evercookie_etag.php handles etagging
339
var img = new Image();
340
img.style.visibility = 'hidden';
341
img.style.position = 'absolute';
342
img.src = 'evercookie_etag.php?name=' + name;
343
}
344
else
345
{
346
// interestingly enough, we want to erase our evercookie
347
// http cookie so the php will force a cached response
348
var origvalue = this.getFromStr('evercookie_etag', document.cookie);
349
self._ec.etagData = undefined;
350
document.cookie = 'evercookie_etag=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
351
352
$.ajax({
353
url: 'evercookie_etag.php?name=' + name,
354
success: function(data) {
355
// put our cookie back
356
document.cookie = 'evercookie_etag=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
357
358
self._ec.etagData = data;
359
}
360
});
361
}
362
};
363
364
this.evercookie_lso = function(name, value)
365
{
366
var div = document.getElementById('swfcontainer');
367
if (!div)
368
{
369
div = document.createElement("div");
370
div.setAttribute('id', 'swfcontainer');
371
document.body.appendChild(div);
372
}
373
374
var flashvars = {};
375
if (typeof value != 'undefined')
376
flashvars.everdata = name + '=' + value;
377
378
var params = {};
379
params.swliveconnect = "true";
380
var attributes = {};
381
attributes.id = "myswf";
382
attributes.name = "myswf";
383
swfobject.embedSWF("evercookie.swf", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
384
};
385
386
this.evercookie_png = function(name, value)
387
{
388
if (document.createElement('canvas').getContext)
389
{
390
if (typeof(value) != "undefined")
391
{
392
// make sure we have evercookie session defined first
393
document.cookie = 'evercookie_png=' + value;
394
395
// evercookie_png.php handles the hard part of generating the image
396
// based off of the http cookie and returning it cached
397
var img = new Image();
398
img.style.visibility = 'hidden';
399
img.style.position = 'absolute';
400
img.src = 'evercookie_png.php?name=' + name;
401
}
402
else
403
{
404
self._ec.pngData = undefined;
405
var context = document.createElement('canvas');
406
context.style.visibility = 'hidden';
407
context.style.position = 'absolute';
408
context.width = 200;
409
context.height = 1;
410
var ctx = context.getContext('2d');
411
412
// interestingly enough, we want to erase our evercookie
413
// http cookie so the php will force a cached response
414
var origvalue = this.getFromStr('evercookie_png', document.cookie);
415
document.cookie = 'evercookie_png=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
416
417
var img = new Image();
418
img.style.visibility = 'hidden';
419
img.style.position = 'absolute';
420
img.src = 'evercookie_png.php?name=' + name;
421
422
img.onload = function()
423
{
424
// put our cookie back
425
document.cookie = 'evercookie_png=' + origvalue + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
426
427
self._ec.pngData = '';
428
ctx.drawImage(img,0,0);
429
430
// get CanvasPixelArray from given coordinates and dimensions
431
var imgd = ctx.getImageData(0, 0, 200, 1);
432
var pix = imgd.data;
433
434
// loop over each pixel to get the "RGB" values (ignore alpha)
435
for (var i = 0, n = pix.length; i < n; i += 4)
436
{
437
if (pix[i ] == 0) break;
438
self._ec.pngData += String.fromCharCode(pix[i]);
439
if (pix[i+1] == 0) break;
440
self._ec.pngData += String.fromCharCode(pix[i+1]);
441
if (pix[i+2] == 0) break;
442
self._ec.pngData += String.fromCharCode(pix[i+2]);
443
}
444
}
445
}
446
}
447
};
448
449
this.evercookie_local_storage = function(name, value)
450
{
451
try
452
{
453
if (window.localStorage)
454
{
455
if (typeof(value) != "undefined")
456
localStorage.setItem(name, value);
457
else
458
return localStorage.getItem(name);
459
}
460
}
461
catch (e) { }
462
};
463
464
this.evercookie_database_storage = function(name, value)
465
{
466
try
467
{
468
if (window.openDatabase)
469
{
470
var database = window.openDatabase("sqlite_evercookie", "", "evercookie", 1024 * 1024);
471
472
if (typeof(value) != "undefined")
473
database.transaction(function(tx)
474
{
475
tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
476
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
477
"name TEXT NOT NULL, " +
478
"value TEXT NOT NULL, " +
479
"UNIQUE (name)" +
480
")", [], function (tx, rs) { }, function (tx, err) { });
481
482
tx.executeSql("INSERT OR REPLACE INTO cache(name, value) VALUES(?, ?)", [name, value],
483
function (tx, rs) { }, function (tx, err) { })
484
});
485
else
486
{
487
database.transaction(function(tx)
488
{
489
tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
490
function(tx, result1) {
491
if (result1.rows.length >= 1)
492
self._ec.dbData = result1.rows.item(0)['value'];
493
else
494
self._ec.dbData = '';
495
}, function (tx, err) { })
496
});
497
}
498
}
499
} catch(e) { }
500
};
501
502
this.evercookie_session_storage = function(name, value)
503
{
504
try
505
{
506
if (window.sessionStorage)
507
{
508
if (typeof(value) != "undefined")
509
sessionStorage.setItem(name, value);
510
else
511
return sessionStorage.getItem(name);
512
}
513
} catch(e) { }
514
};
515
516
this.evercookie_global_storage = function(name, value)
517
{
518
if (window.globalStorage)
519
{
520
var host = this.getHost();
521
522
try
523
{
524
if (typeof(value) != "undefined")
525
eval("globalStorage[host]." + name + " = value");
526
else
527
return eval("globalStorage[host]." + name);
528
} catch(e) { }
529
}
530
};
531
this.evercookie_silverlight = function(name, value) {
532
/*
533
* Create silverlight embed
534
*
535
* Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
536
* is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
537
*/
538
var source = "evercookie.xap";
539
var minver = "4.0.50401.0";
540
541
var initParam = "";
542
if(typeof(value) != "undefined")
543
initParam = '<param name="initParams" value="'+name+'='+value+'" />';
544
545
var html =
546
'<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
547
initParam +
548
'<param name="source" value="'+source+'"/>' +
549
'<param name="onLoad" value="onSilverlightLoad"/>' +
550
'<param name="onError" value="onSilverlightError"/>' +
551
'<param name="background" value="Transparent"/>' +
552
'<param name="windowless" value="true"/>' +
553
'<param name="minRuntimeVersion" value="'+minver+'"/>' +
554
'<param name="autoUpgrade" value="true"/>' +
555
'<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v='+minver+'" style="text-decoration:none">' +
556
'<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>' +
557
'</a>' +
558
'</object>';
559
document.body.innerHTML+=html;
560
};
561
562
// public method for encoding
563
this.encode = function (input) {
564
var output = "";
565
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
566
var i = 0;
567
568
input = this._utf8_encode(input);
569
570
while (i < input.length) {
571
572
chr1 = input.charCodeAt(i++);
573
chr2 = input.charCodeAt(i++);
574
chr3 = input.charCodeAt(i++);
575
576
enc1 = chr1 >> 2;
577
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
578
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
579
enc4 = chr3 & 63;
580
581
if (isNaN(chr2)) {
582
enc3 = enc4 = 64;
583
} else if (isNaN(chr3)) {
584
enc4 = 64;
585
}
586
587
output = output +
588
_baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
589
_baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
590
591
}
592
593
return output;
594
};
595
596
// public method for decoding
597
this.decode = function (input) {
598
var output = "";
599
var chr1, chr2, chr3;
600
var enc1, enc2, enc3, enc4;
601
var i = 0;
602
603
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
604
605
while (i < input.length) {
606
enc1 = _baseKeyStr.indexOf(input.charAt(i++));
607
enc2 = _baseKeyStr.indexOf(input.charAt(i++));
608
enc3 = _baseKeyStr.indexOf(input.charAt(i++));
609
enc4 = _baseKeyStr.indexOf(input.charAt(i++));
610
611
chr1 = (enc1 << 2) | (enc2 >> 4);
612
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
613
chr3 = ((enc3 & 3) << 6) | enc4;
614
615
output = output + String.fromCharCode(chr1);
616
617
if (enc3 != 64) {
618
output = output + String.fromCharCode(chr2);
619
}
620
if (enc4 != 64) {
621
output = output + String.fromCharCode(chr3);
622
}
623
624
}
625
626
output = this._utf8_decode(output);
627
628
return output;
629
630
};
631
632
// private method for UTF-8 encoding
633
this._utf8_encode = function (string) {
634
string = string.replace(/\r\n/g,"\n");
635
var utftext = "";
636
637
for (var n = 0; n < string.length; n++) {
638
639
var c = string.charCodeAt(n);
640
641
if (c < 128) {
642
utftext += String.fromCharCode(c);
643
}
644
else if((c > 127) && (c < 2048)) {
645
utftext += String.fromCharCode((c >> 6) | 192);
646
utftext += String.fromCharCode((c & 63) | 128);
647
}
648
else {
649
utftext += String.fromCharCode((c >> 12) | 224);
650
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
651
utftext += String.fromCharCode((c & 63) | 128);
652
}
653
654
}
655
656
return utftext;
657
};
658
659
// private method for UTF-8 decoding
660
this._utf8_decode = function (utftext) {
661
var string = "";
662
var i = 0;
663
var c = c1 = c2 = 0;
664
665
while ( i < utftext.length ) {
666
667
c = utftext.charCodeAt(i);
668
669
if (c < 128) {
670
string += String.fromCharCode(c);
671
i++;
672
}
673
else if((c > 191) && (c < 224)) {
674
c2 = utftext.charCodeAt(i+1);
675
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
676
i += 2;
677
}
678
else {
679
c2 = utftext.charCodeAt(i+1);
680
c3 = utftext.charCodeAt(i+2);
681
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
682
i += 3;
683
}
684
685
}
686
687
return string;
688
};
689
690
// this is crazy but it's 4am in dublin and i thought this would be hilarious
691
// blame the guinness
692
this.evercookie_history = function(name, value)
693
{
694
// - is special
695
var baseStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";
696
var baseElems = baseStr.split("");
697
698
// sorry google.
699
var url = 'http://www.google.com/evercookie/cache/' + this.getHost() + '/' + name;
700
701
if (typeof(value) != "undefined")
702
{
703
// don't reset this if we already have it set once
704
// too much data and you can't clear previous values
705
if (this.hasVisited(url))
706
return;
707
708
this.createIframe(url, 'if');
709
url = url + '/';
710
711
var base = this.encode(value).split("");
712
for (var i = 0; i < base.length; i++)
713
{
714
url = url + base[i];
715
this.createIframe(url, 'if' + i);
716
}
717
718
// - signifies the end of our data
719
url = url + '-';
720
this.createIframe(url, 'if_');
721
}
722
else
723
{
724
// omg you got csspwn3d
725
if (this.hasVisited(url))
726
{
727
url = url + '/';
728
729
var letter = "";
730
var val = "";
731
var found = 1;
732
while (letter != '-' && found == 1)
733
{
734
found = 0;
735
for (var i = 0; i < baseElems.length; i++)
736
{
737
if (this.hasVisited(url + baseElems[i]))
738
{
739
letter = baseElems[i];
740
if (letter != '-')
741
val = val + letter;
742
url = url + letter;
743
found = 1;
744
break;
745
}
746
}
747
}
748
749
// lolz
750
return this.decode(val);
751
}
752
}
753
};
754
755
this.createElem = function(type, name, append)
756
{
757
var el;
758
if (typeof name != 'undefined' && document.getElementById(name))
759
el = document.getElementById(name);
760
else
761
el = document.createElement(type);
762
el.style.visibility = 'hidden';
763
el.style.position = 'absolute';
764
765
if (name)
766
el.setAttribute('id', name);
767
768
if (append)
769
document.body.appendChild(el);
770
771
return el;
772
};
773
774
this.createIframe = function(url, name)
775
{
776
var el = this.createElem('iframe', name, 1);
777
el.setAttribute('src', url);
778
return el;
779
};
780
781
// wait for our swfobject to appear (swfobject.js to load)
782
this.waitForSwf = function(i)
783
{
784
if (typeof i == 'undefined')
785
i = 0;
786
else
787
i++;
788
789
// wait for ~2 seconds for swfobject to appear
790
if (i < _ec_tests && typeof swfobject == 'undefined')
791
setTimeout(function() { waitForSwf(i) }, 300);
792
};
793
794
this.evercookie_cookie = function(name, value)
795
{
796
try{
797
if (typeof(value) != "undefined")
798
{
799
// expire the cookie first
800
document.cookie = name + '=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/';
801
document.cookie = name + '=' + value + '; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/';
802
}
803
else
804
return this.getFromStr(name, document.cookie);
805
}catch(e){
806
// the hooked origin is using HttpOnly, so we must set the hook ID in a different way.
807
// evercookie_userdata and evercookie_window will be used in this case.
808
}
809
};
810
811
// get value from param-like string (eg, "x=y&name=VALUE")
812
this.getFromStr = function(name, text)
813
{
814
if (typeof text != 'string')
815
return;
816
817
var nameEQ = name + "=";
818
var ca = text.split(/[;&]/);
819
for (var i = 0; i < ca.length; i++)
820
{
821
var c = ca[i];
822
while (c.charAt(0) == ' ')
823
c = c.substring(1, c.length);
824
if (c.indexOf(nameEQ) == 0)
825
return c.substring(nameEQ.length, c.length);
826
}
827
};
828
829
this.getHost = function()
830
{
831
var domain = document.location.host;
832
if (domain.indexOf('www.') == 0)
833
domain = domain.replace('www.', '');
834
return domain;
835
};
836
837
this.toHex = function(str)
838
{
839
var r = "";
840
var e = str.length;
841
var c = 0;
842
var h;
843
while (c < e)
844
{
845
h = str.charCodeAt(c++).toString(16);
846
while (h.length < 2)
847
h = "0" + h;
848
r += h;
849
}
850
return r;
851
};
852
853
this.fromHex = function(str)
854
{
855
var r = "";
856
var e = str.length;
857
var s;
858
while (e >= 0)
859
{
860
s = e - 2;
861
r = String.fromCharCode("0x" + str.substring(s, e)) + r;
862
e = s;
863
}
864
return r;
865
};
866
867
/*
868
* css history knocker (determine what sites your visitors have been to)
869
*
870
* originally by Jeremiah Grossman
871
* http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
872
*
873
* ported to additional browsers by Samy Kamkar
874
*
875
* compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
876
*
877
* - [email protected]
878
*/
879
880
881
this.hasVisited = function(url)
882
{
883
if (this.no_color == -1)
884
{
885
var no_style = this._getRGB("http://samy-was-here-this-should-never-be-visited.com", -1);
886
if (no_style == -1)
887
this.no_color =
888
this._getRGB("http://samy-was-here-"+Math.floor(Math.random()*9999999)+"rand.com");
889
}
890
891
// did we give full url?
892
if (url.indexOf('https:') == 0 || url.indexOf('http:') == 0)
893
return this._testURL(url, this.no_color);
894
895
// if not, just test a few diff types if (exact)
896
return this._testURL("http://" + url, this.no_color) ||
897
this._testURL("https://" + url, this.no_color) ||
898
this._testURL("http://www." + url, this.no_color) ||
899
this._testURL("https://www." + url, this.no_color);
900
};
901
902
/* create our anchor tag */
903
var _link = this.createElem('a', '_ec_rgb_link');
904
905
/* for monitoring */
906
var created_style;
907
908
/* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
909
var _cssText = '#_ec_rgb_link:visited{display:none;color:#FF0000}';
910
911
/* Methods for IE6, IE7, FF, Opera, and Safari */
912
try {
913
created_style = 1;
914
var style = document.createElement('style');
915
if (style.styleSheet)
916
style.styleSheet.innerHTML = _cssText;
917
else if (style.innerHTML)
918
style.innerHTML = _cssText;
919
else
920
{
921
var cssT = document.createTextNode(_cssText);
922
style.appendChild(cssT);
923
}
924
} catch (e) {
925
created_style = 0;
926
}
927
928
/* if test_color, return -1 if we can't set a style */
929
this._getRGB = function (u, test_color) {
930
if (test_color && created_style == 0)
931
return -1;
932
933
/* create the new anchor tag with the appropriate URL information */
934
_link.href = u;
935
_link.innerHTML = u;
936
// not sure why, but the next two appendChilds always have to happen vs just once
937
document.body.appendChild(style);
938
document.body.appendChild(_link);
939
940
/* add the link to the DOM and save the visible computed color */
941
var color;
942
if (document.defaultView)
943
color = document.defaultView.getComputedStyle(_link, null).getPropertyValue('color');
944
else
945
color = _link.currentStyle['color'];
946
947
return color;
948
};
949
950
this._testURL = function(url, no_color){
951
var color = this._getRGB(url);
952
953
/* check to see if the link has been visited if the computed color is red */
954
if (color == "rgb(255, 0, 0)" || color == "#ff0000")
955
return 1;
956
957
/* if our style trick didn't work, just compare default style colors */
958
else if (no_color && color != no_color)
959
return 1;
960
961
/* not found */
962
return 0;
963
}
964
965
};
966
967
return _class;
968
})();
969
970
971
/*
972
* Again, ugly workaround....same problem as flash.
973
*/
974
var _global_isolated;
975
function onSilverlightLoad(sender, args) {
976
var control = sender.getHost();
977
_global_isolated = control.Content.App.getIsolatedStorage();
978
}
979
/*
980
function onSilverlightError(sender, args) {
981
_global_isolated = "";
982
983
}*/
984
function onSilverlightError(sender, args) {
985
_global_isolated = "";
986
}
987
988