package com.android.mms.ui; import com.android.mms.R; import com.android.mms.dom.OtaNokiaParser; import com.android.mms.dom.OtaOmaParser; import com.android.mms.dom.OtaParser; import com.android.mms.transaction.ApnSetting; import com.android.mms.transaction.BookmarkSetting; import com.android.mms.transaction.OtaConfigVO; import com.android.mms.transaction.OtaConfigVO.BootStarp; import com.android.mms.transaction.OtaConfigVO.EMailSetting; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.telephony.TelephonyManager; import android.util.Log; import android.view.LayoutInflater; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Toast; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class ConfirmOTAActivity extends Activity { /** Called when the activity is first created. */ private static final String TAG = "ConfirmOTAActivity"; private int phoneId = 0; private Map<AlertDialog, Intent> dialogMap = new HashMap<AlertDialog, Intent>(); public static final String CONTENT_MIME_TYPE_B_OTA_OMA = "application/vnd.wap.connectivity-wbxml"; public static final String CONTENT_MIME_TYPE_B_OTA_NOKIA_SETTINGS = "application/x-wap-prov.browser-settings"; public static final String CONTENT_MIME_TYPE_B_OTA_NOKIA_BOOKMARKS = "application/x-wap-prov.browser-bookmarks"; private List<EditText> etList = new ArrayList(); private static String byteToChar(byte b) { StringBuilder result = new StringBuilder(); int a1 = (b >>> 4); result.append("0123456789ABCDEF".charAt((int) (a1 % 16))); a1 = (b & 0x0f); result.append("0123456789ABCDEF".charAt((int) (a1 % 16))); return result.toString(); } private byte[] processImsi(String strImsi) { int strLen = strImsi.length(); if ((strLen % 2) == 0) { strImsi = "1" + strImsi + "F"; } else { strImsi = "9" + strImsi; } char[] charImsi = strImsi.toCharArray(); int len = charImsi.length / 2; byte[] byteImsi = new byte[len]; for (int i = 0; i < len; i++) { int index = i * 2; int temp1 = Integer.parseInt(String.valueOf(charImsi[index])); int temp0 = Integer.parseInt(String.valueOf(charImsi[index + 1])); byteImsi[i] = (byte) ((temp0 << 4) | temp1); } return byteImsi; } private int checkPin(byte[] pin, byte[] pushData, String macData) { Mac mac; try { Log.v(TAG, "pin=" + pin+";pushData="+pushData+";macData"+macData+";"); mac = Mac.getInstance("HmacSHA1"); Key key = new SecretKeySpec(pin, "HmacSHA1"); mac.init(key); byte[] hashValue = mac.doFinal(pushData); StringBuilder result = new StringBuilder(); for (byte b : hashValue) { result.append(byteToChar(b)); } //macData = macData.substring(0, macData.indexOf("00")); Log.v(TAG, "pin==" + pin); Log.v(TAG, "sec==" + macData); String rr = result.toString(); macData = getHexChar(macData); Log.v(TAG, "sec==" + macData); Log.v(TAG, "result =" + rr); Log.v(TAG, "result =" + macData.equals(rr)); if (macData.equals(rr)) { return 0; } else { return 1; } } catch (Exception e) { Log.v(TAG, "exception check pin "); e.printStackTrace(); return 2; } } private final OnClickListener mOKListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int whichButton) { // Get raw PDU push-data from the message and parse it Intent it = dialogMap.get(dialog); byte[] pushData = it.getByteArrayExtra("data"); String mimeType = it.getStringExtra("mimeType"); phoneId = it.getIntExtra("phone_id", 0); String secflag = it.getStringExtra("secflag"); String macData = it.getStringExtra("macData"); if (secflag != null) { TelephonyManager tm = TelephonyManager.getDefault(phoneId); String strImsi = tm.getSubscriberId(); Log.v(TAG, "strImsi==:" + strImsi); EditText et = etList.get(etList.size() - 1); String pin = et.getText().toString();// "1234"; Log.v(TAG, "strPin==:" + pin); byte[] key = null; boolean macFlag = false; if (secflag.equals("80")) { macFlag = true; key = processImsi(strImsi); } else if (secflag.equals("81")) { macFlag = true; key = pin.getBytes(); } else if (secflag.equals("82")) { macFlag = true; byte[] byteImsi = processImsi(strImsi); byte[] bytePin = pin.getBytes(); key = new byte[byteImsi.length + pin.length()]; System.arraycopy(key, 0, byteImsi, 0, byteImsi.length); System.arraycopy(key, byteImsi.length, bytePin, 0, bytePin.length); } else if (secflag.equals("83")) { macFlag = false; } else { macFlag = false; } if (macFlag && key != null) { int checkResult = checkPin(key, pushData, macData); if(checkResult==1 && secflag.equals("80")){ processDialog(4, dialog); return; }else if (checkResult > 0) { processDialog(checkResult, dialog); return; } } } Log.v(TAG, "mimeType==" + mimeType); OtaParser parser; if (mimeType.equals(CONTENT_MIME_TYPE_B_OTA_OMA)) { // Moto OMA parser = new OtaOmaParser(pushData, OtaParser.OTA_OMA_DATA); } else if (mimeType.equals(CONTENT_MIME_TYPE_B_OTA_NOKIA_SETTINGS)) { // Nokia setting parser = new OtaNokiaParser(pushData, OtaParser.OTA_NOKIA_DATA1); } else if (mimeType.equals(CONTENT_MIME_TYPE_B_OTA_NOKIA_BOOKMARKS)) { // Nokia bookmark parser = new OtaNokiaParser(pushData, OtaParser.OTA_NOKIA_DATA2); } else { processDialog(3, dialog); return; } int result=parser.parse(); if(result==OtaParser.OTA_MSG_INVALIDATE || result==OtaParser.OTA_MSG_ERROR){ processDialog(3, dialog); return; } List<OtaConfigVO> data = parser.data; List<Map> emailList = new ArrayList(); Intent i = new Intent("android.email.AutoSetup"); Bundle bb = new Bundle(); int eamilSize = 0; if (data != null) { for (OtaConfigVO config : data) { if (config == null) { continue; } if (null != config.getValue(OtaConfigVO.NAME)) { ApnSetting setting = new ApnSetting(); for (BootStarp bootstartp : config.bsList) { if (!config.getValue(OtaConfigVO.NAME).equals(bootstartp.name)) setting.dropApn(ConfirmOTAActivity.this, bootstartp, phoneId); } String apn = config.getValue(OtaConfigVO.APN); if (null != apn && !apn.equals("") && (config.dataFlag == OtaConfigVO.OMA_W2 || config.dataFlag == OtaConfigVO.OMA_W4 || config.dataFlag == OtaConfigVO.NOKIA_DATA)) { setting.setApn(ConfirmOTAActivity.this, config, phoneId); } } if (config.bmList.size() > 0) { BookmarkSetting bmStting = new BookmarkSetting(); bmStting.setBookmark(ConfirmOTAActivity.this, config); } if (config.emList.size() > 0) { for (EMailSetting es : config.emList) { eamilSize++; Bundle tb = new Bundle(); tb.putString("accountName", es.accountName); tb.putString("userID", es.userID); tb.putString("pwd", es.pwd); tb.putString("returnAddress", es.returnAddress); tb.putString("webSession", es.webSession); tb.putString("protocol", es.protocol); tb.putString("recvHost", es.recvHost); tb.putString("recvPort", es.recvPort); tb.putString("sendHost", es.sendHost); tb.putString("sendPort", es.sendPort); tb.putBoolean("send", es.send); tb.putBoolean("recv", es.recv); tb.putBoolean("recvSSL", es.recvSSL); tb.putBoolean("sendSSL", es.sendSSL); i.putExtra("email" + eamilSize, tb); Log.d(TAG, "accountName:" + es.accountName); Log.d(TAG, "userID:" + es.userID); } } } } if (eamilSize > 0) { i.putExtra("size", eamilSize); sendBroadcast(i); Log.v(TAG, "sendBroadcast result ok"); } Log.v(TAG, "OTA configure ok!"); processDialog(0, dialog); Intent apnIt = new Intent("com.android.broadcasttest.OTAAPNChangge"); sendBroadcast(apnIt); } }; private void processDialog(int flag, DialogInterface dialog) { // setDialogCloseEnable(dialog, false); try { Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing"); field.setAccessible(true); if (flag == 1) { //mShowing=false,not close the dialog field.set(dialog, false); } else { //mShowing=true,close the dialog field.set(dialog, true); dialog.dismiss(); synchronized (dialogMap) { etList.remove(etList.size() - 1); dialogMap.remove(dialog); if (dialogMap.size() == 0) ConfirmOTAActivity.this.finish(); } } } catch (Exception e) { } if (flag == 0) {// process ota message ok Toast.makeText(ConfirmOTAActivity.this, R.string.OTAConfiy_Success, Toast.LENGTH_SHORT) .show(); } else if (flag == 1) {// pin error Toast.makeText(ConfirmOTAActivity.this, R.string.ota_pin_error, Toast.LENGTH_SHORT) .show(); } else if (flag == 2) {// exception Toast.makeText(ConfirmOTAActivity.this, R.string.ota_pin_exception, Toast.LENGTH_SHORT) .show(); } else if (flag == 3) {// error mimetype // OTA message is invalidate // OTA message has error Toast.makeText(ConfirmOTAActivity.this, R.string.ota_mime_error, Toast.LENGTH_SHORT) .show(); }else if (flag == 4) {// error mimetype // OTA message is invalidate // OTA message has error Toast.makeText(ConfirmOTAActivity.this, R.string.ota_imsi_error, Toast.LENGTH_SHORT) .show(); } } private static String getHexChar(String num) { String result = ""; for (int i = 0; i < num.length(); i += 2) { result += (char) Integer.parseInt(num.substring(i, i + 2), 16); } return result; } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent it = this.getIntent(); byte[] header = it.getByteArrayExtra("header"); AlertDialog.Builder dialog = showConfirmDialog(); String secflag = ""; /*** * Encode security method (SEC) (WAP-183-PROVCONT 5.3) * 0x00 = NETWPIN * 0x01 = USERPIN * 0x02 = USERNETWPIN * 0x03 = USERPINMAC * [91] SEC (0x80 | 0x11 = 0x91) (WAP-230-WSP Table 38) * <security-method> The security method (NETWPIN, USERPIN, etc) * [92] MAC (0x80 | 0x12 = 0x92) (WAP-230-WSP Table 38) * <hmac-value> MAC value, always 40 bytes * [00] EOF */ if (header != null && header.length > 0) { int length = header.length; StringBuilder headerdata = new StringBuilder(); for (int i = 0; i < length; i++) { headerdata.append(byteToChar(header[i])); } Log.v(TAG, "headerdata:" + headerdata); int index = headerdata.indexOf("91");// 91 sec length = headerdata.length(); if (index > 0) { String macData = ""; secflag = headerdata.substring(index + 2, index + 4); String macflag = headerdata.substring(index + 4, index + 6); if (macflag.equals("92")) { macData = headerdata.substring(index + 6,(index + 6 + 80)); } EditText et = etList.get(etList.size() - 1); if (secflag.equals("80")) { // do nothing } else if (secflag.equals("81")) { et.setVisibility(EditText.VISIBLE); } else if (secflag.equals("82")) { et.setVisibility(EditText.VISIBLE); } else { // do nothing } it.putExtra("secflag", secflag); it.putExtra("macData", macData); Log.v(TAG, "secflag==:" + secflag); Log.v(TAG, "macData==:" + macData); } } synchronized (dialogMap) { AlertDialog ad = dialog.create(); ad.show(); dialogMap.put(ad, it); } } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); } private AlertDialog.Builder showConfirmDialog() { Builder dialog = new AlertDialog.Builder(this); LayoutInflater inflater = (LayoutInflater) this .getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.ota_dialog, null); etList.add((EditText) layout.findViewById(R.id.idEtOTAPin)); dialog.setView(layout); dialog.setTitle(R.string.OTAConfig_title).setIcon(android.R.drawable.ic_dialog_alert) .setCancelable(true); dialog.setPositiveButton(R.string.yes, mOKListener) .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { synchronized (dialogMap) { // setDialogCloseEnable(dialog, false); dialogMap.remove(dialog); if (dialogMap.size() == 0) ConfirmOTAActivity.this.finish(); } } }).setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { // setDialogCloseEnable(dialog, false); synchronized (dialogMap) { dialogMap.remove(dialog); if (dialogMap.size() == 0) ConfirmOTAActivity.this.finish(); } } }); return dialog; } }