# HG changeset patch # User Pascal Bellard # Date 1338305187 -7200 # Node ID 1edf8ba1ba4e997fbe7e90dc0893a5726913188e # Parent 42924af752bc50d30a117c7ea457873a217a632d move zerobin from undigest diff -r 42924af752bc -r 1edf8ba1ba4e zerobin/receipt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zerobin/receipt Tue May 29 17:26:27 2012 +0200 @@ -0,0 +1,67 @@ +# SliTaz package receipt. + +PACKAGE="zerobin" +VERSION="0.15_alpha" +CATEGORY="network" +SHORT_DESC="Online pastebin where the server has zero knowledge of pasted data." +MAINTAINER="pascal.bellard@slitaz.org" +TARBALL="${PACKAGE}_$VERSION.zip" +WEB_SITE="http://sebsauvage.net/wiki/doku.php?id=php:zerobin" +WGET_URL="http://sebsauvage.net/files/$TARBALL" + +DEPENDS="php" +SUGGESTED="php-gd" + +# Rules to configure and make the package. +compile_rules() +{ + cd $src + patch -p0 < $stuff/zerobin.u + dos2unix *.txt *.php tpl/*.html lib/*.js lib/*.php lib/*.css +} + +# Rules to gen a SliTaz package suitable for Tazpkg. +genpkg_rules() +{ + mkdir -p $fs/usr/share/zerobin + cp -a $src/* $fs/usr/share/zerobin + chown -R www.www $fs/usr/share/zerobin +} + +# Post and pre install commands +post_install() +{ + # Configure lighttpd server + if [ -f $1/etc/lighttpd/lighttpd.conf ]; then + if ! grep -q /usr/share/zerobin/ $1/etc/lighttpd/lighttpd.conf; then + sed -e 's|.*"/examples/" => "/usr/share/examples/",| "/examples/" => "/usr/share/examples/",\n "/paste/" => "/usr/share/zerobin/",|g' -i $1/etc/lighttpd/lighttpd.conf + if [ -z "$1" ]; then + # Start Web server. + /etc/init.d/lighttpd stop + /etc/init.d/lighttpd start + fi + fi + fi + # Configure apache server + if [ -f $1/etc/apache/httpd.conf ]; then + sed -i 's/lighttpd/apache/' $1/etc/rcS.conf + if [ ! -f $1/etc/apache/conf.d/zerobin ]; then + cat > $1/etc/apache/conf.d/zerobin < + Alias /paste /usr/share/zerobin/ + + + php_value upload_max_filesize 2147483647 + DirectoryIndex index.php + AllowOverride None + Order allow,deny + Allow from all + +EOT + if [ -z "$1" ]; then + # Start Web server. + /etc/init.d/apache restart + fi + fi + fi +} diff -r 42924af752bc -r 1edf8ba1ba4e zerobin/stuff/zerobin.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zerobin/stuff/zerobin.js Tue May 29 17:26:27 2012 +0200 @@ -0,0 +1,216 @@ +/* ZeroBin 0.11 - http://sebsauvage.net/wiki/doku.php?id=php:zerobin */ + +// Compress a message (deflate compression). Returns base64 encoded data. +function compress(message) { return Base64.toBase64(RawDeflate.deflate(Base64.utob(message))); } + +// Decompress a message compressed with compress(). +function decompress(data) { return Base64.btou(RawDeflate.inflate(Base64.fromBase64(data))) } + +/* + Encrypt the message with a random key. + Output: An array with two items: + 'data' (string) : json encoded data to store on server side (containing ciphertext,iv and salt) + 'key' (string: the key (encoded in base64) to be kept on client side. + + Example: + c = randomCipher("Hello, world !"); + document.write("Data for server side: "); + document.write(c.data); + document.write('
Key at client side: '); + document.write(c.key); + Output: + Data for server side: {"iv":"a6ZEUEtK2jNcGsdIsKKj9g","salt":"/7wDPD4JRik","ct":"qdD97HChan6B9OShjfBDmQKbw8/1ehdO1u/KbC/r85c"} + Key at client side: VjxODsAaUwar6LJOcc0yaknnUr5XHeg/m7Sn5UF+TC4= +*/ +function randomCipher(message) +{ + var randomkey = (window.location.hash.length > 2) ? + // force key + window.location.hash.substring(1) : + // Generate a random 256 bits key, encoded in base64: + sjcl.codec.base64.fromBits(sjcl.random.randomWords(8,0),0); + var data = sjcl.encrypt(sjcl.misc.pbkdf2(randomkey,0),compress(message)); + return {'data':data,'key':randomkey}; +} + +// Decrypts data encrypted with randomCipher() +function randomDecipher(key,data) +{ + return decompress(sjcl.decrypt(sjcl.misc.pbkdf2(key,0),data)); +} + +// Returns the current script location (without search or hash part of the URL). +// eg. http://server.com/zero/?aaaa#bbbb --> http://server.com/zero/ +function scriptLocation() +{ + return window.location.href.substring(0,window.location.href.length + -window.location.search.length -window.location.hash.length); +} + +// Show decrypted text in the display area +function displayCleartext(text) +{ + if ($('#oldienotice').is(":visible")) // For IE<10. + { + // IE<10 do not support white-space:pre-wrap; so we have to do this BIG UGLY STINKING THING. + $('#cleartext').text(text.replace(/\n/ig,'{BIG_UGLY_STINKING_THING__OH_GOD_I_HATE_IE}')); + $('#cleartext').html($('#cleartext').text().replace(/{BIG_UGLY_STINKING_THING__OH_GOD_I_HATE_IE}/ig,"\r\n
")); + } + else // for other (sane) browsers: + { + $('#cleartext').text(text); + } + urls2links($('#cleartext')); // Convert URLs to clickable links. +} + +// Send data to server +function send_data() +{ + if ($('#message').val().length==0) return; // Do not send if no data. + showStatus('Sending data...'); + var c=randomCipher($('#message').val()); + $.post(scriptLocation(), { data:c.data,expire:$('select#pasteExpiration').val() },'json' ) + .error( function() { showError('Data could not be sent.'); } ) + .success(function(data) + { + var jdata = jQuery.parseJSON(data); + if (data.status==0) + { + stateExistingPaste(); + var url=scriptLocation()+"?"+data.id+'#'+c.key; + showStatus(''); + $('#pastelink').html('Your paste is '+url+''); + $('#pastelink').append('  '); + $('#pastelink').show(); + displayCleartext($('#message').val()); + } + else if (data.status==1) + { + showError('Could not create paste: '+data.message); + } + else + { + showError('Could not create paste.'); + } + } + ); +} + +// Put the screen in "New paste" mode. +function stateNewPaste() +{ + sjcl.random.startCollectors(); + $('#sendbutton').show(); + $('#clonebutton').hide(); + $('#expiration').show(); + $('#language').hide(); // $('#language').show(); + $('#password').hide(); //$('#password').show(); + $('#newbutton').show(); + $('#pastelink').hide(); + $('#message').text(''); + $('#message').show(); + $('#cleartext').hide(); + $('#hashes').hide(); + $('#message').focus(); +} + +// Put the screen in "Existing paste" mode. +function stateExistingPaste() +{ + sjcl.random.startCollectors(); + $('#sendbutton').hide(); + if (!$('#oldienotice').is(":visible")) $('#clonebutton').show(); // Not "clone" for IE<10. + $('#expiration').hide(); + $('#language').hide(); + $('#password').hide(); + $('#newbutton').show(); + $('#pastelink').hide(); + $('#message').hide(); + $('#cleartext').show(); + $('#hashes').show(); +} + +// Clone the current paste. +function clonePaste() +{ + stateNewPaste(); + showStatus(''); + $('#message').text($('#cleartext').text()); +} + +// Create a new paste. +function newPaste() +{ + stateNewPaste(); + showStatus(''); + $('#message').text(''); +} + +// Display an error message +function showError(message) +{ + $('#status').addClass('errorMessage').text(message); +} + +// Display status +function showStatus(message) +{ + $('#status').removeClass('errorMessage'); + if (!message) { $('#status').html(' '); return; } + if (message=='') { $('#status').html(' '); return; } + $('#status').text(message); +} + +// Generate link to URL shortener. +function shortenUrl(url) +{ + return 'http://snipurl.com/site/snip?link='+encodeURIComponent(url); +} + +// Convert URLs to clickable links. +// Input: element : a jQuery DOM element. +// Example URLs to handle: +// magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7 +// http://localhost:8800/zero/?6f09182b8ea51997#WtLEUO5Epj9UHAV9JFs+6pUQZp13TuspAUjnF+iM+dM= +// http://user:password@localhost:8800/zero/?6f09182b8ea51997#WtLEUO5Epj9UHAV9JFs+6pUQZp13TuspAUjnF+iM+dM= +// FIXME: add ppa & apt links. +function urls2links(element) +{ + var re = /((http|https|ftp):\/\/[\w?=&.\/-;#@~%+-]+(?![\w\s?&.\/;#~%"=-]*>))/ig; + element.html(element.html().replace(re,'$1')); + var re = /((magnet):[\w?=&.\/-;#@~%+-]+)/ig; + element.html(element.html().replace(re,'$1')); +} + +$(document).ready(function() { + if ($('#cipherdata').text().length>1) // Display an existing paste + { + if (window.location.hash.length==0) // Missing decryption key in URL ? + { + showError('Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector which strips part of the URL ?)'); + return; + } + var data = $('#cipherdata').text(); + try { + // Get key and decrypt data + var key = window.location.hash.substring(1); + // Strip &utm_source=... parameters added after the anchor by some stupid web 2.0 services. + // We simply strip everything after & + i = key.indexOf('&'); if (i>-1) { key = key.substring(0,i); } + if (key.charAt(key.length-1)!=='=') key+='='; // Add trailing = if missing. + var cleartext = randomDecipher(key,data); + stateExistingPaste(); // Show proper elements on screen. + displayCleartext(cleartext); + } catch(err) { + showError('Could not decrypt data (Wrong key ?)'); + } + } + else if ($('#errormessage').text().length>1) // Display error message from php code. + { + showError($('#errormessage').text()); + } + else // Create a new paste. + { + newPaste(); + } +}); diff -r 42924af752bc -r 1edf8ba1ba4e zerobin/stuff/zerobin.u --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zerobin/stuff/zerobin.u Tue May 29 17:26:27 2012 +0200 @@ -0,0 +1,15 @@ +--- lib/zerobin.js ++++ lib/zerobin.js +@@ -180,7 +180,11 @@ + { + if ($('textarea#message').val().length==0) return; // Do not send if no data. + showStatus('Sending paste...',spin=true); +- var randomkey = sjcl.codec.base64.fromBits(sjcl.random.randomWords(8,0),0); ++ var randomkey = (window.location.hash.length > 2) ? ++ // force key ++ window.location.hash.substring(1) : ++ // Generate a random 256 bits key, encoded in base64: ++ sjcl.codec.base64.fromBits(sjcl.random.randomWords(8,0),0); + var cipherdata = zeroCipher(randomkey,$('textarea#message').val()); + var data_to_send = { data:cipherdata, + expire:$('select#pasteExpiration').val(),