隨筆-348  評論-598  文章-0  trackbacks-0
          飛信免費短信接口:http://sms.api.bz/fetion.php?username=13800138000&password=123456&sendto=13800138000&message=短信內容,號碼和密碼請自行替換
          #!/usr/bin/perl
          #
          # Open Fetion Perl Version
          # By Shikai Chen ( csk@live.com )
          # 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;
            }
          whileindex($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
          posted on 2010-05-09 18:05 TiGERTiAN 閱讀(1000) 評論(0)  編輯  收藏 所屬分類: Perl/Python

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          專注移動開發--Windows Mobile, Android, iPhone, J2ME, BlackBerry, Symbian, Windows Phone

          慢慢混,慢慢學
          <2010年5月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          常用鏈接

          留言簿(43)

          隨筆分類(402)

          隨筆檔案(306)

          相冊

          我的好友們

          搜索

          •  

          積分與排名

          • 積分 - 812961
          • 排名 - 50

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 江孜县| 东丰县| 电白县| 浠水县| 环江| 新源县| 富民县| 德惠市| 凤庆县| 文成县| 绥江县| 桐庐县| 清原| 汶上县| 临颍县| 蚌埠市| 白朗县| 米林县| 乌兰县| 横山县| 宜章县| 兰考县| 大田县| 浏阳市| 哈尔滨市| 泰兴市| 娱乐| 韩城市| 林甸县| 长顺县| 永安市| 剑河县| 马鞍山市| 陆良县| 广河县| 苏尼特左旗| 施秉县| 藁城市| 岳西县| 泌阳县| 项城市|