#!/usr/bin/perl
# Wed Mar 31 18:56:46 CEST 2010 aramosf@gmail.com v0.1
# 
# Limitaciones:
# - Lento
# - Requiere que la persona que bloquea sea amigo de un amigo
# - La contraseña va en un parámetro, ojo en máquinas compartidas
# - Usuarios con privacidad activada


use strict;
use warnings;
use LWP::UserAgent;

$| = 1;

if ($#ARGV < 3) { 
 print "uso: $0 <correo1> <contraseña1> <correo2> <contraseña2>\n\n";
 print "http://www.securitybydefault.com\n";
exit 1;
}

my ($mi_user,$mi_pass,$o_user,$o_pass)=($ARGV[0], $ARGV[1], $ARGV[2], $ARGV[3]);
my $debug = $ARGV[4];
my (%ua,$res);

$debug ||= 0;


sub fblogin {
 my $u=$_[0];
 my $p=$_[1];
 my %user;
 # a que asusta el encode?
 $user{"charset_test"}="%E2%82%AC%2C%C2%B4%2C%E2%82%AC%2C%C2%B4%2C%E6%B0%B4%2C%D0%94%2C%D0%84";
 $user{"locale"}="es_LA";
 $user{"non_com_login"}="";
 $user{"email"}="$u";
 $user{"pass"}="$p";
 $user{"lsd"}="xxxxx";
 $ua{$u} = LWP::UserAgent->new;
 # debug
 if ($debug > 3) {
  $ua{$u}->default_header('Accept-Encoding' => scalar HTTP::Message::decodable());
  $ua{$u}->add_handler("request_send",  sub { shift->dump; return });
  $ua{$u}->add_handler("response_done", sub { shift->dump; return });
 }

 push @{ $ua{$u}->requests_redirectable }, 'POST';
 $ua{$u}->cookie_jar({ file => "cookies$u.txt" });
 $ua{$u}->agent('Mozilla/5.0');
 $res = $ua{$u}->get("http://www.facebook.com/");
 $res = $ua{$u}->post("https://login.facebook.com/login.php?login_attempt=1",\%user);
 my $html = $res->content();
 print "$html" if $debug >2;
 $html =~ m|user:(\d+),|; my $id= $1; $html="";
 if (! $id) { print "Algo esta mal con el ID: $id $u:$p\n"; exit 1; }
 print "ID: $id\n" if $debug >0;
 $res = $ua{$u}->get("http://www.facebook.com/ajax/social_graph/dialog/popup.php?id=$id&__a=1&__d=1");
 $html = $res->content();
 print "$html" if $debug >2;
 $html =~ m|post_form_id.*?value=\\"(\w+)\\"|; my $postform = $1; $html="";
 if (! $postform) { print "Algo esta mal con el post_form $postform $u:$p\n"; exit 1; }
 print "Post_Form: $postform\n" if $debug >0;
 return($id,$postform);
}
sub getfriends {
 my $id=$_[0];
 my $postform=$_[1];
 my $u=$_[2];
 $res = $ua{$u}->get("http://www.facebook.com/friends/ajax/friends.php?__a=1&id=$id&flid=&view=everyone&q=&nt=0&nk=0&st=0&ps=350&s=0");
 my $h = $res->content();
 if ($h =~ m/Friends\.refreshStart\(350\)/) {
 $res = $ua{$u}->get("http://www.facebook.com/friends/ajax/friends.php?__a=1&id=$id&flid=&view=everyone&q=&nt=0&nk=0&st=0&ps=350&s=350");
 $h .= $res->content();
 }

 my (@friends,%fr);
 my @html = split '>',$h;
 foreach (@html) { 
  if ($_ =~ m/.*friendClick\(this, event, (\d+)\);\\\"/) {
   if (! $fr{$1}) { $fr{$1}=1; push(@friends,$1); }
  }
 }
 return @friends;
} 


sub getname {
 my $id=$_[0];
 my $u=$_[1];
 $res = $ua{$u}->get("http://www.facebook.com/profile.php?id=$id");
 my $h = $res->content();
 if ($h =~ m/<title>Facebook \| (.*?)<\/title>/) {
  return $1;
# si tiene alias hay que seguir buscando
 } else {
  $h =~ m/window\.location\.replace\("(.*?)"\);.*/;
  my $url = $1;
  $url =~ s/\\//g;
  $res = $ua{$u}->get("$url");
  $h = $res->content();
  if ($h =~ m/<title>Facebook \| (.*?)<\/title>/) {
   return $1; 
  } else { 
    return "error"; 
  }
 }
}
sub checkuser {
 my $id=$_[0];
 my $u=$_[1];
 $res = $ua{$u}->get("http://www.facebook.com/profile.php?id=$id");
 my $h = $res->content();
 if ($h =~ m/window\.location\.replace.*home\.php/) { 
  return 1; 
 } else { return 0; }
 

}

# Comprobación de cuentas
print "- Comprobando accesos: ";
my ($o_id,$o_postform)=&fblogin($o_user,$o_pass);
my ($my_id,$my_postform)=&fblogin($mi_user,$mi_pass);
print "[x].\n";

# Se meten los IDs de MIS amigos en @my_friends
print "- Obteniendo tus amigos ";
my @my_friends = &getfriends($my_id,$my_postform,$mi_user);
if ($debug >0) {
print "Mis amigos:\n"; foreach (@my_friends) { print "$_\n"; }
}
my $total=$#my_friends+1;
print "[x]. Total: ".$total."\n";


# a guardar amigos-de-mis-amigos
print "- Obteniendo los amigos de tus amigos\n";
my %froffr;
my %froffr_n; # numero de amigos por amigo (para calcular despues)
my $froffr_b; # numero de amigos de amigos total
my $c=0;
foreach (@my_friends) {
 print "Friends of: $_:\n" if $debug >0;
  @{$froffr{$_}} =&getfriends($_,$my_postform,$mi_user);
  $froffr_n{$_}=0;
  $c++;
 foreach my $ff (@{$froffr{$_}}) {
  $froffr_n{$_}++;
  $froffr_b++;
  print "\t$ff\n" if $debug >0;
 }
 print ".";
 if ( $c % 10  == 0) { print "$c"; }
 
 print "Num Total de amigos de $_: $froffr_n{$_}\n" if $debug >0; 
}
print "\n-- Obteniendo los amigos de tus amigos [x]. Total: $froffr_b\n";

# cotilleando con el otro usuario
# se almacena en %
print "- Espia obteniendo los amigos de tus amigos\n";
my %o_froffr;
my %o_froffr_n; # numero de amigos parar comparar
my $o_froffr_b; # numero de amigos de amigos total
$c=0;
#($o_id,$o_postform)=&fblogin($o_user,$o_pass);
foreach (@my_friends) {
  print "Friends of: $_ by other:\n" if $debug > 0;
  @{$o_froffr{"$_"}}=&getfriends($_,$o_postform,$o_user);
  $o_froffr_n{$_}=0;
  $c++;
 foreach my $ff (@{$o_froffr{$_}}) {
  $o_froffr_n{$_}++;
  $o_froffr_b++;
  print "\t$ff\n" if $debug >0;
 }
 print ".";
 if ( $c % 10  == 0) { print "$c"; }
 
 if (! $o_froffr_n{$_}) {
  $o_froffr_n{$_}=0; 
 }
  print "Num Total de amigos de $_ (otro): $o_froffr_n{$_} x\n" if $debug >0; 
}
print "\n-- Espia obteniendo los amigos de tus amigos [x]. Total: $o_froffr_b\n";

# comparar el numero de amigos que veo yo de amigos  mis amigos
# con el numero de amigos que ve el espia de mis amigos
# si 0 = usuario con privacidad
my $priv=0;
foreach (@my_friends) {
 if ($froffr_n{$_} < $o_froffr_n{$_}) {
     print "DIFERENCIA $_ - yo veo: $froffr_n{$_} - espia ve: $o_froffr_n{$_}\n" if $debug >0; 
 }
 if ($o_froffr_n{$_} == 0 ) {
     $priv++;
     print "/ Usuario con privacidad activada: $_\n" if $debug > 0;
 }
}
print "- Usuarios con privacidad activada: [x]. Total: $priv\n";

# comparar arrays ( @{$froffr{$u}} y @{$o_froffr{$u}})
# guarda la diferencia en @diff y crea un hash con un array y
# las diferencias y el usuario que las tiene 
my (@diff, @k, %a, %bloq, $name);
foreach my $u (@my_friends) {
 %a=map{$_=>1} @{$froffr{$u}};
 @diff=grep(!defined $a{$_}, @{$o_froffr{$u}});
 foreach (@diff) { push(@{$bloq{$_}},$u); }
}

# conexion a FB con MI usuario para comprobar que no llego (checkuser)
#($my_id,$my_postform)=&fblogin($mi_user,$mi_pass);
#
my (%bloq_friends,@validusers,$b);
foreach my $d (keys %bloq) {
 $bloq_friends{$d} = "";
 if (&checkuser($d,$mi_user)) { 
   push(@validusers,$d); 
   foreach my $u (@{$bloq{$d}}) {
    print "Te bloquea $d: visto por $u\n" if $debug >0; 
    $b=&getname($u,$mi_user);
    $bloq_friends{$d} .= "$b, "
   }
 }
}

# Imprimir resultados y matchear ID->Name
#($o_id,$o_postform)=&fblogin($o_user,$o_pass);
foreach my $d (@validusers) {
  $bloq_friends{$d} =~ s/..$//g;
  $name=&getname($d,$o_user);
  print "+ Usuario que te bloquea: $name ($d) amigo de: $bloq_friends{$d}\n";
}




