#################################################### #################################################### # SAMESSENGER # # by Mark Bradshaw # # email: mark@networksimplicity.com # # # # SAMessenger will accept command line alerts that # # are sent through the MSN Messenger network. # # # # To use this you'll probably need to use "ppm" to # # install Digest::MD5. # #################################################### #################################################### use IO::Select; use IO::Socket; use Digest::MD5; ##################################################### # Put in the username and password SAMessenger should # connect with. Why hardcode this rather than get it # from the command line? Because this is meant to be # used in a script and it doesn't change (for me). # # NOTE: If the username has an @ symbol you should # precede the @ with a backslash (\). $username="msn_username_here"; $password="msn_password_here"; $debug = 0; $ctx = Digest::MD5->new; if ( $ARGV[0] ne "" ) { $handle = $ARGV[0]; } else { print "What handle should the alert go to?\n> "; $handle = ; chop ($handle); } $num_params = @ARGV; if ( $ARGV[1] ne "" ) { for ( $i=1; $i<$num_params; $i++ ) { $message = "$message $ARGV[$i]"; } } else { print "Message?\n> "; $message = ; chop ($message); } print "\nAttempting to connect...\n"; $address = "64.4.13.206"; $port = "1863"; $check_remote = new IO::Select(); initConn(); ############# # Begin login. sendLine1("VER $out_conn_num MSNP6 MSNP5 MSNP4 CVR0"); sendLine1("INF $out_conn_num"); sendLine1("USR $out_conn_num MD5 I $username"); # If the MSN server is busy (or something) it'll ask # you to move to another server. This handles the # move(s). while ( $line =~ /.*NS ([\d\.]+):(\d+).*/ ) { $address = $1; $port = $2; print "Transfering to a new server: $address:$port.\n"; initConn(); sendLine1("VER $out_conn_num MSNP6 MSNP5 MSNP4 CVR0"); sendLine1("INF $out_conn_num"); sendLine1("USR $out_conn_num MD5 I $username"); } if ( $line =~ /USR \d+ MD5 S ([\d\.]*).*/ ) { $hash=$1; } $ctx->add($hash); $ctx->add($password); $digest = $ctx->hexdigest; sendLine1("USR $out_conn_num MD5 S $digest"); while ( $line !~ /$\n/ ) { readLine1(); } ################# # Login complete. print "Connected!\n"; sendLine1("SYN $out_conn_num 1"); sendLine1("CHG $out_conn_num NLN"); sendLine1("XFR $out_conn_num SB"); while ( $line !~ /XFR.*/ ) { readLine1(); } if ( $line =~ /XFR \d+ SB (\d+\.\d+\.\d+\.\d+):(\d+) CKI ([\d\.]*).*/ ) { $sbip=$1; $sbport=$2; $sbchallenge=$3; } if ( $debug ) { print "1=$sbip, 2=$sbport, 3=$sbchallenge\n"; } $remote2 = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $sbip, PeerPort => $sbport, ) or die "Can't connect to SB"; $check_remote->add($remote2); $out_conn_num2=1; sendLine2("USR $out_conn_num2 $username $sbchallenge"); sendLine2("CAL $out_conn_num2 $handle"); while ( $line !~ /JOI.*/ ) { readLine2(); } sendMSNMsg($message); print "Message sent.\n"; ################################ ################################ ################################ sub initConn { $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $address, PeerPort => $port, ) or die "Can't connect"; $check_remote->add($remote); $out_conn_num=0; $in_conn_num=0; } sub sendLine1 { my($message) = @_; if ( $debug ) { print "$message\n"; } print $remote "$message\r\n"; readLine1(); $out_conn_num++; } sub sendLine2 { my($message) = @_; if ( $debug ) { print "$message\n"; } print $remote2 "$message\r\n"; readLine2(); $out_conn_num2++; } sub readLine1 { if ( $debug ) { print "Control - "; } $line = <$remote>; if ( $line eq "" ) { print "Connection dropped.\n"; print "The user $username can't login. Did you specify the right username"; print " and password in the SAMessenger source?\n"; exit; } if ( $debug ) { print "$line"; } } sub readLine2 { if ( $debug ) { print "SB - "; } $line = <$remote2>; if ( $line eq "" ) { print "SB Connection dropped.\n"; exit; } if ( $debug ) { print "$line"; } } sub sendMSNMsg { my($message) = @_; $line = "MIME-Version: 1.0\r\n"; $line2 = "Content-Type: text/plain; charset=UTF-8\r\n"; $line3 = "X-MMS-IM-Format: FN=MS\%20Shell\%20Dlg; EF=; CO=0; CS=0; PF=0\r\n\r\n"; $line = "$line$line2$line3$message"; $length=length($line); if ( $debug ) { print "MSG $out_conn_num2 N $length\r\n$line\n"; } print $remote2 "MSG $out_conn_num2 N $length\r\n$line"; $out_conn_num2++; }