package de.jplitza.deviceadministrator;

import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;

import java.security.spec.X509EncodedKeySpec;
import net.i2p.crypto.eddsa.*;

public class IncomingSms extends BroadcastReceiver {
    static enum Command {
        TEST,
        LOCATE,
        WIPE
    };

    private void activateGps(Context context) {
        DevicePolicyManager mDPM = (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
        mDPM.setSecureSetting(getComponentName(context), Settings.Secure.LOCATION_MODE, new Integer(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY).toString());
    }
    public static ComponentName getComponentName(Context context) {
        return new ComponentName(context.getApplicationContext(), DeviceAdmin.class);
    }
    private void getLocation(Context context, String number) throws SecurityException {
        activateGps(context);
        LocationManager locationManager = (LocationManager) context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, new LocationSender(number), null);
    }

    public void onReceive(Context context, Intent intent) {

        SmsMessage msgs[] = android.provider.Telephony.Sms.Intents.getMessagesFromIntent(intent);

        if (msgs == null)
            return;

        for (SmsMessage msg : msgs) {

            String senderNum = msg.getDisplayOriginatingAddress();
            String message = msg.getDisplayMessageBody();
            Log.i("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);

            try {
                byte data[] = Base64.decode(message, Base64.DEFAULT);

                EdDSAEngine sig = new EdDSAEngine();
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
                sig.initVerify(new EdDSAPublicKey(new X509EncodedKeySpec(Base64.decode(
                        prefs.getString("public_key", ""),
                        Base64.DEFAULT
                )
                )));
                if (!sig.verifyOneShot(data, 0, 2, data, 2, data.length - 2))
                    continue;
                Log.i("SmsReceiver", "Signature valid, command: " + data[1] + ", seqnum: " + data[0]);
                byte seqnum = data[0];
                Command command = Command.values()[data[1]];
                if (seqnum < new Integer(prefs.getString("seqnum", "0")))
                    continue;
                switch (command) {
                    case TEST:
                        Toast.makeText(context, "DevAdmin: Test with seqnum " + seqnum + " received.", Toast.LENGTH_LONG).show();
                        break;
                    case LOCATE:
                        getLocation(context, senderNum);
                        break;
                    case WIPE:
                        // TODO
                        break;
                }
                SharedPreferences.Editor e = prefs.edit();
                e.putString("seqnum", new Integer(seqnum + 1).toString());
                e.apply();
            } catch (Exception e) {
                Log.e("SmsReceiver", "Exception", e);

            }
        }
    }
}

@@ -301,75 +301,15 @@
 tion
-;%0Aimport android.location.LocationManager;%0Aimport android.os.Bundle
+Manager
 ;%0Aim
@@ -389,45 +389,8 @@
 gs;%0A
-import android.telephony.SmsManager;%0A
 impo
@@ -640,23 +640,16 @@
 r %7B%0A    
-static 
 enum Com
@@ -703,17 +703,16 @@
 PE%0A    %7D
-;
 %0A%0A    pr
@@ -953,28 +953,24 @@
 ON_MODE,
- new
  Integer
 (Setting
@@ -961,16 +961,25 @@
  Integer
+.toString
 (Setting
@@ -1015,27 +1015,16 @@
 CCURACY)
-.toString()
 );%0A    %7D
@@ -1928,95 +1928,8 @@
 y();
-%0A            Log.i(%22SmsReceiver%22, %22senderNum: %22 + senderNum + %22; message: %22 + message);
 %0A%0A  
@@ -2519,17 +2519,17 @@
     Log.
-i
+d
 (%22SmsRec
@@ -2661,94 +2661,184 @@
     
-Command command = Command.values()%5Bdata%5B1%5D%5D;%0A                if (seqnum %3C new Integer(
+if (seqnum %3C Integer.valueOf(prefs.getString(%22seqnum%22, %220%22))) %7B%0A                    Log.d(%22SmsReceiver%22, %22Sequence number %22 + seqnum + %22 is lower than last sequence number %22 + 
 pref
@@ -2864,17 +2864,17 @@
 %22, %220%22))
-)
+;
 %0A       
@@ -2888,32 +2888,141 @@
       continue;%0A
+                %7D%0A                try %7B%0A                    Command command = Command.values()%5Bdata%5B1%5D%5D;%0A    
                 
@@ -3036,24 +3036,28 @@
 (command) %7B%0A
+    
             
@@ -3099,16 +3099,20 @@
         
+    
 Toast.ma
@@ -3118,24 +3118,97 @@
 akeText(
-context,
+%0A                                    context,%0A                                   
  %22DevAdm
@@ -3211,17 +3211,23 @@
 vAdmin: 
-T
+Valid t
 est with
@@ -3264,26 +3264,91 @@
 d.%22,
- Toast.LENGTH_LONG
+%0A                                    Toast.LENGTH_LONG%0A                            
 ).sh
@@ -3369,39 +3369,47 @@
                 
+  
+  
 break;%0A
+    
                 
@@ -3425,16 +3425,20 @@
 LOCATE:%0A
+    
         
@@ -3502,39 +3502,47 @@
                 
+   
+ 
 break;%0A
+    
                 
@@ -3584,45 +3584,424 @@
     
-// TODO%0A                        break
+    DevicePolicyManager mDPM = (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);%0A                            mDPM.wipeData(0);%0A                            break;%0A                    %7D%0A                %7D%0A                catch(ArrayIndexOutOfBoundsException e) %7B%0A                    Log.w(%22SmsReceiver%22, %22Valid message but invalid command received: %22 + data%5B1%5D);%0A                    continue
 ;%0A  
@@ -4116,20 +4116,16 @@
 um%22,
- new
  Integer
 (seq
@@ -4120,16 +4120,25 @@
  Integer
+.toString
 (seqnum 
@@ -4145,19 +4145,8 @@
 + 1)
-.toString()
 );%0A 

Clean up code and improve error handling/logging