2013-01-15

Récupérer les identifiants OMTP/IMAP FreeMobile

(mise à jour pour les Android récents)




Plus de 300 téléchargements, un peu plus de 110 installations actives, vous avez rempli votre partie du contrat. À moi de remplir la mienne en vous donnant le modus operandi ET les sources de ce qui est publié sur le PlayStore.

La récupération est relativement simple:
  1. Envoyer "STATUS:pv=13;ct=free.VVM.10;pt=5499;//VVM" par binarySMS au 2051:5499
  2. Lire les SMS de réponses du 2051
  3. Isoler celui qui match la regexp ".*;u=.*;pw=.*;.*"
  4. Parser les éléments "u", "pw", "srv", "ipt"
That's all folks !

Vous pouvez télécharger mon application exemple sur le PlayStore : https://play.google.com/store/apps/details?id=net.cekage.vvmfreemobile


Le code source est publié sur mon compte github : https://github.com/cekage/net.cekage.vvmfreemobile

Si vous préférez faire le programme par vous-même, voici le code source :

La classe principale MainActivity.java

package net.cekage.vvmfreemobile;

import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;

import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;

/**
 * inspired by
 * http://code.google.com/p/krvarma-android-samples/source/browse/trunk
 * /SMSDemo/?r=37
 */

public class MainActivity extends Activity {
 public static final String TAG = "cekage_FreeVVM";
 EditText etlp;

 private String FREEMOBILE_ASKING = "isAsking";

 private String FREEMOBILE_DISPLAYED_DATE = "vvminfos";
 ImageButton ibSearch;
 ImageView ivLogo;
 ProgressBar pbAsking;

 private BroadcastReceiver smsreceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
   Bundle bundle = intent.getExtras();
   SmsMessage[] msgs = null;

   if (null != bundle) {
    String info = "";// "Binary SMS from ";
    Object[] pdus = (Object[]) bundle.get("pdus");
    msgs = new SmsMessage[pdus.length];
    byte[] data = null;

    for (int i = 0; i < msgs.length; i++) {
     msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);

     data = msgs[i].getUserData();

     for (int index = 0; index < data.length; ++index) {
      info += Character.toString((char) data[index]);
     }
    }
    updateETLP(info);
    uiAsking(false);
   }
  }

 };

 public void btnClickFetch(View v) {

  SmsManager smsm = SmsManager.getDefault();
  smsm.sendDataMessage("2051", null, (short) 5499,
    "STATUS:pv=13;ct=free.VVM.10;pt=5499;//VVM".getBytes(), null,
    null);
  uiAsking(true);

 }

 public void btnClickShare(View v) {
  Intent sendIntent = new Intent();
  sendIntent.setAction(Intent.ACTION_SEND);
  sendIntent.putExtra(Intent.EXTRA_TEXT, etlp.getText());
  sendIntent.setType("text/plain");
  startActivity(sendIntent);

 }

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  etlp = (EditText) findViewById(R.id.etLoginPass);
  ibSearch = (ImageButton) findViewById(R.id.btnSearch);
  ivLogo = (ImageView) findViewById(R.id.ivLogo);
  pbAsking = (ProgressBar) findViewById(R.id.pbAsking);
  if (savedInstanceState != null) {
   etlp.setText(savedInstanceState
     .getString(FREEMOBILE_DISPLAYED_DATE));
   uiAsking(savedInstanceState.getBoolean(FREEMOBILE_ASKING, false));
  }

  IntentFilter ifDATASMS = new IntentFilter(
    "android.intent.action.DATA_SMS_RECEIVED");
  ifDATASMS.addDataScheme("sms");
  registerReceiver(smsreceiver, ifDATASMS);

 }

 private void uiAsking(Boolean isAsking) {
  ivLogo.setVisibility(isAsking ? View.GONE : View.VISIBLE);
  pbAsking.setVisibility(!isAsking ? View.GONE : View.VISIBLE);
  ibSearch.setEnabled(!isAsking);
 }

 protected void onSaveInstanceState(Bundle bundle) {
  super.onSaveInstanceState(bundle);
  bundle.putString(FREEMOBILE_DISPLAYED_DATE, etlp.getText().toString());
  bundle.putBoolean(FREEMOBILE_ASKING, !ibSearch.isEnabled());
 }

 private void updateETLP(String binarymessage) {

  String FREEMOBILE_LOGIN = "";
  String FREEMOBILE_PASSWORD = "";
  String FREEMOBILE_SERVER = "";
  String FREEMOBILE_PORT = "";

  if (binarymessage.matches(".*;u=.*;pw=.*;.*")) {

   String[] separated = binarymessage.split(";");
   for (String param : separated) {
    if (param.startsWith("u="))
     FREEMOBILE_LOGIN = param.substring(2);
    else if (param.startsWith("pw="))
     FREEMOBILE_PASSWORD = param.substring(3);
    else if (param.startsWith("srv="))
     FREEMOBILE_SERVER = param.substring(4);
    else if (param.startsWith("ipt="))
     FREEMOBILE_PORT = param.substring(4);
   }
   etlp.setText(String.format(
     "Login: %s\nPass: %s\nServer: %s\nPort: %s",
     FREEMOBILE_LOGIN, FREEMOBILE_PASSWORD, FREEMOBILE_SERVER,
     FREEMOBILE_PORT));

  } else {

   etlp.setText(binarymessage);
  }
 }

}

Le layout activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/ivLogo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/ic_launcher"
        android:visibility="visible" />

    <ProgressBar
        android:id="@+id/pbAsking"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" />

    <EditText
        android:id="@+id/etLoginPass"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:ems="20"
        android:inputType="textMultiLine"
        android:lines="5"
        android:singleLine="false"
        android:text="@string/et_mask" >

        <requestFocus />
    </EditText>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <ImageButton
            android:id="@+id/btnSearch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#0000"
            android:onClick="btnClickFetch"
            android:src="@android:drawable/ic_menu_search"
            android:text="@string/btn_search" />

        <ImageButton
            android:id="@+id/btnShare"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#0000"
            android:onClick="btnClickShare"
            android:src="@android:drawable/ic_menu_share" />
    </LinearLayout>

</LinearLayout>

Le manifest AndroidManifest.xml :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.cekage.vvmfreemobile"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="4"
        android:targetSdkVersion="17" />

    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />

    <application
        android:allowBackup="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>