Perl版的飞信运行程序

Perl版的飞信运行程序
飞信免费短信接口: http://sms.api.bz/fetion.php?username=13800138000&password=123456&sendto=13800138000&message=短信内容,号码和密码请自行替换
# !/usr/bin/perl
#
# Open Fetion Perl Version
# By Shikai Chen ( [email protected] )
# Please visit my website http://www.csksoft.net

# USAGE: <this_script> <your_mobile_number> <password> <target_number> <message to send>

# REQUIREMENTS:
# -----------------------------
# PERL interpreter
# Curl
# shell with utf-8 encoding

# Date                 Revision 
#-------------------------------
# June.28th 2009       0.1

# LICENSE GPL
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
#

use  Digest :: MD5 qw(md5 md5_hex);
use   Socket ;

#  Global Config

my   $FETION_USER_AGENT      =   " IIC2.0/PC 2.3.0230 " ;
my   $FETION_DOMAIN_URL      =   " fetion.com.cn " ;
my   $FETION_CONFIG_URL      =   " https://nav.fetion.com.cn/nav/getsystemconfig.aspx " ;
my   $FETION_CONF_REQUEST    =   " <config><user mobile-no=\ " %s \ "  /><client type=\ " PC \ "  version=\ " 2.3 . 0230 \ "  platform=\ " W5 . 1 \ "  /><servers version=\ " 0 \ "  /><service-no version=\ " 12 \ "  /><parameters version=\ " 15 \ "  /><hints version=\ " 13 \ "  /><http-applications version=\ " 14 \ "  /><client-config version=\ " 17 \ "  /></config> " ;
my   $FETION_SSIAPP_POST     =   " mobileno=%s&pwd=%s " ;
my   $FETION_SIPC_LOGIN_P1   =   " <args><device type=\ " PC \ "  version=\ " 6 \ "  client-version=\ " 2.3 . 0230 \ "  /><caps value=\ " simple - im;im - session;temp - group \ "  /><events value=\ " contact;permission; system - message \ "  /><user-info attributes=\ " all \ "  /><presence><basic value=\ " 400 \ "  desc=\ " \ "  /></presence></args> " ;
my   $FETION_SIPC_LOGIN_R1   =   " R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 1 R\r\nL: %s\r\n\r\n " ;
my   $FETION_SIPC_LOGIN_P2   =   " <args><device type=\ " PC \ "  version=\ " 6 \ "  client-version=\ " 2.3 . 0230 \ "  /><caps value=\ " simple - im;im - session;temp - group \ "  /><events value=\ " contact;permission; system - message \ "  /><user-info attributes=\ " all \ "  /><presence><basic value=\ " 400 \ "  desc=\ " \ "  /></presence></args> " ;
my   $FETION_SIPC_LOGIN_R2   =   " R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 2 R\r\nA: Digest response=\ " %s \ " ,cnonce=\ " %s \ " \r\nL: %s\r\n\r\n " ;
my   $FETION_SIPC_SENDSMS    =   " M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: tel:%s\r\nN: SendSMS\r\nL: %s\r\n\r\n " ;
my   $FETION_SIPC_LOGOUT     =   " R %s SIP-C/2.0\r\nF: %s\r\nI: 1 \r\nQ: 3 R\r\nX: 0\r\n\r\n " ;

#  Global Data

my   $FETION_SSI_URL         =   " https://uid.fetion.com.cn/ssiportal/SSIAppSignIn.aspx " ;
my   $FETION_SIPC_ADDRESS    =   " 221.176.31.33:8080 " ;

my   $g_isverbose    =   0 ;
my   $g_fetion_num   =   "" ;
my   $g_mobile_num   =   "" ;
my   $g_passwd       =   "" ;
my   $g_cnonce       =   "" ;
my   $g_nonce        =   "" ;

# TODO: proxy support not included
#
# Functions
# UNUSED
# Generate GUID String

sub  guid
{
  
local ( $randomseed );
  
local ( $hashed_id );

  
$randomseed   =   rand ( 1000 );
  
$hashed_id   =   uc (md5_hex  time () . " $randomseed " );

  
$hashed_id   =   ' { ' . substr ( $hashed_id , 0 , 8 ) . ' - '
                  
. substr ( $hashed_id , 8 , 4 ) . ' - '
                  
. substr ( $hashed_id , 12 , 4 ) . ' - '
                  
. substr ( $hashed_id , 16 , 4 ) . ' - '
                  
. substr ( $hashed_id , 20 , 12 ) . ' } ' ;
}

#  Debug Output
sub  debug_print
{
  
if  (  $g_isverbose   ==   1 )
  {
    
print   @_ [ 0 ] . " \n " ;
  }
}

# ############################################################
## HELP FUNCTIONS

# ~~~~~~~~~~~~~~~~~
# SIPC Socket
# ~~~~~~~~~~~~~~~~~

# Init the sipc socket and connect to the target
#
# sipc_connect( addr, port )

sub  sipc_connect
{
  
local   $dest ;
  
local   $exec_ans   =   - 1 ;
  
$dest   =  sockaddr_in(  @_ [ 1 ] ,  inet_aton(  @_ [ 0 ] ) );
  
if  (  socket ( SIPC_CLIENT ,  AF_INET ,  SOCK_STREAM ,  SOL_TCP))
  {
    
setsockopt ( SIPC_CLIENT ,  SOL_SOCKET ,  SO_SNDTIMEO ,   pack ( ' LL ' ,   15 , 0 ) );
    
setsockopt ( SIPC_CLIENT ,  SOL_SOCKET ,  SO_RCVTIMEO ,   pack ( ' LL ' ,   15 , 0 ) );
    
if  (  connect ( SIPC_CLIENT ,   $dest  ) )
    { 

      
$exec_ans   =   0 ;
    }
    
else
    {
      
close  SIPC_CLIENT;

    }
  }
  
return   $exec_ans ;
}

# Close the sipc socket connection
sub  sipc_close
{
  
close  SIPC_CLIENT;
}

# Read data from the sipc socket
#
# RETURN: the data

sub  sipc_read
{
  
local   $read_buffer ;
  
local   $recv_data ;
  
local   $recv_len ;
  
do  
  {
    
$recv_len   =   sysread (SIPC_CLIENT ,   $recv_data ,   4 );
    
$read_buffer   .=   $recv_data ;
  }
while index ( $read_buffer ,   " \r\n\r\n " ) ==   - 1  );

  
if  (  $read_buffer   =~   / L :  ([ 0 - 9 ] + ) / i )
  {
    
local   $data_len   =  $ 1 ;
    
$recv_len   =   sysread (SIPC_CLIENT ,   $recv_data ,   $data_len );
    
# TODO: the actually received data length is not verified.
     $read_buffer   .=   $recv_data ;
  }

  
return   $read_buffer ;
}

# Write data to the spic socket
#
#spic_write( data )
# RETURN: length of the data been sent

sub  sipc_write
{
  
local   $sent_size ;
  
$sent_size   =   syswrite (SIPC_CLIENT ,   @_ [ 0 ] ,   length ( @_ [ 0 ]));

}

# Send sipc request and receive the response
#sipc_request(request_data)
# RETURN: response data

sub  sipc_request
{
  
& sipc_write(  @_ [ 0 ] );
  
# TODO: check whether the write operation works
  
  
return   & sipc_read();
}

# ###############################
# ~~~~~~~~~~~~~~~~~
# CURL Functions
# ~~~~~~~~~~~~~~~~~

# Post HTTP data via curl
# @url url
# @post data to post
# return HTTP response

# curl_http_post($url, $post = null) 

sub  curl_http_post
{
  
local   $curl_cmd ;
  
local   $curl_response ;
  
$curl_cmd   =   " curl -s -k -m 20 " ;
  
$curl_cmd   .=   "  -A \ " $FETION_USER_AGENT \ "" # set user agent

  
if  (  @_ [ 1 ] ne  ""  )  # postdata
  {
    
$curl_cmd   .=   "  -d \@\- " ;
  }

  
$curl_cmd   =    " echo -n  " . quotemeta ( @_ [ 1 ]) . " | " . $curl_cmd . "  @_[0] " ;
  
$response   =  ` $curl_cmd `;
  
if  ($ ?   !=   0 )
  {
    
$response   =   "" # execute curl failed, clear the response data
  }
  
return   $response # return the response
}

# ##########################################################
# Fetion Procotol handled here

#Retrieve the config XML of the given fetion account
#
#fetion_get_config(mobile_num)
#RETURN: config xml

sub  fetion_get_config
{
  
local   $request_string ;
  
local   $returndata ;

  
$request_string   =   sprintf ( $FETION_CONF_REQUEST ,   @_ [ 0 ]);
  
  
$returndata   =   & curl_http_post( $FETION_CONFIG_URL ,   $request_string );
}

# Retrieve the URL to query SIP
#
#fetion_ssiapp_addr( conf_xml )

sub  fetion_ssiapp_addr
{
  
local   $matched_string ;
  
  
if  (   @_ [ 0 =~   /< ssi - app - sign - in > ([ ^< ] * ) <\/ ssi - app - sign - in >/ i)
  {
    
$matched_string   =  $ 1 ;
  }
else
  {
    
$matched_string   =   "" ;
  }
  
return   $matched_string ;
}

# Retrieve the SIPC login address
#
#fetion_sipc_address( conf_xml )

sub  fetion_sipc_address
{
  
local   $matched_string ;
  
if  (   @_ [ 0 =~   /< sipc - proxy > ([ ^< ] * ) <\/ sipc - proxy >/ i)
  {
    
$matched_string   =  $ 1 ;
  }
else
  {
    
$matched_string   =   "" ;
  }
  
return   $matched_string ;

}

# Pefrom SSIAPP login action
#fetion_ssiapp_login(  ssi_url, mobile_num, passwd )
# RETURN: login return xml

sub  fetion_ssiapp_login
{
  
local   $request_string ;
  
local   $returndata ;

  
$request_string   =   sprintf ( $FETION_SSIAPP_POST ,   @_ [ 1 ] ,   @_ [ 2 ]);
  
  
$returndata   =   & curl_http_post( @_ [ 0 ] ,   $request_string );

}

# Get the fetion account number
#fetion_get_account_num ( ssiapp_login_return_xml)
#

sub  fetion_get_account_num
{
  
local   $matched_string   =    "" ;
  
if  (  @_ [ 0 =~   /< user uri =\ " sip:([0-9]+)\@fetion.com.cn;p=[0-9]+\ " / i )
  {
    
$matched_string   =  $ 1 ;
  }

  
return   $matched_string ;
}

# Generate the disgest info for the secondary SIPC login
sub  fetion_sipc_gen_digest
{
  
$g_cnonce   =   uc (md5_hex  rand ( 1000 ));
  
  
local   $key   =  md5( " $g_fetion_num:$FETION_DOMAIN_URL:$g_passwd " );
  
local   $h1    =   uc (md5_hex(  " $key:$g_nonce:$g_cnonce "  ));
  
local   $h2    =   uc (md5_hex(  " REGISTER:$g_fetion_num "   ));
  
local   $finalans   =   uc (md5_hex(  " $h1:$g_nonce:$h2 "  ));
  
return   $finalans ;
}

# Pefrom SIPC login
#fetion_sip_login() 

sub  fetion_sipc_login
{
  
local   $login_request ;
  
local   $login_response ;
  
if  ( $g_fetion_num  eq  ""
  {
    
return   - 1 ;
  }

  
$login_request   =   sprintf ( $FETION_SIPC_LOGIN_R1 ,   $FETION_DOMAIN_URL ,   $g_fetion_num ,   length ( $FETION_SIPC_LOGIN_P1 ));
  
$login_request   .=   $FETION_SIPC_LOGIN_P1 ;

  debug_print 
" Request#1\n " . $login_request . " \n " ;

  
$login_response   =   & sipc_request(  $login_request  );

  debug_print 
" Response#1\n " . $login_response . " \n " ;

  
if  (  $login_response  eq  ""  )
  {
    
return   - 1 ;
  }

  
if  (  $login_response   =~   / nonce =\ " ([^\ " ]{ 32 }) \ " /i )
  {
    $g_nonce = $1;  
    debug_print 
" g_nonce : " .$g_nonce. " \ n " ;
  }else
  {
    return -2;
  }

  $login_request = sprintf($FETION_SIPC_LOGIN_R2, $FETION_DOMAIN_URL, $g_fetion_num, &fetion_sipc_gen_digest(), $g_cnonce ,length($FETION_SIPC_LOGIN_P2));
  $login_request .= $FETION_SIPC_LOGIN_P2;

  debug_print 
" Request # 2:\n".$login_request."\n";

  
$login_response   =   & sipc_request(  $login_request  );

  debug_print 
" Response#2:\n " . $login_response . " \n " ;
  
if  (  $login_response   =~   / 200  OK /  )
  {
    
print   " Login OK\n " ;
    
return   0 ;
  }

  
return   - 1 ;
}

# Send the required text to the specified mobile
#fetion_sendSMS( target_num, text )
#NOTE: always assumes the text is encoded using UTF-8.

sub  fetion_sendSMS
{
  
local   $sms_request   =   sprintf ( $FETION_SIPC_SENDSMS , $FETION_DOMAIN_URL ,   $g_fetion_num ,   @_ [ 0 ] ,   length ( @_ [ 1 ])); 
  
$sms_request   .=   @_ [ 1 ];

  debug_print 
" SendSMS Request:\n " . $sms_request . " \n " ;
  
local   $sipc_response   =   & sipc_request( $sms_request );
  debug_print 
" SendSMS Response:\n " . $sipc_response . " \n " ;
  
  
if  (  $sipc_response   =~   / Send  SMS OK /  )
  {
    
print   " Send SMS succeed\n " ;
    
return   0 ;
  }
  
return   - 1 ;
}

# Logout Fetion
#

sub  fetion_sipc_logout
{
  
  
local   $logout_request   =   sprintf ( $FETION_SIPC_LOGOUT , $FETION_DOMAIN_URL ,   $g_fetion_num );
  debug_print 
" Send Logout Request:\n " . $logout_request . " \n " ;
  
local   $sipc_response   =   & sipc_request( $logout_request );
  debug_print 
" Logout Response:\n " . $sipc_response . " \n "
}








# #################################################
#


sub  fetion_verbose
{
  
$g_isverbose   =   1 ;

}

#  INIT the Fetion Lib
# fetion_init( mobile_num, passwd)

sub  fetion_init
{
  
$g_mobile_num   =   @_ [ 0 ];
  
$g_passwd   =   @_ [ 1 ];

  
print   " Retrieving the config xml\n " ;
  
$config_xml   =& fetion_get_config(  $g_mobile_num  );
  
  
& debug_print ( " The XML:\n " . $config_xml . " \n " );
  
if  ( $config_xml  eq  "" )
  {
    
print   " cannot retrieve the config xml exit\n " ;
    
return   - 1 ;
  }

  
print   " Retrieving the SSIAPP URL\n " ;
  
$FETION_SSI_URL   =   & fetion_ssiapp_addr( $config_xml );
  
& debug_print ( " The URL:  " . $FETION_SSI_URL . " \n " );

  
if  ( $FETION_SSI_URL  eq  "" )
  {
    
print   " cannot get the ssiapp url exit\n " ;
    
return   - 1 ;
  }     

  
print   " Retrieving the SIPC Address\n " ;
  
$FETION_SIPC_ADDRESS   =   & fetion_sipc_address( $config_xml );
  
& debug_print ( " The Address:  " . $FETION_SIPC_ADDRESS . " \n " );

  
if  ( $FETION_SIPC_ADDRESS  eq  "" )
  {
    
print   " cannot get the address exit\n " ;
    
return   - 1 ;
  } 

  
print   " Trying to get the fetion number of the current account\n " ;
  
$g_fetion_num   =   & fetion_get_account_num( & fetion_ssiapp_login( $FETION_SSI_URL ,   $g_mobile_num ,   $g_passwd ));
  
& debug_print ( " The Fetion Number:  " . $g_fetion_num . " \n " );

  
if  ( $g_fetion_num  eq  "" )
  {
    
print   " cannot get the fetion number exit\n " ;
    
return   - 1 ;
  } 

  
print   " Connecting to the SIPC via TCP socket\n " ;
  
local   @addr_info   =   split ( " : " ,   $FETION_SIPC_ADDRESS );
  
  
if  (  & sipc_connect(  @addr_info [ 0 ] ,   @addr_info [ 1 ] )  !=   0 )
  {
    
print   " Cannot connect to the address: " . $FETION_SIPC_ADDRESS . " \n " ;
    
& debug_print ( " Reason:  " . $ !. " \n " );
  }
  
return   0
}


#  Release the Fetion Lib

sub  fetion_close
{
  
& sipc_close;
}
# ############################################################################


sub  main
{
  
if  ( & fetion_init(  @ARGV [ 0 ] ,   @ARGV [ 1 ] )  !=   0 )
  {
    
return   - 1 ;
  }

  
if  ( & fetion_sipc_login()  !=   0  )
  {
    
return   - 1 ;
  }

  
if  ( & fetion_sendSMS(  @ARGV [ 2 ] ,   @ARGV [ 3 ])  !=   0 )
  {
    
return   - 1 ;
  }


  
& fetion_sipc_logout();
  
& fetion_close();
  
return   0 ;
}

& main;


---------------------------------------------------------
专注移动开发
Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian

你可能感兴趣的:(Perl版的飞信运行程序)