Search My Blog

ruby (4) web (4) ruby on rails (3) security (3) GPG (2) OpenPGP (2) RFC (2) linux (2) rails (2) shell (2) sysadmin (2) Exchange (1) GIT. (1) IMAP (1) RCS (1) SSH (1) SVN (1) bundle (1) cURL (1) command line (1) crack (1) css (1) developer (1) email (1) fail (1) hack (1) http (1) mac (1) network (1) password (1) regular expression (1) script (1) subversion (1) terminal (1) textmate (1) tip (1) vim (1)

Wednesday, February 15, 2012

What is GnuPG and how to create your GPG primary key and subkeys



Daniel-san, must talk. Walk on road, hm? Walk left side, safe. Walk right side, safe. Walk middle, sooner or later, get squish just like grape. Here, karate, same thing. Either you karate do "yes", or karate do "no". You karate do "guess so", get squish just like grape. Understand?
- Mr Kesuke Miyagi


For GPG the same holds true. It's never a good idea to entrust your safety to a stranger.
If you are starting with GPG you may be frightened by the lack of a short, practical documentation about how to create your keys and how to best use them. Unfortunately GPG seems to be a niche topic for insider people, I've been very frustrated learning how do certain thing work.
So I'm writing a few number of posts that should help people with little or no knowledge about public key cryptography to gain confidence with the GNU Privacy Guard (GnuPG or GPG) implementation of the PKC paradigma. Current versions of PGP are interoperable with GnuPG and other OpenPGP-compliant systems. GnuPG is a part of the Free Software Foundation's GNU software project, and has received major funding from the German government.


What is Public Key Cryptography (PKC)?

As written in the The GNU Privacy Handbook by the The Free Software Foundation (FSF), Public-key ciphers are based on one-way trapdoor functions. A one-way function is a function that is easy to compute, but the inverse is hard to compute. For example, it is easy to multiply two prime numbers together to get a composite, but it is difficult to factor a composite into its prime components. A one-way trapdoor function is similar, but it has a trapdoor. That is, if some piece of information is known, it becomes easy to compute the inverse. For example, if you have a number made of two prime factors, then knowing one of the factors makes it easy to compute the second. Given a public-key cipher based on prime factorization, the public key contains a composite number made from two large prime factors, and the encryption algorithm uses that composite to encrypt the message. The algorithm to decrypt the message requires knowing the prime factors, so decryption is easy if you have the private key containing one of the factors but extremely difficult if you do not have it.


What is a "key" and what you can do with it?

In public key cryptography, as opposed to symmetic key cryptography, a “key” actually of two parts, you can think about them as the two very large prime numbers used in the one-way trapdoor function described above: a public key, and a secret (or private) key; for this reason it would be more appropriate to refer to a “key pair”.
More about the analogy between a key pair and the prime numbers can be found on the RSA working example on Wikipedia

With a key pair you can mainly do two sort of things on some data: sign & verify, or encrypt & decrypt:
- You use your secret key to digitally sign files, and others use your public key to verify the signature.
- Or, others use your public key to encrypt something, and you use the secret key to decrypt it.

One very special use of a key pair is to sign other people’s public key: doing so, you mean that you trust that key pair as belonging to someone you know in person. The more people sign your public key, the more trustable it is. A group of people that trust each other signing their keys is called a web of trust. A “web of trust” is the cryptography equivalent of “reputation”. This model is opposed to the centralized trust model of a public key infrastructure (PKI), which relies exclusively on a certificate authority (or a hierarchy of such).

As the word suggests, a secret key (and its backup) should be kept out of reach from any other person, whereas the public key should spread all over the world so that others have a mean to verify your authenticity and encrypt files for your eyes only.

Once your primary (master) key has been trusted by many people, properly used and mantained, it becomes one of the best proof of your online identity, so you should store it in a safe and possibly disconnected place.
And here’s where the subkeys come into play.


How to create my GPG key and subkeys

OpenPGP encourages use of multiple subkeys, which are like the normal key pairs, except that they are always listed along with their master key pair.
When you create your own key pair,

$ gpg -v --gen-key
gpg (GnuPG/MacGPG2) 2.0.17; Copyright (C) 2011 Free Software Foundation, Inc.

gpg: keyring `~/.gnupg/secring.gpg' created
gpg: keyring `~/.gnupg/pubring.gpg' created

ALGORITHM:
Please select what kind of key you want:
(1) RSA and RSA (default because it’s now the best choice)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1

KEYSIZE:
What keysize do you want? (2048) 4096

EXPIRATION:
Please specify how long the key should be valid.
0 = key does not expire
= key expires in n days
w = key expires in n weeks
m = key expires in n months
y = key expires in n years
Key is valid for? (0) 0

IDENTITY:
GnuPG needs to construct a user ID to identify your key.
Real name: Claudio Floreani
Email address: a.valid@email.com
Comment: Write here something that will help other people to recognize you

You need a Passphrase to protect your secret key.
gpg: writing public key to `~/.gnupg/pubring.gpg'
gpg: writing secret key to `~/.gnupg/secring.gpg'
gpg: ~/.gnupg/trustdb.gpg: trustdb created
gpg: using PGP trust model
gpg: key 889C36B7 marked as ultimately trusted
public and secret key created and signed.

pub 4096R/889C36B7 2010-10-01 (MASTER KEY, usage: SC, sign and certify)
Key fingerprint = 0ABE C1F7 D52A F468 A483 466A 0F6D 370E 889C 36B7
uid Claudio Floreani (some clues about me)
sub 4096R/E6F9976E 2010-10-01 (DEFAULT SUBKEY, usage: E, encryption)
GnuPG actually builds a signing-only key as the master key (the one marked with “pub” and flagged "Sign" and "Certify"), and creates an encryption subkey automatically (the one marked with “sub” and flagged “Encrypt”).


Revocation certificate: when you should build it and why you should use it?

After your keypair is created you should immediately generate a revocation certificate for the whole key using the command --gen-revoke (note: to revoke a subkey or a signature, use the  subcommands revkey or revsig from --edit-key):

$ gpg --gen-revoke 889C36B7 > revoc_cert/889C36B7_revoc_cert.asc
(this won’t alter your keyring)
You can then import that revocation certificate onto your keyring to revoke the key. Think about the revocation certificate as an insurance that lets you keep ultimate control over your key. Once you decided to get rid of your key you would like to share this revocation certificate, keeping in mind that a revoked public key:
  • can still be used to verify signatures made by you in the past
  • cannot be used to encrypt future messages to you
  • can be used to decrypt messages sent to you in the past (if you still do have access to the secret key)



GPG file types

You may have noticed that the certificate has an .asc extension. That’s because by default this command output a text file.

GnuPG uses two main file types:
- .ASC: ASCII Armored files (MIME: application/pgp-keys): a special text format that GPG (and PGP) use to convert binary data into ASCII text so that is especially suitable for use in email messages.
- .GPG: Binary files (MIME: application/x-pgp-keyring): By default most GPG operations produce this binary files that designed to be used directly by GPG (or PGP).

By default GPG creates its keyring under a hidden folder named .gnupg in the user's home (~/.gnupg), but you can override this specifying a GNUPGHOME environment variable:
$ export GNUPGHOME="/another/path/"
Under this folder, GPG creates these files at the first usage:
secring.gpg - Holds the secret keyring (can be viewed with gpg -k or gpg --list-keys)
pubring.gpg - Holds the public keyring (can be viewed with gpg -K or gpg --list-secret-keys)
trustdb.gpg - It's the trust database. (There is no need to backup this file, it is better to backup the ownertrust values: gpg –export-ownertrust)
random_seed - Is used to preserve the internal random pool
gpg.conf - Default configuration file
In the following post I will describe some basic GPG usage, and take a depth look at subkeys and their capabilities.


Friday, January 27, 2012

How to put any directory under SVN revision control using a self-contained repository

Okay, I've not found this elsewhere so I'm writing a post about how I did it.
The tipical SVN scenario is when you and other people are working on shared files by checking out any number of working copies from a repository,
$ svn checkout http://svn.collab.net/repos/svn/trunk /home/me/src/project4/working_copy3
modifying the files and then committing the changes and let the revision control system manage conflicts and merge the updates.
$ svn commit -m "Corrected number of cheese slices."
In this scenario the best place for the repository is in a dedicated and secured server, it doesn't make any sense to have the repository inside its working copy: you want to feel free to make any kind of disaster and even delete the whole directory because you know you can start all over again by checking out a fresh original copy.

But SVN is so simple and powerful that you can let it track any changes that happens on a directory on your own personal computer, for backup or security purposes (think about /etc) or to study what an application does to the the files; and sometimes it may be convenient to create the repository in the same directory that repository is controlling, so you can always backup and move the directory without worrying to break the relationship between the working copy and the repository.
In my case I had an encrypted volume that I mount and unmount in different computers and I wanted to track the changes on this volume even without a network connection, so it turned out that making a self-contained SVN system was the best choice.

There are some simple initial steps to do this, and once completed you can work on the directory as you do usually with any other working copy. Before proceeding just make sure to make a backup of anything you are touching.


Suppose "/pwd" is the directory you want to put under revision control, and start creating a SVN repository where you want (since it will be moved later, I'll place it under /tmp):
$ svnadmin create /tmp/repo/
then import /pwd in this repository and remove it if successfully imported:
$ svn import /pwd/ file:///tmp/repo/ -m '[/] Start tracking all changes within pwd' && rm -fr /pwd/
Now if you check it out you'll have just put /pwd under revision control:
$ svn checkout file:///tmp/repo/ /pwd/

...but wait! IT'S NOT THAT SIMPLE FOR "LIVE" DIRECTORIES!
If you are working on a "live" directory (such as /etc on a busy system), it's not very safe to simply import and delete it because some files may need to change before you check out. So on a "live" directory we'll do it slightly differently:
$ svnadmin create /tmp/repo/
$ svn import /pwd/ file:///tmp/repo/ -m '[/] Start tracking all changes within pwd'
we'll check out under another temporary path
$ svn checkout file:///tmp/repo/ /tmp/pwd/
and move just the SVN system folders into the "live directory":
$ find /tmp/pwd/ -type d -name ".svn" -exec mv -vi {} /pwd/ \;
NOTE: In a Mac OS environment, use 'ditto' instead of 'mv':
$ cd /tmp/pwd/
$ find . -d -type d -name ".svn" -exec ditto {} /pwd/{} \;
$ cd ~-
Now /pwd is effectively a working copy and you can update the files that changed in the meanwhile, and get rid off the other working copy /tmp/pwd:
$ rm -fr /tmp/pwd/

And here comes the part to move the repository inside the working copy:
Change to /pwd/ and update (only needed if it was a "live" directory)
$ cd /pwd/ && svn update
tell SVN to ignore the folder ".repo" where we will put the repository, and commit.
$ svn propset svn:ignore .repo .
$ svn commit -m '[/] svn propset svn:ignore .repo .'
At this point, instead of just moving the repository in "/pwd/.repo", we make a precautionary step to ensure that if we are working on a "live" directory no changes would be lost when we relocate the repository: first we symlink the repository,
$ ln -s /tmp/repo/ .repo
then we tell what is the new location of the SVN repository
$ svn switch --relocate file:///tmp/repo/ file:///pwd/.repo/
and only after making the switch we effectively move it replacing the symlink all at once
$ rm /pwd/.repo && mv -vf /tmp/repo/ /pwd/.repo/
Now you have a self-contained revision control of the current directory.



If you find this useful please leave a comment ;)

Monday, January 9, 2012

Monkeypatching the Ruby IMAP class to build a client for Exchange email servers not compliant with RFC standards

When trying to use Ruby Class Net::IMAP to automate some searching/arranging/deleting tasks for my office email I came across some Exchange responses that are not strictly compliant with the IMAP standard (currently 4rev1, described in RFC3501)

After loading the standard IMAP class
ruby-1.9.2-p290 :001 > require 'net/imap'
=> true

we can connect to the IMAP server by instantiating an Net::IMAP object that describes the type of connection used (IP address, TCP port and whether we should use SSL to encrypt the communication).
My company uses IMAP over SSL (port 993/tcp) with a 'PLAIN' authentication, so let's start with:
ruby-1.9.2-p290 :002 > imap= Net::IMAP.new( 'outlook.h3g.it', :port=>'imaps', :ssl=>true )
=> #<Net::IMAP:0x0000010109e118 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x0000010109e0c8>, @host="outlook.h3g.it", @port="imaps", @tag_prefix="RUBY", @tagno=0, @parser=#<Net::IMAP::ResponseParser:0x0000010109e028 @str="* OK IMAP4 019 Ready\r\n", @pos=22, @lex_state=:EXPR_BEG, @token=nil, @flag_symbols={}>, @sock=#<OpenSSL::SSL::SSLSocket:0x0000010109d678>, @usessl=true, @responses={}, @tagged_responses={}, @response_handlers=[], @tagged_response_arrival=#<MonitorMixin::ConditionVariable:0x0000010109bb70 @monitor=#<Net::IMAP:0x0000010109e118 ...>, @cond=#<ConditionVariable:0x0000010109bb48 @waiters=[], @waiters_mutex=#<Mutex:0x0000010109baf8>>>, @continuation_request_arrival=#<MonitorMixin::ConditionVariable:0x0000010109bad0 @monitor=#<Net::IMAP:0x0000010109e118 ...>, @cond=#<ConditionVariable:0x0000010109baa8 @waiters=[], @waiters_mutex=#<Mutex:0x0000010109ba58>>>, @idle_done_cond=nil, @logout_command_tag=nil, @debug_output_bol=true, @exception=nil, @greeting=#<struct Net::IMAP::UntaggedResponse name="OK", data=#<struct Net::IMAP::ResponseText code=nil, text="IMAP4 019 Ready">, raw_data="* OK IMAP4 019 Ready\r\n">, @client_thread=#<Thread:0x00000100892c80 run>, @receiver_thread=#<Thread:0x0000010109afb8 run>>

So far so good, but when I introduce myself to the server I receive an error:
ruby-1.9.2-p290 :003 > imap.authenticate( 'PLAIN', my_name, my_password )
Net::IMAP::ResponseParseError: unexpected token CRLF (expected SPACE)
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:3235:in `parse_error'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:3087:in `match'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:2058:in `continue_req'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:2045:in `response'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1973:in `parse'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1124:in `get_response'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1036:in `receive_responses'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1023:in `block in initialize'

It seems that our client is expecting a T_SPACE while server is sending T_CRLF. Interesting to say, Microsoft states that Exchange is "compatible with RFC3501" but also that "(AUTH=PLAIN not supported)" (http://technet.microsoft.com/en-us/library/ff848256.aspx). Why?? It seems to me that once again they are not able to understand a clear (A)BNF specification on a standard RFC:

RFC3501: INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
9. Formal Syntax
response = *(continue-req / response-data) response-done
continue-req = "+" SP (resp-text / base64) CRLF
response-data = "*" SP (resp-cond-state / resp-cond-bye / mailbox-data / message-data / capability-data) CRLF
response-done = response-tagged / response-fatal
response-fatal = "*" SP resp-cond-bye CRLF ; Server closes connection immediately
response-tagged = tag SP resp-cond-state CRLF

RFC clearly says that a SP(ace) is needed after the "+" sign, as correctly defined in the 'continue_req' method:
require 'net/imap'
module Net
class IMAP
class ResponseParser
def continue_req
match(T_PLUS)
match(T_SPACE)
return ContinuationRequest.new(resp_text, @str)
end
end
end
end

however we can try to fix (but I should say 'break') it to suit the Exchange server's needs, deleting the 'match(T_SPACE)' statement:
require 'net/imap'
module Net
class IMAP
class ResponseParser
def continue_req
match(T_PLUS)
return ContinuationRequest.new(resp_text, @str)
end #def continue_req
end #class ResponseParser
end #class IMAP
end #module Net

And then try again:
ruby-1.9.2-p290 :004 > imap.authenticate( 'PLAIN', my_name, my_password )
=> #, raw_data="RUBY0001 OK AUTHENTICATE completed.\r\n">

And now it's ok.
But testing some other IMAP command we soon face another error:
ruby-1.9.2-p290 :005 > imap.noop
=> #, raw_data="RUBY0002 OK NOOP completed.\r\n">

ruby-1.9.2-p290 :006 > imap.status( 'INBOX', 'MESSAGES' )
Net::IMAP::ResponseParseError: unexpected token SPACE (expected CRLF)
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:3235:in `parse_error'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:3087:in `match'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:2051:in `response'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1973:in `parse'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1124:in `get_response'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1036:in `receive_responses'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/imap.rb:1023:in `block in initialize'

Exchange server (sometimes?) adds an extra space before CRLF (again violating the RFC command syntax listed above).
This time we need to change the response method:
require 'net/imap'
module Net
class IMAP
class ResponseParser
def response
token = lookahead
case token.symbol
when T_PLUS
result = continue_req
when T_STAR
result = response_untagged
else
result = response_tagged
end
match(T_CRLF)
match(T_EOF)
return result
end
end
end
end

adding a 'match(T_SPACE) if lookahead.symbol == T_SPACE' just before the CRLF match:
require 'net/imap'
module Net
class IMAP
class ResponseParser
def response
token = lookahead
case token.symbol
when T_PLUS
result = continue_req
when T_STAR
result = response_untagged
else
result = response_tagged
end
match(T_SPACE) if lookahead.symbol == T_SPACE
match(T_CRLF)
match(T_EOF)
return result
end #def response
end #class ResponseParser
end #class IMAP
end #module Net

I've tested this 'monkeypatched' IMAP class long enough to say that fortunately this is all we need to make our client work... does it means that Microsoft is really shifting towards standards-based technology? Bah!

Sunday, December 18, 2011

Power to the terminal command line: download any video by yourself

Those that, like me, don't have a flat rate for the Internet connection, know how careful you have to be watching to an interesting online video, like a video tutorial or a webinar, when the site doesn't allow you to review it offline, because if you have to watch it again later, your time/volume price limit approaches as quickly as larger is the video size.

However, the fact that a website does not allow the download of an online video is not quite true: your browser has to download it indeed, and it even temporarily stores it for the time that it needs it.
If this does surprise you, you might find useful to take a closer look at what does your browser when you click to watch a video online.

The video, like any other resource on the web page, has to be linked in the page your browser is showing: this means that parsing the code of the page it has to find its URL.
But if you look at the page source sometimes you are not able to find it, what you see instead is something like:
<script src="http://cssjs.chesscomfiles.com/js/videoplayer.js">
</script>
<script>
BuildSWFObject(592,'8917218|86291812c0025268a81210a7c89cfbac','modern-benoni-1-the-amanovs-thrilling-battle','videocontainer');
</script>
or
<embed allowscriptaccess="always" flashvars="file=http://www.chess.com/show/ 8917218&amp;autostart=false&amp;config=http://www.chess.com/config.xml" height="180" menu="false" pluginspage="http://www.macromedia.com/go/getflashplayer" quality="high" src="http://www.chess.com/player.swf" type="application/x-shockwave-flash" width="320"></embed>

This means the video location will be revealed dynamically when the video player's script is executed.

Using some tools to debug the browser behaviour, like Safari's Web Inspector, we can easily find the exact GET statement used to retrieve the video because most of the time it is the largest object in the page, so sorting the request by objects size or by loading time it will be the first result:



http://www.chess.com/video/serve-video?file=modern-benoni-1-the-amanovs-thrilling-battle&streamer=lighttpd&token=8917218|86291812c0025268a81210a7c89cfbac&crap=mp4?start=0&id=playerId&client=FLASH%20MAC%2011,1,102,55&version=4.3.132&width=710

Taking a closer look at this GET, we will see that a query is performed using the parameters given in the above script:


file: modern-benoni-1-the-amanovs-thrilling-battle
token: 8917218|86291812c0025268a81210a7c89cfbac

Besides, every GET declares a "User-Agent" and a "Referer Page", used by the server to know the kind of browser and where this request comes from.
If the site needs to know something more about who is making the request, it will expects a cookie, a small piece of text stored by the browser to uniquely identify the current user or browsing session. You can find out this cookie in the Web Inspector by matching the web site hostname:


Now you have all the information needed to ask by yourself the video to the web server, you just need some tool to manually send out this GET: wget or cURL, to name only the best known.

With curl these are the options to set the User-Agent, the Referer and the cookie:

-A/--user-agent
-b/--cookie (The data should be in the format "NAME1=VALUE1; NAME2=VALUE2")
-e/--referer
-o/--output Write output to instead of stdout.

By putting all together we can test if it works by downloading manually the file:

$ curl -e 'http://www.chess.com/video/player/modern-benoni-1-the-amanovs-thrilling-battle' -A 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.52.7 (KHTML, like Gecko) Version/5.1.2 Safari/534.52.7' -o test_GET.mp4 -b'__utmz=1.7324923106.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=1; __utmb=1.3.99.2139100016; __utma=1.721394078.1214124012.1214859116.8217491996.3; meebo-cim-session=3142ff122e11209bb12c; mcim=7281478shfjf8g1ASASGKJgakgaskg88&amp;AgANGJJGAKKhagsjgasgkgkasgkkgahsAFSkgjj73263853930139501915hgn3031nc90000128tnguj%2hjfd9hgh32h88813jkgkgkkgk138; _chartbeat2=98124091hhhfaksn.1849812495199; ki_t=1324118915713%3B1324118915713%3B1324118915713%3B1%3B1; ki_u=ababa666-12de-5121-0241-fef88ccac10a; view_counter=hsahgk3r7881r7v318h13921r8; __qca=P0-841249119-8817214891285; cal=hdasjsfhjhjAJSFJHFAJ28389391239r9vkdjskfjkjfakj34h1jhjGKGKjkj3k12j3rkvjk13jrkvjk1j2kjgkjk21kjg8214781249fa99214899982191248SHHJEJBedbeuEBbeF; tf_login_id=xhejak; PHPSESSID=sakjgjk2383gakj3t98gj1jj11; __utmz=21314121.7381273182.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=56795640; __utmb=21314121.1.10.2138921496; __utma=12144141.521442111.1214148871.8912481811.1142819189.1; __utmxx=72121411.; __utmx=21314121.' 'http://www.chess.com/video/serve-video?file=modern-benoni-1-the-amanovs-thrilling-battle&amp;streamer=lighttpd&amp;token=8917218|86291812c0025268a81210a7c89cfbac&amp;crap=mp4?start=0&amp;id=playerId&amp;client=FLASH%20MAC%2011,1,102,55&amp;version=4.3.132&amp;width=710'

% Total % Received % Xferd  Average Speed   Time    Time     Time  Current
                            Dload  Upload   Total   Spent    Left  Speed
5 22.8M 5 1182k    0     0  35135      0  0:11:20  0:00:34  0:10:46 12231^C

Keep in mind that the cookies and the token used might be useful only within the current browser session, so you can make the previous test only during the current session of the browser with the web site.

Friday, December 2, 2011

A good example of password security fail

Se la sicurezza si vede dal mattino, alla Regione Lombardia sono messi male.

Non sei ancora registrato che già ti mettono in guardia sulle loro competenze:


Buon cielo! Perché mai la mia password non dovrebbe avere due caratteri consecutivi uguali!?
Non staranno davvero dicendo che una password con due caratteri ripetuti è meno sicura delle altre...

Si potrebbe anche lasciare al buon senso stabilire se
"HHZ915ji"
è più indovinabile di
"PAPERINO"
ma almeno rendiamoci conto di quanto sia più facile per un password cracker listare le password valide o forzare la password di un account se queste non possono avere caratteri ripetuti!

Se n sono i caratteri ammissibili nella password, ci sono nk possibili password di lunghezza k; ma ci sono solo n(n-1)(k-1) possibili password senza caratteri consecutivi ripetuti, perché scelto arbitrariamente il primo carattere, devo scegliere il successivo tra gli N-1 caratteri diversi dall'ultimo digitato.

Questo, tradotto in numeri, significa che se le password mediamente sono di 12 caratteri su 37 (lettere, numeri e spazi), sapendo che non ci sono caratteri ripetuti il nostro cracker ha già scartato il 26% delle possibilità! Ha un quarto di possibilità in più di indovinare.
Anche per la minoranza di utenti che usano password con maiuscole e minuscole contemporaneamente le scelte sono comunque ridotte del 16%, oltre un sesto.

In generale su un alfabeto di 63 caratteri (lettere maiuscole e minuscole, numeri e spazi) la percentuale di password senza caratteri ripetuti diminuisce quasi linermente all'aumentare della lunghezza della password secondo questo grafico


Da cui vediamo che
Le password di 7 caratteri non ripetuti sono circa il 90% del totale
Le password di 15 caratteri non ripetuti sono circa l'80% del totale
Le password di 23 caratteri non ripetuti sono circa il 70% del totale
Le password di 32 caratteri non ripetuti sono circa il 60% del totale

Cioè se è vero che all'aumentare della lunghezza della password il cracker impiegherà più tempo, alla Regione Lombardia gli fanno uno sconto sempre più conveniente.

Tempi di saldi natalizi cari cracker! :)


Tuesday, October 25, 2011

Ruby how to get my private and public IP address



Ok,
you've just deployed your newest ruby app on a bunch of servers, and you need that this app knows the IP address of the server where it's running.

I've read some bizarre ways ("Get your local IP address" or "Get your local IP address") to do this, such as opening an UDP socket and inferring it from the interface used to route the packet.
With the Socket class you may do this more easily and also get the benefit of having useful Addrinfo objects and you are able to distinguish easily between public and private interfaces.

First of all:
Socket::ip_address_list
returns the Array of Addrinfo objects with all your interfaces (it deals with both IPv4 and IPv6).

You can then filter them using the standard Enumerable methods select() and detect() along with these Addrinfo methods:
Addrinfo#ipv4?
Addrinfo#ipv6?
Addrinfo#ipv4_private?
Addrinfo#ipv4_loopback?
Addrinfo#ipv4_multicast?
and convert them to string in dotted notation with
Addrinfo#ip_address

as in:

def all_my_ipv4_interfaces
socket.ip_address_list.select{|intf| intf.ipv4?}
end

def my_loopback_ipv4
socket.ip_address_list.detect{|intf| intf.ipv4_loopback?}
end

def my_first_private_ipv4
socket.ip_address_list.detect{|intf| intf.ipv4_private?}
end

def my_first_public_ipv4
socket.ip_address_list.detect{|intf| intf.ipv4? and !intf.ipv4_loopback? and !intf.ipv4_multicast? and !intf.ipv4_private?}
end

all_my_ipv4_interfaces
=> [#<Addrinfo: 127.0.0.1>, #<Addrinfo: 10.212.142.73>, #<Addrinfo: 62.127.4.80>]
my_first_private_ipv4
=> #<Addrinfo: 10.212.142.73>
my_first_public_ipv4.ip_address
=> "62.127.4.80"

Monday, October 10, 2011

Real citizens of a virtual world or virtual citizens of a real world?

I like GPG.
When I started wandering around the Web with my modem about fifteen years ago, the impression was that of being a ghost. There were channels and newsgroups, but behind the words you wrote you could be anyone.
Internet was anonymous.
Time has passed, at the beginning we worried about not being anonymous anymore, then we started not wanting to be that anymore. The Internet has become a virtual extension of our social space.
With the first social networks we thought we could finally have the nationality of this virtual world, but once again we were wrong. We have become virtual citizens of a real world.
What we do on social networks has real world consequences because, in fact, the Internet IS the real world.
Every company has its own site, unique and recognizable. It is difficult for a phishing or cybersquatting not being soon discovered.
But, on the Internet we are less real than the Internet itself. Our virtual identities are ephemeral and too easy to counterfeit and violate. Anyone can pretend to be us, by registering on our behalf, robbing a password, or self attributing pictures, videos, comments or even entire blogs.
And increasingly those who do not know us personally take an idea of us with an online search.
Yet there is a standard protocol (RFC 4880 ), a standard as the email and the Internet itself, which guarantees to each of us a Pretty Good Privacy (PGP).

Each sysadmin knows and uses SSH. And being lazy as all the sysadmins has learned that he can store his public key on remote servers for not even having to type a password to connect.
Indeed, this mechanism should provide better security than passwords, but it's not true because nobody cares about the keys and keeps them safe. On the contrary, during hardware or software changes SSH keys are easily regenerated.

A sysadmin has learned that this message:
means to delete the corresponding line from ~ / .ssh / known_hosts
Almost all sysadmins that I know, at the sight of the message, not even go look for the line and delete the entire portfolio of keys.
And even the very rare cases of people who care about preserving and checking the keys, completely ignore their AUTHENTICITY.

GIT is a distributed code versioning system, and for programmers is a revolution. But lacking the central server repository as a guarantee of the revisions, disappears even the last glimmer of authenticity of the code.
So we put it all on GitHub ... but as long as we rely on the SSH only we are just at the same point.

GPG is not more complex than GIT. Those who keep care of their GPG keys why don't use this portfolio of keys for SSH?
GPG is powerful. Allows you to generate subkeys of the primary key (which should be kept on a disconnected storage and used only when necessary), to choose an expire date, and even to revoke them.
And unlike certificates is as reliable, is free and requires no bureaucratic times.
I have read of the possibility to export a GPG subkey and use it as public key for SSH, but publications on the correct procedure are scarce. Since when it comes to safety it's better not to improvise, I decided to ask for help from someone who was an expert rather than do it by myself. On StackOverflow the question was even banned from a security specialist arguing that it "solicited opinions, debates, discussions, surveys, or flaming".
Maybe no one really cares, because we all want to remain virtual citizens of a virtual world.



Read this post in italian

Thursday, October 6, 2011

Add a shortcut to TextMate to lookup a class or method definition in a tooltip

UPDATED Mar 11 Ott 2011 12:52:36 CEST

I'm Vim user. I love the command mode, and I had fun to dance with those keystroke commands.
However changing OS means viewing things in another perspective, and switching from Linux to Mac OS for me meant choosing an editor that has its roots in the operating system where it runs.
In the case of Mac OS it not only means it should have a suitable GUI, but it should fire up instantly and above all it should behave like a Mac App.
TextMate was the obvious choice. Because behaving like a Mac App means that if you pick a folder in the Finder and drop it in the editor icon, it should straight open it like a Project. And it means that under the guise of a bare and simple application hides a world of possibilities and customization. That world in TextMate is called Bundles.

Let's talk about Bundles with a real case. (TextMate|I) was missing a shortcut to quickly lookup the definition of a class or method name, so I decided to write a TextMate command that shows me the definition in a tooltip for the current word under the caret.
The difficulties I had were merely related to the complexity of this shell scripting. Since I was trying to keep it as simple and efficient I could, I chose to use the standard unix tools: grep find and sed (it ended up that maybe a ruby script would have done it easier :))

All you have to do to use it in your TextMate is to open the Bundle editor (⌃ ⌥ ⌘ B), make a new command under "Ruby", assign a "Key Equivalent" like ⌃ ] and paste the following script in the "Command(s):" windows
#!/bin/bash
SEARCHPATH=$(test -x "$TM_PROJECT_DIRECTORY" && echo "$TM_PROJECT_DIRECTORY" || echo $(dirname "$TM_FILEPATH") )
STARTPATTERN="^([[:space:]]|;)*(def|class)([[:space:]]|;)+$TM_CURRENT_WORD([^A-Za-z0-9_].*)*$"
ENDPATTERN="^([[:space:]]|;)*end([[:space:]]|;)*"
FILESMATCH=$( (egrep -ns "$STARTPATTERN" "$TM_FILEPATH" || egrep -nsR "$STARTPATTERN" --exclude="*.svn*" "$SEARCHPATH") |cut -d: -f-2 )
echo $FILESMATCH # Show on tooltip
echo $FILESMATCH |cut -d: -f1 |xargs -0 basename |pbcopy # Copy on clipboard for later use with cmd+T
find "$TM_FILEPATH" "$SEARCHPATH" -type f -name '*.rb' -exec sed -En "/$STARTPATTERN/,/$ENDPATTERN/p" {} \; |sed -E "/$ENDPATTERN/q"
CODE UPDATED Mar 11 Ott 2011 12:52:36 CEST
Now it also copies the first matching filename to the clipboard, so you can open this file by pressing cmd+T (and then go to the exact line with cmd+L)

Make sure the output is "Show as Tool Tip" like this:

If you've done it correctly, placing the caret on or after any method or class name and pressing ⌃ ] (or whatever key assignment you've made) will search in the current file ($TM_FILEPATH) and then recursively in the project directory ($TM_PROJECT_DIRECTORY) or in the file directory (if file is not in a project), and show a tooltip with:
  1. the name of the file (if different from the one you are editing) and the line where the first definition of the method or class is found
  2. the portion of definition from the declaration to the first "end" found

Although not perfect, it will do its best to avoid commented lines and false matches.
Even if this script was done for ruby, you can use it as a base for other programming languages, just change the -name '*.rb' part of the find command in the extension of your sources, and the keywords def - class - end that matches your method, function or class definitions.

In the very unsual case you are running TextMate not on a Mac OS, or if you want to adapt the script to run in a linux shell, just skip the line to "Copy on clipboard for later use with cmd+T" and remember that to use the Extended Regular Expression in SED you have to use the -r switch instead of -E.

For any explanation, contribution or discussion on the script please leave a comment below, and if you find it useful please leave me a positive feedback! :)

Tuesday, October 4, 2011

My CSS stylesheet for Ruby on Rails syntax highligthing

As my very first post, I would like to share with you the CSS stylesheet I use to format Ruby snippets.
If you need a CSS stylesheet ready to be applied to your html code block, or you simply like my ruby formatting color schema, you can take it!

div.rb-code {
 padding:1em 1em 1em 1em;
 border:0.2em groove #000000;
 font-family:Andale Mono,monospace;
 font-size:1.2em;
 color:#CC9900;
 background-color:#3A3A3A;
 overflow:auto;
 z-index:1;
}
div.rb-block-def {}
div.rb-block-exe {}
div.rb-code div.tab { padding-left:1.4em; }
div.rb-code .attribute { color:#FFFF66; }
div.rb-code .argument { color:#FFFF00; font-style:italic; }
div.rb-code .class-parent { color:#00FF00; }
div.rb-code .class { color:#FF00FF; font-weight:bold; }
div.rb-code .comment { color:#FFFFFF; }
div.rb-code .constant { color:#FF9966; }
div.rb-code .keyword { color:#FF8000; text-decoration:underline; }
div.rb-block-def .method { color:#FF00FF; }
div.rb-code .module { color:#A020F0; font-weight:bold; }
div.rb-code .number { color:#00FFFF; font-weight:bold; }
div.rb-code .regexp { color:#FF0000; }
div.rb-code .string { color:#99CCFF; }
div.rb-code .symbol { color:#CCFF66; }
div.rb-code .var { color:#FFFF66; font-weight:bold; }
div.rb-block-exe .command { color:#99CCFF; font-weight:bold; }
div.rb-block-exe .evaluation { color:#F0F0F0; font-size:0.8em; }
div.rb-block-exe .prompt { color:#CC9900; }

To use it, simply place all your code snippet between <DIV class='rb-code'>...</DIV>, and then wrap inside the appropriate <SPAN>...</SPAN> block the portions you need to highligth.

You can distinguish def blocks and executable blocks placing them inside a <DIV class='rb-block-def'> or a <DIV class='rb-block-exe'>

To ident a block, put it inside another <DIV class='tab'>

Look at the following example:

<DIV class='rb-code'>  
<DIV class='rb-block-def'>
<DIV><SPAN class='keyword'>class</SPAN> <SPAN class='class'>Person</SPAN></DIV>
<DIV class='tab'>
<DIV><SPAN class='keyword'>def</SPAN> <SPAN class='method'>speak_now</SPAN>(<SPAN class='argument'>thought</SPAN>)</DIV>
<DIV class='tab'>
<DIV>puts <SPAN class='var'>thought</SPAN></DIV>
</DIV>
<DIV><SPAN class='keyword'>end</SPAN></DIV>
</DIV>
<DIV><SPAN class='keyword'>end</SPAN></DIV>
</DIV>
</DIV>

it will be shown as:

class Person
def speak_now(thought)
puts thought
end
end