├── .gitignore
├── LICENSE
├── README.md
├── agent
├── build.gradle
├── lint.xml
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── mwr
│ │ └── dz
│ │ ├── Agent.java
│ │ ├── EndpointAdapter.java
│ │ ├── activities
│ │ ├── AboutActivity.java
│ │ ├── ConnectorActivity.java
│ │ ├── EndpointActivity.java
│ │ ├── EndpointSettingsActivity.java
│ │ ├── MainActivity.java
│ │ ├── ServerActivity.java
│ │ └── SettingsActivity.java
│ │ ├── models
│ │ ├── EndpointManager.java
│ │ └── ServerSettings.java
│ │ ├── receivers
│ │ └── Receiver.java
│ │ ├── service_connectors
│ │ ├── ClientServiceConnection.java
│ │ ├── IncomingReplyHandler.java
│ │ ├── ServerServiceConnection.java
│ │ └── SessionServiceConnection.java
│ │ ├── services
│ │ ├── ClientService.java
│ │ ├── ConnectorService.java
│ │ ├── ServerService.java
│ │ └── SessionService.java
│ │ └── views
│ │ ├── CheckListItemView.java
│ │ ├── ConnectorStatusIndicator.java
│ │ ├── EndpointListRowView.java
│ │ ├── EndpointListView.java
│ │ ├── ServerListRowView.java
│ │ └── logger
│ │ ├── LogMessageAdapter.java
│ │ └── LogMessageRowView.java
│ └── res
│ ├── drawable-hdpi
│ ├── drozer.png
│ ├── ic_action_delete.png
│ ├── ic_action_edit.png
│ ├── ic_action_new.png
│ ├── ic_action_online.png
│ ├── ic_action_refresh.png
│ ├── ic_action_search.png
│ ├── ic_action_unknown.png
│ ├── ic_input_add.png
│ ├── ic_launcher.png
│ ├── ic_notification.png
│ ├── ic_stat_active.png
│ ├── ic_stat_offline.png
│ ├── ic_stat_online.png
│ └── ic_stat_unknown.png
│ ├── drawable-ldpi
│ ├── ic_action_delete.png
│ ├── ic_action_edit.png
│ ├── ic_action_new.png
│ ├── ic_action_online.png
│ ├── ic_action_refresh.png
│ ├── ic_action_unknown.png
│ ├── ic_input_add.png
│ ├── ic_stat_active.png
│ ├── ic_stat_offline.png
│ ├── ic_stat_online.png
│ └── ic_stat_unknown.png
│ ├── drawable-mdpi
│ ├── ic_action_delete.png
│ ├── ic_action_edit.png
│ ├── ic_action_new.png
│ ├── ic_action_online.png
│ ├── ic_action_refresh.png
│ ├── ic_action_search.png
│ ├── ic_action_unknown.png
│ ├── ic_input_add.png
│ ├── ic_launcher.png
│ ├── ic_notification.png
│ ├── ic_stat_active.png
│ ├── ic_stat_offline.png
│ ├── ic_stat_online.png
│ └── ic_stat_unknown.png
│ ├── drawable-xhdpi
│ ├── ic_action_delete.png
│ ├── ic_action_edit.png
│ ├── ic_action_new.png
│ ├── ic_action_online.png
│ ├── ic_action_refresh.png
│ ├── ic_action_search.png
│ ├── ic_action_unknown.png
│ ├── ic_input_add.png
│ ├── ic_launcher.png
│ ├── ic_notification.png
│ ├── ic_stat_active.png
│ ├── ic_stat_offline.png
│ ├── ic_stat_online.png
│ └── ic_stat_unknown.png
│ ├── drawable
│ └── ic_stat_connecting.xml
│ ├── layout-land
│ └── activity_main.xml
│ ├── layout-v14
│ ├── toggle_endpoint.xml
│ └── toggle_server.xml
│ ├── layout
│ ├── activity_about.xml
│ ├── activity_endpoint.xml
│ ├── activity_endpoint_settings.xml
│ ├── activity_main.xml
│ ├── activity_server.xml
│ ├── check_list_item.xml
│ ├── list_view_row_endpoint.xml
│ ├── list_view_row_server.xml
│ ├── notification_session.xml
│ ├── toggle_endpoint.xml
│ └── toggle_server.xml
│ ├── menu
│ ├── activity_connector.xml
│ ├── activity_endpoint_settings.xml
│ └── activity_main.xml
│ ├── raw
│ ├── agent.bks
│ └── ca.bks
│ ├── values-v11
│ └── styles.xml
│ ├── values-v14
│ └── styles.xml
│ ├── values
│ ├── attrs.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ ├── endpoint_headers.xml
│ └── preferences.xml
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── jdiesel
├── CMakeLists.txt
├── build.gradle
├── lib
│ └── protobuf-java-2.6.1.jar
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── cpp
│ └── libmstring
│ │ └── mstring.cpp
│ ├── java
│ └── com
│ │ └── mwr
│ │ └── jdiesel
│ │ ├── api
│ │ ├── APIVersionException.java
│ │ ├── DeviceInfo.java
│ │ ├── Frame.java
│ │ ├── InvalidMessageException.java
│ │ ├── UnexpectedMessageException.java
│ │ ├── builders
│ │ │ ├── MessageFactory.java
│ │ │ ├── ReflectionResponseFactory.java
│ │ │ ├── SystemRequestFactory.java
│ │ │ └── SystemResponseFactory.java
│ │ ├── connectors
│ │ │ ├── Connection.java
│ │ │ ├── Connector.java
│ │ │ ├── Endpoint.java
│ │ │ ├── EndpointSocketFactory.java
│ │ │ ├── Server.java
│ │ │ └── ServerSocketFactory.java
│ │ ├── handlers
│ │ │ ├── FileTransformMessageHandler.java
│ │ │ ├── MessageHandler.java
│ │ │ ├── ReflectionMessageHandler.java
│ │ │ └── SystemMessageHandler.java
│ │ ├── links
│ │ │ ├── Client.java
│ │ │ ├── Link.java
│ │ │ └── Server.java
│ │ ├── sessions
│ │ │ ├── Session.java
│ │ │ └── SessionCollection.java
│ │ └── transport
│ │ │ ├── SecureTransport.java
│ │ │ ├── SocketTransport.java
│ │ │ ├── Transport.java
│ │ │ └── TransportDisconnectedException.java
│ │ ├── connection
│ │ ├── AbstractConnection.java
│ │ ├── AbstractLink.java
│ │ ├── AbstractSession.java
│ │ ├── AbstractSessionCollection.java
│ │ └── SecureConnection.java
│ │ ├── logger
│ │ ├── LogMessage.java
│ │ ├── Logger.java
│ │ └── OnLogMessageListener.java
│ │ ├── reflection
│ │ ├── ObjectStore.java
│ │ ├── Reflector.java
│ │ └── types
│ │ │ ├── ReflectedArray.java
│ │ │ ├── ReflectedBinary.java
│ │ │ ├── ReflectedNull.java
│ │ │ ├── ReflectedObject.java
│ │ │ ├── ReflectedPrimitive.java
│ │ │ ├── ReflectedString.java
│ │ │ └── ReflectedType.java
│ │ └── util
│ │ ├── Shell.java
│ │ ├── Strings.java
│ │ └── Verify.java
│ ├── proto
│ └── protobuf.proto
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── values-v11
│ └── styles.xml
│ ├── values-v14
│ └── styles.xml
│ └── values
│ ├── strings.xml
│ └── styles.xml
├── mwrandroid
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── mwr
│ │ └── common
│ │ └── android
│ │ └── app
│ │ └── NotifyingService.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── layout
│ └── list_view_row_log_message.xml
│ ├── values-v11
│ └── styles.xml
│ ├── values-v14
│ └── styles.xml
│ └── values
│ ├── strings.xml
│ └── styles.xml
├── mwrtls
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── mwr
│ │ └── common
│ │ └── tls
│ │ ├── X509Fingerprint.java
│ │ └── trust_managers
│ │ ├── KeyStoreTrustManager.java
│ │ └── NaiveTrustManager.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── values-v11
│ └── styles.xml
│ ├── values-v14
│ └── styles.xml
│ └── values
│ ├── strings.xml
│ └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | /*/*/build/
3 | build/
4 | /*/.externalNativeBuild/
5 |
6 | # Local configuration file (sdk path, etc)
7 | local.properties
8 |
9 | # Gradle generated files
10 | .gradle/
11 |
12 | # Signing files
13 | .signing/
14 |
15 | # User-specific configurations
16 | .idea/libraries/
17 | .idea/workspace.xml
18 | .idea/tasks.xml
19 | .idea/.name
20 | .idea/compiler.xml
21 | .idea/copyright/profiles_settings.xml
22 | .idea/encodings.xml
23 | .idea/misc.xml
24 | .idea/modules.xml
25 | .idea/scopes/scope_settings.xml
26 | .idea/vcs.xml
27 | .idea/
28 | *.iml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012, 2013 MWR InfoSecurity
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 | * Neither the name of MWR InfoSecurity nor the names of its contributors
13 | may be used to endorse or promote products derived from this software
14 | without specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL MWR INFOSECURITY BE LIABLE FOR ANY
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
27 |
28 | This licence does not apply to the following components:
29 |
30 | - The Google Protocol Buffers support library for Java, located at:
31 | /libs/protobuf-java-2.4.1.jar. Owned by Google and available to download
32 | from: https://developers.google.com/protocol-buffers/
33 |
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | drozer
2 | ======
3 |
4 | drozer (formerly Mercury) is the leading security testing framework for Android.
5 |
6 | drozer allows you to search for security vulnerabilities in apps and devices by assuming the role of an app and interacting with the Dalvik VM, other apps' IPC endpoints and the underlying OS.
7 |
8 | drozer provides tools to help you use, share and understand public Android exploits. It helps you to deploy a drozer Agent to a device through exploitation or social engineering. Using weasel (MWR's advanced exploitation payload) drozer is able to maximise the permissions available to it by installing a full agent, injecting a limited agent into a running process, or connecting a reverse shell to act as a Remote Access Tool (RAT).
9 |
10 | drozer is open source software, maintained by MWR InfoSecurity, and can be downloaded from:
11 |
12 | mwr.to/drozer
13 |
14 |
15 | Building Using Android Studio
16 | -----------------------------
17 |
18 | 1. Open Android Studio and launch the Android SDK manager from it (Tools > Android > SDK Manager)
19 | 1. Check that these two components are installed and updated to the latest version. Install or upgrade
20 | them if necessary.
21 | 1. *Android SDK Platform Tools*
22 | 2. *Android Support Library*
23 | 3. *Google Play Services*
24 | 4. *Google Repository*
25 | 5. *Android NDK tools*
26 | 1. Return to Android Studio and select *Import Project*
27 | 1. Select the **drozer-agent** directory
28 | 1. Select "Import from existing model - Gradle"
29 |
30 | **IMPORTANT**: Once imported make sure the project has been synchronized with the Gradle files.
31 |
32 | Build Dependencies
33 | ------------------
34 |
35 | 1. Java 1.7
36 | 2. libprotobuf-java 2.6.1 or higher
37 | 3. protobuf-compiler 2.6 or higher
38 |
39 | License
40 | -------
41 |
42 | drozer is released under a 3-clause BSD License. See LICENSE for full details.
43 |
44 |
45 | Contacting the Project
46 | ----------------------
47 |
48 | drozer is Open Source software, made great by contributions from the community.
49 |
50 | For full source code, to report bugs, suggest features and contribute patches please see our Github project:
51 |
52 | https://github.com/mwrlabs/drozer
53 |
54 | Bug reports, feature requests, comments and questions can be submitted sent to:
55 |
56 | drozer [at] mwrinfosecurity.com
57 |
58 | Follow the latest drozer news, follow the project on Twitter:
59 |
60 | @mwrdrozer
61 |
--------------------------------------------------------------------------------
/agent/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | buildToolsVersion "29.0.3"
6 | ndkVersion '21.3.6528147'
7 |
8 | defaultConfig {
9 | applicationId "com.mwr.dz"
10 | minSdkVersion 7
11 | targetSdkVersion 29
12 | }
13 |
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile project(':jdiesel')
24 | compile project(':mwrtls')
25 | compile project(':mwrandroid')
26 | }
27 |
--------------------------------------------------------------------------------
/agent/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/agent/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
31 |
34 |
37 |
40 |
41 |
45 |
46 |
47 |
48 |
49 |
50 |
53 |
56 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/EndpointAdapter.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz;
2 |
3 | import com.mwr.dz.models.EndpointManager;
4 | import com.mwr.dz.views.EndpointListRowView;
5 | import com.mwr.jdiesel.api.connectors.Endpoint;
6 |
7 | import android.content.Context;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.BaseAdapter;
11 |
12 | public class EndpointAdapter extends BaseAdapter {
13 |
14 | public interface OnEndpointSelectListener {
15 |
16 | public void onEndpointSelect(Endpoint endpoint);
17 | public void onEndpointToggle(Endpoint endpoint, boolean toggle);
18 |
19 | }
20 |
21 | private Context context = null;
22 | private EndpointManager endpoint_manager = null;
23 | private OnEndpointSelectListener endpoint_listener = null;
24 |
25 | public EndpointAdapter(Context context, EndpointManager endpoint_manager, OnEndpointSelectListener endpoint_listener) {
26 | this.context = context;
27 | this.endpoint_listener = endpoint_listener;
28 | this.endpoint_manager = endpoint_manager;
29 |
30 | this.endpoint_manager.setOnDatasetChangeListener(new EndpointManager.OnDatasetChangeListener() {
31 |
32 | @Override
33 | public void onDatasetChange(EndpointManager manager) {
34 | EndpointAdapter.this.notifyDataSetChanged();
35 | }
36 |
37 | });
38 | }
39 |
40 | @Override
41 | public int getCount() {
42 | return this.endpoint_manager.size();
43 | }
44 |
45 | @Override
46 | public Object getItem(int pos) {
47 | return this.endpoint_manager.all().get(pos);
48 | }
49 |
50 | @Override
51 | public long getItemId(int pos) {
52 | return pos;
53 | }
54 |
55 | @Override
56 | public View getView(int pos, View copyView, ViewGroup parent) {
57 | EndpointListRowView view = new EndpointListRowView(this.context);
58 | view.setEndpoint((Endpoint)this.getItem(pos));
59 | view.setEndpointListener(this.endpoint_listener);
60 |
61 | return view;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/activities/AboutActivity.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.activities;
2 |
3 | import com.mwr.dz.R;
4 |
5 | import android.os.Bundle;
6 | import android.app.Activity;
7 | import android.content.pm.PackageManager.NameNotFoundException;
8 | import android.view.Menu;
9 | import android.widget.TextView;
10 |
11 | public class AboutActivity extends Activity {
12 |
13 | private TextView description;
14 |
15 | private String getVersionName() {
16 | try {
17 | return this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
18 | }
19 | catch(NameNotFoundException e) {
20 | throw new RuntimeException();
21 | }
22 | }
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_about);
28 |
29 | this.description = (TextView)this.findViewById(R.id.about_description);
30 | this.description.setText(String.format(this.getString(R.string.about_description), this.getVersionName()));
31 | }
32 |
33 | @Override
34 | public boolean onCreateOptionsMenu(Menu menu) {
35 | return false;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/activities/ConnectorActivity.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.activities;
2 |
3 | import java.lang.ref.WeakReference;
4 |
5 | import com.mwr.dz.Agent;
6 | import com.mwr.dz.R;
7 | import com.mwr.jdiesel.api.connectors.Connector;
8 |
9 | import android.app.Activity;
10 | import android.app.AlertDialog;
11 | import android.app.Dialog;
12 | import android.content.Context;
13 | import android.content.DialogInterface;
14 | import android.os.Bundle;
15 | import android.os.Handler;
16 | import android.os.Message;
17 | import android.view.Menu;
18 | import android.view.MenuItem;
19 |
20 | public abstract class ConnectorActivity extends Activity {
21 |
22 | public static class IncomingFingerprintHandler extends Handler {
23 |
24 | private final WeakReference context;
25 |
26 | public IncomingFingerprintHandler(Context context) {
27 | this.context = new WeakReference(context);
28 | }
29 |
30 | @Override
31 | public void handleMessage(Message msg) {
32 | ConnectorActivity context = (ConnectorActivity)this.context.get();
33 | Bundle data = msg.getData();
34 |
35 | if(data.getString(Connector.CONNECTOR_SSL_FINGERPRINT) != null)
36 | context.receiveFingerprint(data.getString(Connector.CONNECTOR_SSL_FINGERPRINT));
37 | else
38 | context.receiveFingerprint(context.getString(R.string.ssl_no_fingerprint));
39 | }
40 |
41 | }
42 |
43 | protected Dialog createInformationDialog(int titleId, int messageId) {
44 | return new AlertDialog.Builder(this)
45 | .setTitle(titleId)
46 | .setMessage(messageId)
47 | .setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
48 |
49 | public void onClick(DialogInterface dialog, int id) {}
50 |
51 | })
52 | .create();
53 | }
54 |
55 | protected Dialog createInformationDialog(int titleId, String message) {
56 | return new AlertDialog.Builder(this)
57 | .setTitle(titleId)
58 | .setMessage(message)
59 | .setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
60 |
61 | public void onClick(DialogInterface dialog, int id) {}
62 |
63 | })
64 | .create();
65 | }
66 |
67 | @Override
68 | public boolean onCreateOptionsMenu(Menu menu) {
69 | getMenuInflater().inflate(R.menu.activity_connector, menu);
70 | return true;
71 | }
72 |
73 | @Override
74 | public boolean onOptionsItemSelected(MenuItem item) {
75 | switch(item.getItemId()) {
76 | case R.id.show_fingerprint:
77 | this.showFingerprintDialog();
78 | return true;
79 |
80 | case R.id.refresh_status:
81 | this.refreshStatus();
82 | return true;
83 |
84 | default:
85 | return super.onOptionsItemSelected(item);
86 | }
87 | }
88 |
89 | @Override
90 | protected void onPause() {
91 | super.onPause();
92 |
93 | Agent.getInstance().unbindServices();
94 | }
95 |
96 | @Override
97 | protected void onResume() {
98 | super.onResume();
99 |
100 | Agent.getInstance().bindServices();
101 | }
102 |
103 | public abstract void receiveFingerprint(String fingerprint);
104 | protected abstract void refreshStatus();
105 | protected abstract void showFingerprintDialog();
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/models/ServerSettings.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.models;
2 |
3 | import android.content.SharedPreferences;
4 | import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
5 |
6 | import com.mwr.dz.Agent;
7 | import com.mwr.jdiesel.api.connectors.Server;
8 |
9 | public class ServerSettings implements OnSharedPreferenceChangeListener {
10 |
11 | private Server server;
12 |
13 | private char[] getKeyPassword() {
14 | return this.getSettings().getString(Server.SERVER_KEY_PASSWORD, "drozer").toCharArray();
15 | }
16 |
17 | private char[] getKeyStorePassword() {
18 | return this.getSettings().getString(Server.SERVER_KEYSTORE_PASSWORD, "drozer").toCharArray();
19 | }
20 |
21 | private String getKeyStorePath() {
22 | return this.getSettings().getString(Server.SERVER_KEYSTORE_PATH, "/data/data/com.mwr.dz/files/drozer.bks");
23 | }
24 |
25 | private String getPassword() {
26 | return this.getSettings().getString(Server.SERVER_PASSWORD, "");
27 | }
28 |
29 | private int getPort() {
30 | return Integer.parseInt(this.getSettings().getString(Server.SERVER_PORT, "31415"));
31 | }
32 |
33 | private SharedPreferences getSettings() {
34 | return Agent.getInstance().getSettings();
35 | }
36 |
37 | private boolean isSSL() {
38 | return this.getSettings().getBoolean(Server.SERVER_SSL, false);
39 | }
40 |
41 | public void load(Server server) {
42 | this.server = server;
43 |
44 | server.setPort(this.getPort());
45 | server.setPassword(this.getPassword());
46 | server.setSSL(this.isSSL());
47 |
48 | if(this.isSSL()) {
49 | server.setSSL(this.isSSL());
50 | server.setKeyStorePath(this.getKeyStorePath());
51 | server.setKeyStorePassword(this.getKeyStorePassword());
52 | server.setKeyPassword(this.getKeyPassword());
53 | }
54 |
55 | server.resetKeyManagerFactory();
56 |
57 | this.getSettings().registerOnSharedPreferenceChangeListener(this);
58 | }
59 |
60 | @Override
61 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
62 | if(key.equals(Server.SERVER_PORT))
63 | this.server.setPort(this.getPort());
64 | if(key.equals(Server.SERVER_PASSWORD))
65 | this.server.setPassword(this.getPassword());
66 |
67 | if(key.equals(Server.SERVER_SSL)) {
68 | this.server.setSSL(this.isSSL());
69 | server.setKeyStorePath(this.getKeyStorePath());
70 | server.setKeyStorePassword(this.getKeyStorePassword());
71 | server.setKeyPassword(this.getKeyPassword());
72 | }
73 |
74 | if(key.equals(Server.SERVER_KEYSTORE_PATH))
75 | server.setKeyStorePath(this.getKeyStorePath());
76 | if(key.equals(Server.SERVER_KEYSTORE_PASSWORD))
77 | server.setKeyStorePassword(this.getKeyStorePassword());
78 | if(key.equals(Server.SERVER_KEY_PASSWORD))
79 | server.setKeyPassword(this.getKeyPassword());
80 | }
81 |
82 | public boolean save(Server server) {
83 | SharedPreferences.Editor editor = Agent.getInstance().getSettings().edit();
84 |
85 | editor.remove(Server.SERVER_PORT);
86 | editor.putString(Server.SERVER_PORT, Integer.valueOf(this.getPort()).toString());
87 |
88 | return editor.commit();
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/receivers/Receiver.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.receivers;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 |
8 | public class Receiver extends BroadcastReceiver {
9 |
10 | public static final String PWN_INTENT = "com.mwr.dz.PWN";
11 |
12 | @Override
13 | public void onReceive(Context context, Intent intent) {
14 | Intent start_service = new Intent();
15 | start_service.putExtras(intent);
16 |
17 | if(intent.getCategories().contains("com.mwr.dz.START_EMBEDDED")) {
18 | start_service.addCategory("com.mwr.dz.START_EMBEDDED");
19 | start_service.setComponent(new ComponentName("com.mwr.dz", "com.mwr.dz.services.ServerService"));
20 | }
21 | else {
22 | if(intent.getCategories().contains("com.mwr.dz.CREATE_ENDPOINT"))
23 | start_service.addCategory("com.mwr.dz.CREATE_ENDPOINT");
24 | if(intent.getCategories().contains("com.mwr.dz.START_ENDPOINT"))
25 | start_service.addCategory("com.mwr.dz.START_ENDPOINT");
26 |
27 | start_service.setComponent(new ComponentName("com.mwr.dz", "com.mwr.dz.services.ClientService"));
28 | }
29 |
30 | context.startService(start_service);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/service_connectors/ClientServiceConnection.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.service_connectors;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Context;
5 | import android.content.ServiceConnection;
6 | import android.os.Bundle;
7 | import android.os.IBinder;
8 | import android.os.Message;
9 | import android.os.Messenger;
10 | import android.os.RemoteException;
11 | import android.util.Log;
12 |
13 | import com.mwr.dz.Agent;
14 | import com.mwr.dz.services.ClientService;
15 | import com.mwr.jdiesel.api.connectors.Endpoint;
16 |
17 | public class ClientServiceConnection implements ServiceConnection {
18 |
19 | private Messenger service = null;
20 | private boolean bound = false;
21 |
22 | public boolean isBound() {
23 | return this.bound;
24 | }
25 |
26 | public void getDetailedEndpointStatus(int id, Messenger replyTo) throws RemoteException {
27 | Bundle data = new Bundle();
28 |
29 | data.putInt(Endpoint.ENDPOINT_ID, id);
30 |
31 | Message msg = Message.obtain(null, ClientService.MSG_GET_DETAILED_ENDPOINT_STATUS);
32 | msg.replyTo = Agent.getInstance().getMessenger();
33 | msg.setData(data);
34 |
35 | this.send(msg);
36 | }
37 |
38 | public void getEndpointStatuses(Messenger replyTo) throws RemoteException {
39 | Message msg = Message.obtain(null, ClientService.MSG_GET_ENDPOINTS_STATUS);
40 | msg.replyTo = replyTo;
41 |
42 | this.send(msg);
43 | }
44 |
45 | public void getPeerFingerprint(int id, Messenger replyTo) throws RemoteException {
46 | Bundle data = new Bundle();
47 | data.putBoolean("ctrl:no_cache_messenger", true);
48 | data.putInt(Endpoint.ENDPOINT_ID, id);
49 |
50 | Message msg = Message.obtain(null, ClientService.MSG_GET_SSL_FINGERPRINT);
51 | msg.replyTo = replyTo;
52 | msg.setData(data);
53 |
54 | this.send(msg);
55 | }
56 |
57 | @Override
58 | public void onServiceConnected(ComponentName className, IBinder service) {
59 | this.service = new Messenger(service);
60 | this.bound = true;
61 |
62 | if(Agent.getInstance().getSettings().getBoolean("restore_after_crash", true)){
63 | for(Endpoint e : Agent.getInstance().getEndpointManager().all()){
64 | if(e.isActive()){
65 | try {
66 | Log.d("ClientService", "Resuming connection to endpoint...");
67 | Agent.getInstance().getClientService().startEndpoint(e, Agent.getInstance().getMessenger());
68 | } catch (RemoteException re) {
69 | re.printStackTrace();
70 | }
71 | }
72 | }
73 | }
74 |
75 | }
76 |
77 | @Override
78 | public void onServiceDisconnected(ComponentName className) {
79 | this.service = null;
80 | this.bound = false;
81 | }
82 |
83 | protected void send(Message msg) throws RemoteException {
84 | this.service.send(msg);
85 | }
86 |
87 | public void startEndpoint(Endpoint endpoint, Messenger replyTo) throws RemoteException {
88 | Bundle data = new Bundle();
89 | data.putInt(Endpoint.ENDPOINT_ID, endpoint.getId());
90 |
91 | Message msg = Message.obtain(null, ClientService.MSG_START_ENDPOINT);
92 | msg.replyTo = replyTo;
93 | msg.setData(data);
94 |
95 | this.send(msg);
96 |
97 | endpoint.enabled = true;
98 | endpoint.notifyObservers();
99 | }
100 |
101 | public void stopEndpoint(Endpoint endpoint, Messenger replyTo) throws RemoteException {
102 | Bundle data = new Bundle();
103 |
104 | data.putInt(Endpoint.ENDPOINT_ID, endpoint.getId());
105 |
106 | Message msg = Message.obtain(null, ClientService.MSG_STOP_ENDPOINT);
107 | msg.replyTo = replyTo;
108 | msg.setData(data);
109 |
110 | this.send(msg);
111 |
112 | endpoint.enabled = false;
113 | endpoint.notifyObservers();
114 | }
115 |
116 | public void unbind(Context context) {
117 | if(this.bound) {
118 | context.unbindService(this);
119 | this.bound = false;
120 | }
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/service_connectors/IncomingReplyHandler.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.service_connectors;
2 |
3 | import java.lang.ref.WeakReference;
4 |
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.Message;
8 |
9 | import com.mwr.dz.Agent;
10 | import com.mwr.dz.services.ClientService;
11 | import com.mwr.dz.services.ConnectorService;
12 | import com.mwr.dz.services.ServerService;
13 | import com.mwr.jdiesel.api.connectors.Connector;
14 | import com.mwr.jdiesel.api.connectors.Endpoint;
15 | import com.mwr.jdiesel.logger.LogMessage;
16 |
17 | public class IncomingReplyHandler extends Handler {
18 |
19 | private final WeakReference agent;
20 |
21 | public IncomingReplyHandler(Agent agent) {
22 | this.agent = new WeakReference(agent);
23 | }
24 |
25 | @Override
26 | public void handleMessage(Message msg) {
27 | Agent agent = this.agent.get();
28 | Bundle data = msg.getData();
29 |
30 | switch(msg.what) {
31 | case ClientService.MSG_GET_DETAILED_ENDPOINT_STATUS:
32 | agent.getEndpointManager().get(data.getInt(Endpoint.ENDPOINT_ID)).setDetailedStatus(data);
33 | break;
34 |
35 | case ClientService.MSG_GET_ENDPOINTS_STATUS:
36 | for(Endpoint e : agent.getEndpointManager().all())
37 | if(data.containsKey("endpoint-" + e.getId()))
38 | e.setStatus(Endpoint.Status.values()[data.getInt("endpoint-" + e.getId())]);
39 | break;
40 |
41 | case ServerService.MSG_GET_DETAILED_SERVER_STATUS:
42 | agent.getServerParameters().setDetailedStatus(data);
43 | break;
44 |
45 | case ServerService.MSG_GET_SERVER_STATUS:
46 | agent.getServerParameters().setStatus(Connector.Status.values()[data.getInt("server")]);
47 | break;
48 |
49 | case ConnectorService.MSG_LOG_MESSAGE:
50 | LogMessage log_message = new LogMessage(data.getBundle(Connector.CONNECTOR_LOG_MESSAGE));
51 | if (data.containsKey(Endpoint.ENDPOINT_ID))
52 | agent.getEndpointManager().get(data.getInt(Endpoint.ENDPOINT_ID)).getLogger().log(log_message);
53 | else
54 | agent.getServerParameters().getLogger().log(log_message);
55 | break;
56 |
57 | default:
58 | super.handleMessage(msg);
59 | }
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/service_connectors/ServerServiceConnection.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.service_connectors;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Context;
5 | import android.content.ServiceConnection;
6 | import android.content.SharedPreferences.Editor;
7 | import android.os.Bundle;
8 | import android.os.IBinder;
9 | import android.os.Message;
10 | import android.os.Messenger;
11 | import android.os.RemoteException;
12 |
13 | import com.mwr.dz.Agent;
14 | import com.mwr.dz.services.ServerService;
15 | import com.mwr.jdiesel.api.connectors.Server;
16 |
17 | public class ServerServiceConnection implements ServiceConnection {
18 |
19 | private Messenger service = null;
20 | private boolean bound = false;
21 |
22 | public void getDetailedServerStatus(Messenger replyTo) throws RemoteException {
23 | Message msg = Message.obtain(null, ServerService.MSG_GET_DETAILED_SERVER_STATUS);
24 | msg.replyTo = replyTo;
25 |
26 | this.send(msg);
27 | }
28 |
29 | public void getHostFingerprint(Messenger replyTo) throws RemoteException {
30 | Bundle data = new Bundle();
31 | data.putBoolean("ctrl:no_cache_messenger", true);
32 |
33 | Message msg = Message.obtain(null, ServerService.MSG_GET_SSL_FINGERPRINT);
34 | msg.replyTo = replyTo;
35 | msg.setData(data);
36 |
37 | this.send(msg);
38 | }
39 |
40 | public void getServerStatus(Messenger replyTo) throws RemoteException {
41 | Message msg = Message.obtain(null, ServerService.MSG_GET_SERVER_STATUS);
42 | msg.replyTo = replyTo;
43 |
44 | this.send(msg);
45 | }
46 |
47 | public boolean isBound() {
48 | return this.bound;
49 | }
50 |
51 | @Override
52 | public void onServiceConnected(ComponentName className, IBinder service) {
53 | this.service = new Messenger(service);
54 | this.bound = true;
55 | if(Agent.getInstance().getSettings().getBoolean("localServerEnabled", false) && Agent.getInstance().getSettings().getBoolean("restore_after_crash", true)){
56 | try {
57 | ServerServiceConnection ssc = Agent.getInstance().getServerService();
58 | Server server = Agent.getInstance().getServerParameters();
59 | Messenger messenger = Agent.getInstance().getMessenger();
60 |
61 | ssc.startServer(server, messenger);
62 | } catch (RemoteException e) {
63 | e.printStackTrace();
64 | }
65 | }
66 | }
67 |
68 | @Override
69 | public void onServiceDisconnected(ComponentName className) {
70 | this.service = null;
71 | this.bound = false;
72 | }
73 |
74 | protected void send(Message msg) throws RemoteException {
75 | this.service.send(msg);
76 | }
77 |
78 | public void startServer(Server server, Messenger replyTo) throws RemoteException {
79 | Message msg = Message.obtain(null, ServerService.MSG_START_SERVER);
80 | msg.replyTo = replyTo;
81 |
82 | this.send(msg);
83 |
84 | Editor edit = Agent.getInstance().getSettings().edit();
85 | edit.putBoolean("localServerEnabled", true);
86 | edit.commit();
87 |
88 | server.enabled = true;
89 | server.notifyObservers();
90 | }
91 |
92 | public void stopServer(Server server, Messenger replyTo) throws RemoteException {
93 | Message msg = Message.obtain(null, ServerService.MSG_STOP_SERVER);
94 | msg.replyTo = replyTo;
95 |
96 | this.send(msg);
97 |
98 | Editor edit = Agent.getInstance().getSettings().edit();
99 | edit.putBoolean("localServerEnabled", false);
100 | edit.commit();
101 |
102 | server.enabled = false;
103 | server.notifyObservers();
104 | }
105 |
106 | public void unbind(Context context) {
107 | if(this.bound) {
108 | context.unbindService(this);
109 | this.bound = false;
110 | }
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/service_connectors/SessionServiceConnection.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.service_connectors;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Context;
5 | import android.content.ServiceConnection;
6 | import android.os.IBinder;
7 | import android.os.Messenger;
8 | import android.os.RemoteException;
9 |
10 | import com.mwr.dz.services.SessionService;
11 |
12 | public class SessionServiceConnection implements ServiceConnection {
13 |
14 | private Messenger service = null;
15 | private boolean bound = false;
16 |
17 | public boolean isBound() {
18 | return this.bound;
19 | }
20 |
21 | public void notifySessionStarted(String sessionId) {
22 | try {
23 | this.send(android.os.Message.obtain(null, SessionService.MSG_START_SESSION, sessionId));
24 | }
25 | catch(RemoteException e) {}
26 | }
27 |
28 | public void notifySessionStopped(String sessionId) {
29 | try {
30 | this.send(android.os.Message.obtain(null, SessionService.MSG_STOP_SESSION, sessionId));
31 | }
32 | catch(RemoteException e) {}
33 | }
34 |
35 | @Override
36 | public void onServiceConnected(ComponentName className, IBinder service) {
37 | this.service = new Messenger(service);
38 | this.bound = true;
39 | }
40 |
41 | @Override
42 | public void onServiceDisconnected(ComponentName className) {
43 | this.service = null;
44 | this.bound = false;
45 | }
46 |
47 | public void send(android.os.Message msg) throws RemoteException {
48 | this.service.send(msg);
49 | }
50 |
51 | public void unbind(Context context) {
52 | if(this.bound) {
53 | context.unbindService(this);
54 | this.bound = false;
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/services/ConnectorService.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.services;
2 |
3 | import java.lang.ref.WeakReference;
4 | import java.util.ArrayList;
5 |
6 | import com.mwr.jdiesel.api.connectors.Connector;
7 | import com.mwr.jdiesel.api.connectors.Endpoint;
8 | import com.mwr.jdiesel.logger.LogMessage;
9 | import com.mwr.jdiesel.logger.Logger;
10 | import com.mwr.jdiesel.logger.OnLogMessageListener;
11 |
12 | import android.app.Service;
13 | import android.content.Intent;
14 | import android.os.Bundle;
15 | import android.os.Handler;
16 | import android.os.IBinder;
17 | import android.os.Message;
18 | import android.os.Messenger;
19 | import android.os.RemoteException;
20 |
21 | public abstract class ConnectorService extends Service implements OnLogMessageListener {
22 |
23 | public static final int MSG_LOG_MESSAGE = 1;
24 |
25 | /**
26 | * IncomingHandler is used to process all messages received by the
27 | * ConnectorService. It stores a reference to the incoming messenger (if
28 | * applicable) and hands the message off to the implementation for
29 | * processing.
30 | */
31 | private static class IncomingHandler extends Handler {
32 |
33 | private final WeakReference service;
34 |
35 | public IncomingHandler(ConnectorService service) {
36 | this.service = new WeakReference(service);
37 | }
38 |
39 | @Override
40 | public void handleMessage(Message msg) {
41 | Bundle data = msg.getData();
42 | ConnectorService service = this.service.get();
43 |
44 | if(data == null || !data.getBoolean("ctrl:no_cache_messenger"))
45 | service.cacheMessenger(msg.replyTo);
46 |
47 | service.handleMessage(msg);
48 | }
49 |
50 | }
51 |
52 | private final Messenger messenger = new Messenger(new IncomingHandler(this));
53 | private final ArrayList messengers = new ArrayList();
54 | protected static boolean running = false;
55 |
56 | /**
57 | * Broadcasts a bundle of data, as a log message, to every messenger that has
58 | * previously sent us a message.
59 | */
60 | protected void broadcastLogMessageBundle(Bundle data) {
61 | Message message = Message.obtain(null, ConnectorService.MSG_LOG_MESSAGE);
62 | message.setData(data);
63 |
64 | this.sendToAllMessengers(message);
65 | }
66 |
67 | /**
68 | * Stores a reference to a Messenger, if we haven't already stored it.
69 | */
70 | public void cacheMessenger(Messenger messenger) {
71 | if(!this.messengers.contains(messenger))
72 | this.messengers.add(messenger);
73 | }
74 |
75 | /**
76 | * handleMessage() is handed every message that is passed to this service,
77 | * to process and send any replies.
78 | *
79 | * Override in an implementation of Connector service.
80 | */
81 | public abstract void handleMessage(Message msg);
82 |
83 | @Override
84 | public IBinder onBind(Intent intent) {
85 | return this.messenger.getBinder();
86 | }
87 |
88 | @Override
89 | public void onLogMessage(Logger logger, LogMessage message) {
90 | Bundle data = new Bundle();
91 | data.putBundle(Connector.CONNECTOR_LOG_MESSAGE, message.toBundle());
92 |
93 | Connector connector = logger.getOwner();
94 |
95 | if(connector instanceof Endpoint)
96 | data.putInt(Endpoint.ENDPOINT_ID, ((Endpoint)connector).getId());
97 | this.broadcastLogMessageBundle(data);
98 | }
99 |
100 | @Override
101 | public int onStartCommand(Intent intent, int flags, int startId) {
102 | return START_REDELIVER_INTENT;
103 | }
104 |
105 | /**
106 | * Attempt to deliver a Message to all messengers that have previously sent
107 | * a message to this service, without specifying not to cache their handle.
108 | */
109 | protected void sendToAllMessengers(Message msg) {
110 | for(Messenger m : this.messengers) {
111 | try {
112 | m.send(msg);
113 | }
114 | catch(RemoteException e) {}
115 | }
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/services/SessionService.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.services;
2 |
3 | import java.lang.ref.WeakReference;
4 | import java.util.HashSet;
5 |
6 | import android.app.PendingIntent;
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.content.ServiceConnection;
10 | import android.os.Handler;
11 | import android.os.IBinder;
12 | import android.os.Message;
13 | import android.os.Messenger;
14 | import android.widget.RemoteViews;
15 |
16 | import com.mwr.common.android.app.NotifyingService;
17 | import com.mwr.dz.R;
18 | import com.mwr.dz.activities.MainActivity;
19 |
20 | public class SessionService extends NotifyingService {
21 |
22 | public static final int MSG_START_SESSION = 1;
23 | public static final int MSG_STOP_SESSION = 2;
24 |
25 | private final Messenger messenger = new Messenger(new IncomingHandler(this));
26 | private static boolean running = false;
27 | private HashSet sessions = new HashSet();
28 |
29 | static class IncomingHandler extends Handler {
30 |
31 | private final WeakReference service;
32 |
33 | public IncomingHandler(SessionService service) {
34 | this.service = new WeakReference(service);
35 | }
36 |
37 | @Override
38 | public void handleMessage(Message msg) {
39 | SessionService service = this.service.get();
40 | String session_id = (String)msg.obj;
41 |
42 | switch(msg.what) {
43 | case MSG_START_SESSION:
44 | service.add(session_id);
45 |
46 | service.updateNotification();
47 | break;
48 |
49 | case MSG_STOP_SESSION:
50 | service.remove(session_id);
51 |
52 | service.updateNotification();
53 | break;
54 |
55 | default:
56 | super.handleMessage(msg);
57 | }
58 | }
59 |
60 | }
61 |
62 | public void add(String session_id) {
63 | this.sessions.add(session_id);
64 | }
65 |
66 | @Override
67 | public IBinder onBind(Intent arg0) {
68 | return this.messenger.getBinder();
69 | }
70 |
71 | @Override
72 | public void onCreate() {
73 | super.onCreate();
74 |
75 | SessionService.running = true;
76 | }
77 |
78 | @Override
79 | public void onDestroy() {
80 | SessionService.running = false;
81 | }
82 |
83 | @Override
84 | protected void onCreateNotification(RemoteViews view) {
85 | view.setImageViewResource(R.id.cs_notification_icon, R.drawable.ic_notification);
86 | view.setTextViewText(R.id.cs_notification_ticker, getString(R.string.session_connected));
87 | }
88 |
89 | public void remove(String session_id) {
90 | this.sessions.remove(session_id);
91 | }
92 |
93 | public static void startAndBindToService(Context context, ServiceConnection serviceConnection) {
94 | if(!SessionService.running)
95 | context.startService(new Intent(context, SessionService.class));
96 |
97 | Intent intent = new Intent(context, SessionService.class);
98 | context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
99 | }
100 |
101 | private void updateNotification() {
102 | if(!this.sessions.isEmpty())
103 | this.showNotification(this.getString(R.string.app_name), R.layout.notification_session, R.drawable.ic_notification, PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0));
104 | else
105 | this.hideNotification(this.getString(R.string.app_name), R.layout.notification_session);
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/views/CheckListItemView.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.views;
2 |
3 | import com.mwr.dz.R;
4 |
5 | import android.content.Context;
6 | import android.content.res.TypedArray;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.LinearLayout;
11 | import android.widget.TextView;
12 |
13 | public class CheckListItemView extends LinearLayout {
14 |
15 | private TextView label = null;
16 | private ImageView status = null;
17 |
18 | public CheckListItemView(Context context) {
19 | super(context);
20 |
21 | this.setUpView();
22 | }
23 |
24 | public CheckListItemView(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 |
27 | this.setUpView();
28 |
29 | TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CheckListItemView);
30 |
31 | this.setLabel(a.getString(R.styleable.CheckListItemView_text));
32 | this.setStatus(a.getBoolean(R.styleable.CheckListItemView_defaultValue, false));
33 |
34 | a.recycle();
35 | }
36 |
37 | public void setLabel(int resId) {
38 | this.setLabel(this.getContext().getString(resId));
39 | }
40 |
41 | public void setLabel(String text) {
42 | this.label.setText(text);
43 | }
44 |
45 | public void setStatus(boolean status) {
46 | this.status.setImageResource(status ? android.R.drawable.button_onoff_indicator_on : android.R.drawable.button_onoff_indicator_off);
47 | }
48 |
49 | private void setUpView() {
50 | this.addView(View.inflate(this.getContext(), R.layout.check_list_item, null));
51 |
52 | this.label = (TextView)this.findViewById(R.id.check_list_item_label);
53 | this.status = (ImageView)this.findViewById(R.id.check_list_item_status);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/views/ConnectorStatusIndicator.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.views;
2 |
3 | import java.util.Observable;
4 | import java.util.Observer;
5 |
6 | import com.mwr.dz.R;
7 | import com.mwr.jdiesel.api.connectors.Connector;
8 |
9 | import android.content.Context;
10 | import android.graphics.drawable.AnimationDrawable;
11 | import android.util.AttributeSet;
12 | import android.view.Gravity;
13 | import android.widget.ImageView;
14 | import android.widget.LinearLayout;
15 |
16 | public class ConnectorStatusIndicator extends LinearLayout implements Observer {
17 |
18 | private AnimationDrawable animation = null;
19 | private Connector connector_parameters = null;
20 | private ImageView status_image = null;
21 |
22 | public ConnectorStatusIndicator(Context context) {
23 | super(context);
24 |
25 | this.setUpView();
26 | }
27 |
28 | public ConnectorStatusIndicator(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 |
31 | this.setUpView();
32 | }
33 |
34 | public void setConnector(Connector connector_parameters) {
35 | if(this.connector_parameters != null)
36 | this.connector_parameters.deleteObserver(this);
37 |
38 | this.connector_parameters = connector_parameters;
39 |
40 | this.connector_parameters.addObserver(this);
41 | }
42 |
43 | private void setUpView() {
44 | this.animation = (AnimationDrawable)getResources().getDrawable(R.drawable.ic_stat_connecting);
45 |
46 | this.status_image = new ImageView(this.getContext());
47 | this.addView(this.status_image);
48 |
49 | this.setGravity(Gravity.CENTER_VERTICAL);
50 | }
51 |
52 | @Override
53 | public void update(Observable observable, Object data) {
54 | Connector connector_parameters = (Connector)observable;
55 |
56 | switch(connector_parameters.getStatus()) {
57 | case ACTIVE:
58 | this.status_image.setImageDrawable(getResources().getDrawable(R.drawable.ic_stat_active));
59 | break;
60 |
61 | case CONNECTING:
62 | this.status_image.setImageDrawable(this.animation);
63 |
64 | this.status_image.post(new Runnable() {
65 |
66 | @Override
67 | public void run() {
68 | if(animation.isRunning())
69 | animation.stop();
70 |
71 | animation.start();
72 | }
73 |
74 | });
75 | break;
76 |
77 | case OFFLINE:
78 | this.status_image.setImageDrawable(getResources().getDrawable(R.drawable.ic_stat_offline));
79 | break;
80 |
81 | case ONLINE:
82 | this.status_image.setImageDrawable(getResources().getDrawable(R.drawable.ic_stat_online));
83 | break;
84 |
85 | case UNKNOWN:
86 | this.status_image.setImageDrawable(getResources().getDrawable(R.drawable.ic_stat_unknown));
87 | break;
88 |
89 | case UPDATING:
90 | this.status_image.setImageDrawable(getResources().getDrawable(R.drawable.ic_stat_unknown));
91 | break;
92 | }
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/views/EndpointListRowView.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.views;
2 |
3 | import java.util.Observable;
4 | import java.util.Observer;
5 |
6 | import com.mwr.dz.EndpointAdapter;
7 | import com.mwr.dz.R;
8 | import com.mwr.jdiesel.api.connectors.Endpoint;
9 |
10 | import android.content.Context;
11 | import android.util.AttributeSet;
12 | import android.view.View;
13 | import android.widget.CompoundButton;
14 | import android.widget.LinearLayout;
15 | import android.widget.RelativeLayout;
16 | import android.widget.TextView;
17 | import android.widget.ToggleButton;
18 |
19 | public class EndpointListRowView extends LinearLayout implements Observer, CompoundButton.OnCheckedChangeListener, View.OnClickListener {
20 |
21 | private Endpoint endpoint = null;
22 | private TextView endpoint_connection_string_field = null;
23 | private RelativeLayout endpoint_detail_layout = null;
24 | private TextView endpoint_name_field = null;
25 | private ConnectorStatusIndicator endpoint_status_indicator = null;
26 | private ToggleButton endpoint_toggle_button = null;
27 |
28 | private EndpointAdapter.OnEndpointSelectListener endpoint_listener = null;
29 |
30 | private volatile boolean setting_endpoint = false;
31 |
32 | public EndpointListRowView(Context context) {
33 | super(context);
34 |
35 | this.setUpView();
36 | }
37 |
38 | public EndpointListRowView(Context context, AttributeSet attrs) {
39 | super(context, attrs);
40 |
41 | this.setUpView();
42 | }
43 |
44 | public void setEndpoint(Endpoint endpoint) {
45 | if(this.endpoint != null)
46 | this.endpoint.deleteObserver(this);
47 |
48 | this.setting_endpoint = true;
49 | this.endpoint = endpoint;
50 |
51 | this.endpoint_connection_string_field.setText(this.endpoint.toConnectionString());
52 | this.endpoint_name_field.setText(this.endpoint.getName());
53 | this.endpoint_status_indicator.setConnector(this.endpoint);
54 | this.endpoint_toggle_button.setChecked(this.endpoint.isEnabled());
55 | this.setting_endpoint = false;
56 |
57 | this.endpoint.addObserver(this);
58 | }
59 |
60 | public void setEndpointListener(EndpointAdapter.OnEndpointSelectListener endpoint_listener) {
61 | this.endpoint_listener = endpoint_listener;
62 | }
63 |
64 | private void setUpView() {
65 | this.addView(View.inflate(this.getContext(), R.layout.list_view_row_endpoint, null));
66 |
67 | this.endpoint_connection_string_field = (TextView)this.findViewById(R.id.endpoint_connection_string);
68 | this.endpoint_detail_layout = (RelativeLayout)this.findViewById(R.id.list_view_row_endpoint);
69 | this.endpoint_name_field = (TextView)this.findViewById(R.id.endpoint_name);
70 | this.endpoint_status_indicator = (ConnectorStatusIndicator)this.findViewById(R.id.endpoint_status_indicator);
71 | this.endpoint_toggle_button = (ToggleButton)this.findViewById(R.id.endpoint_toggle);
72 |
73 | this.endpoint_detail_layout.setOnClickListener(this);
74 | this.endpoint_toggle_button.setOnCheckedChangeListener(this);
75 | }
76 |
77 | @Override
78 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
79 | if(!this.setting_endpoint && this.endpoint_listener != null)
80 | this.endpoint_listener.onEndpointToggle(this.endpoint, isChecked);
81 | }
82 |
83 | @Override
84 | public void onClick(View v) {
85 | if(this.endpoint_listener != null)
86 | this.endpoint_listener.onEndpointSelect(this.endpoint);
87 | }
88 |
89 | @Override
90 | public void update(Observable observable, Object data) {
91 | this.setEndpoint((Endpoint)observable);
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/views/EndpointListView.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.views;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ListView;
6 |
7 | public class EndpointListView extends ListView {
8 |
9 | public EndpointListView(Context context, AttributeSet attrs) {
10 | super(context, attrs);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/views/ServerListRowView.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.views;
2 |
3 | import java.util.Observable;
4 | import java.util.Observer;
5 |
6 | import android.content.Context;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.CompoundButton.OnCheckedChangeListener;
10 | import android.widget.CompoundButton;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 | import android.widget.ToggleButton;
14 |
15 | import com.mwr.dz.R;
16 | import com.mwr.jdiesel.api.connectors.Server;
17 | import com.mwr.jdiesel.api.connectors.Server.OnChangeListener;
18 |
19 | public class ServerListRowView extends LinearLayout implements Observer, OnCheckedChangeListener {
20 |
21 | public interface OnServerViewListener {
22 |
23 | public void onToggle(boolean toggle);
24 |
25 | }
26 |
27 | private TextView adb_server_port_field = null;
28 | private ConnectorStatusIndicator adb_server_status_indicator = null;
29 | private ToggleButton adb_server_toggle_button = null;
30 | private Server server_parameters = null;
31 |
32 | private OnServerViewListener server_view_listener;
33 |
34 | private volatile boolean setting_server = false;
35 |
36 | public ServerListRowView(Context context) {
37 | super(context);
38 |
39 | this.initView();
40 | }
41 |
42 | public ServerListRowView(Context context, AttributeSet attrs) {
43 | super(context, attrs);
44 |
45 | this.initView();
46 | }
47 |
48 | private void initView() {
49 | this.addView(View.inflate(this.getContext(), R.layout.list_view_row_server, null));
50 |
51 | this.setBackgroundResource(android.R.drawable.list_selector_background);
52 |
53 | this.adb_server_port_field = (TextView)this.findViewById(R.id.adb_server_port);
54 | this.adb_server_status_indicator = (ConnectorStatusIndicator)this.findViewById(R.id.adb_server_status_indicator);
55 | this.adb_server_toggle_button = (ToggleButton)this.findViewById(R.id.adb_server_toggle);
56 |
57 | this.adb_server_toggle_button.setOnCheckedChangeListener(this);
58 | }
59 |
60 | @Override
61 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
62 | if(!this.setting_server)
63 | this.server_view_listener.onToggle(isChecked);
64 | }
65 |
66 | public void setServerParameters(Server server_parameters) {
67 | this.setting_server = true;
68 | this.server_parameters = server_parameters;
69 |
70 | this.adb_server_port_field.setText(Integer.valueOf(this.server_parameters.getPort()).toString());
71 | this.adb_server_status_indicator.setConnector(this.server_parameters);
72 | this.adb_server_toggle_button.setChecked(this.server_parameters.isEnabled());
73 | this.setting_server = false;
74 |
75 | this.server_parameters.setOnChangeListener(new OnChangeListener() {
76 |
77 | @Override
78 | public void onChange(Server parameters) {
79 | ServerListRowView.this.setServerParameters(parameters);
80 | }
81 |
82 | });
83 | this.server_parameters.addObserver(this);
84 | }
85 |
86 | public void setServerViewListener(OnServerViewListener listener) {
87 | this.server_view_listener = listener;
88 | }
89 |
90 | @Override
91 | public void update(Observable observable, Object data) {
92 | this.setServerParameters((Server)observable);
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/views/logger/LogMessageAdapter.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.views.logger;
2 |
3 | import com.mwr.jdiesel.logger.LogMessage;
4 | import com.mwr.jdiesel.logger.Logger;
5 | import com.mwr.jdiesel.logger.OnLogMessageListener;
6 |
7 | import android.content.Context;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.BaseAdapter;
11 |
12 | public class LogMessageAdapter extends BaseAdapter implements OnLogMessageListener {
13 |
14 | private Context context = null;
15 | private Logger logger = null;
16 |
17 | public LogMessageAdapter(Context context, Logger logger) {
18 | this.context = context;
19 | this.logger = logger;
20 |
21 | this.logger.addOnLogMessageListener(this);
22 | }
23 |
24 | @Override
25 | public int getCount() {
26 | return this.logger.getLogMessages().size();
27 | }
28 |
29 | @Override
30 | public Object getItem(int pos) {
31 | return this.logger.getLogMessages().get(pos);
32 | }
33 |
34 | @Override
35 | public long getItemId(int pos) {
36 | return pos;
37 | }
38 |
39 | @Override
40 | public View getView(int pos, View copyView, ViewGroup parent) {
41 | LogMessageRowView view = new LogMessageRowView(this.context);
42 |
43 | view.setLogMessage((LogMessage)this.getItem(pos));
44 |
45 | return view;
46 | }
47 |
48 | @Override
49 | public void onLogMessage(Logger logger, LogMessage message) {
50 | this.notifyDataSetChanged();
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/agent/src/main/java/com/mwr/dz/views/logger/LogMessageRowView.java:
--------------------------------------------------------------------------------
1 | package com.mwr.dz.views.logger;
2 |
3 | import com.mwr.dz.R;
4 | import com.mwr.jdiesel.logger.LogMessage;
5 |
6 | import android.content.Context;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.LinearLayout;
10 | import android.widget.TextView;
11 |
12 | public class LogMessageRowView extends LinearLayout {
13 |
14 | private LogMessage message = null;
15 | private TextView message_label = null;
16 | private TextView message_message = null;
17 |
18 | public LogMessageRowView(Context context) {
19 | super(context);
20 |
21 | this.setUpView();
22 | }
23 |
24 | public LogMessageRowView(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 |
27 | this.setUpView();
28 | }
29 |
30 | private void setLevel(int level) {
31 | switch(level) {
32 | case LogMessage.ASSERT:
33 | this.message_label.setText(R.string.log_level_tag_assert);
34 | this.message_label.setBackgroundColor(0xffff0000);
35 | this.message_label.setTextColor(0xffffffff);
36 | break;
37 |
38 | case LogMessage.DEBUG:
39 | this.message_label.setText(R.string.log_level_tag_debug);
40 | this.message_label.setBackgroundColor(0xff00ff00);
41 | this.message_label.setTextColor(0xff000000);
42 | break;
43 |
44 | case LogMessage.ERROR:
45 | this.message_label.setText(R.string.log_level_tag_error);
46 | this.message_label.setBackgroundColor(0xffff0000);
47 | this.message_label.setTextColor(0xffffffff);
48 | break;
49 |
50 | case LogMessage.INFO:
51 | this.message_label.setText(R.string.log_level_tag_info);
52 | break;
53 |
54 | case LogMessage.VERBOSE:
55 | this.message_label.setText(R.string.log_level_tag_verbose);
56 | this.message_label.setBackgroundColor(0xff00ff00);
57 | this.message_label.setTextColor(0xff000000);
58 | break;
59 |
60 | case LogMessage.WARN:
61 | this.message_label.setText(R.string.log_level_tag_warn);
62 | this.message_label.setBackgroundColor(0xffffa500);
63 | this.message_label.setTextColor(0xff000000);
64 | break;
65 |
66 | default:
67 | this.message_label.setText(R.string.log_level_tag_unknown);
68 | break;
69 | }
70 | }
71 |
72 | public void setLogMessage(LogMessage message) {
73 | this.message = message;
74 |
75 | this.setLevel(this.message.getLevel());
76 | this.message_message.setText(this.message.getMessage());
77 | }
78 |
79 | private void setUpView() {
80 | this.addView(View.inflate(this.getContext(), R.layout.list_view_row_log_message, null));
81 |
82 | this.message_label = (TextView)this.findViewById(R.id.log_message_level);
83 | this.message_message = (TextView)this.findViewById(R.id.log_message_message);
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/drozer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/drozer.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_action_delete.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_action_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_action_edit.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_action_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_action_new.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_action_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_action_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_action_refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_action_refresh.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_action_search.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_action_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_action_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_input_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_input_add.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_notification.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_stat_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_stat_active.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_stat_offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_stat_offline.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_stat_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_stat_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-hdpi/ic_stat_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-hdpi/ic_stat_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_action_delete.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_action_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_action_edit.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_action_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_action_new.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_action_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_action_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_action_refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_action_refresh.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_action_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_action_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_input_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_input_add.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_stat_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_stat_active.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_stat_offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_stat_offline.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_stat_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_stat_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-ldpi/ic_stat_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-ldpi/ic_stat_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_action_delete.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_action_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_action_edit.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_action_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_action_new.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_action_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_action_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_action_refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_action_refresh.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_action_search.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_action_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_action_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_input_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_input_add.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_notification.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_stat_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_stat_active.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_stat_offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_stat_offline.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_stat_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_stat_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-mdpi/ic_stat_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-mdpi/ic_stat_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_action_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_action_delete.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_action_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_action_edit.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_action_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_action_new.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_action_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_action_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_action_refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_action_refresh.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_action_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_action_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_input_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_input_add.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_notification.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_stat_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_stat_active.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_stat_offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_stat_offline.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_stat_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_stat_online.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable-xhdpi/ic_stat_unknown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/drawable-xhdpi/ic_stat_unknown.png
--------------------------------------------------------------------------------
/agent/src/main/res/drawable/ic_stat_connecting.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout-land/activity_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
16 |
17 |
23 |
24 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout-v14/toggle_endpoint.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout-v14/toggle_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
20 |
21 |
30 |
31 |
41 |
42 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/activity_endpoint.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
18 |
19 |
20 |
21 |
31 |
38 |
45 |
52 |
59 |
66 |
67 |
77 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/activity_endpoint_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
16 |
17 |
24 |
25 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/activity_server.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
17 |
18 |
19 |
20 |
30 |
37 |
44 |
51 |
58 |
65 |
66 |
76 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/check_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
18 |
19 |
20 |
21 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/list_view_row_endpoint.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
25 |
33 |
34 |
42 |
43 |
44 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/list_view_row_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
27 |
28 |
36 |
37 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/notification_session.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
17 |
23 |
31 |
32 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/toggle_endpoint.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/agent/src/main/res/layout/toggle_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/agent/src/main/res/menu/activity_connector.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
--------------------------------------------------------------------------------
/agent/src/main/res/menu/activity_endpoint_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/agent/src/main/res/menu/activity_main.xml:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/agent/src/main/res/raw/agent.bks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/raw/agent.bks
--------------------------------------------------------------------------------
/agent/src/main/res/raw/ca.bks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/agent/src/main/res/raw/ca.bks
--------------------------------------------------------------------------------
/agent/src/main/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/agent/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/agent/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/agent/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/agent/src/main/res/xml/endpoint_headers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/agent/src/main/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
14 |
17 |
23 |
28 |
33 |
39 |
45 |
51 |
52 |
55 |
56 |
59 |
63 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:4.0.1'
9 | classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.12'
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | google()
16 | jcenter()
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 30 15:22:47 BST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/jdiesel/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 |
3 | add_library( mstring
4 | SHARED
5 | src/main/cpp/libmstring/mstring.cpp)
6 |
7 | target_link_libraries(mstring
8 | android
9 | log)
--------------------------------------------------------------------------------
/jdiesel/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.google.protobuf'
3 |
4 | android {
5 | compileSdkVersion 29
6 | buildToolsVersion "29.0.3"
7 | ndkVersion '21.3.6528147'
8 |
9 | defaultConfig {
10 | minSdkVersion 7
11 | targetSdkVersion 29
12 | }
13 |
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
18 | }
19 | }
20 | externalNativeBuild {
21 | cmake {
22 | path 'CMakeLists.txt'
23 | }
24 | }
25 |
26 | sourceSets {
27 | main {
28 | proto {
29 | srcDir 'src/main/proto'
30 | }
31 | java {
32 | srcDir 'src/main/java'
33 | }
34 | }
35 | }
36 | }
37 |
38 | dependencies {
39 | compile project(':mwrtls')
40 | compile files('lib/protobuf-java-2.6.1.jar')
41 | }
42 |
43 | protobuf {
44 | generateProtoTasks {
45 | all().each { task ->
46 | task.builtins {
47 | java { }
48 | }
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/jdiesel/lib/protobuf-java-2.6.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LeadroyaL/drozer-agent/387e478d81dfdf834c13d4178b0f4ab2e49da10a/jdiesel/lib/protobuf-java-2.6.1.jar
--------------------------------------------------------------------------------
/jdiesel/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/jdiesel/src/main/cpp/libmstring/mstring.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * mstring.cpp
3 | * Buffered String Search.
4 | *
5 | * Written by Rodrigo Chiossi
6 | *
7 | *
8 | * This is a native implementation of a buffered string search algorithm,
9 | * optimized to reduce the overhead of the JNI call.
10 | *
11 | * The number of strings found is usually very big which makes it impossible
12 | * return a list of jstrings objects back to java (due to the restriction of
13 | * 512 local references) without paying the price of DeleteLocalRef().
14 | *
15 | * This implementation creates a single Java string with all strings separated
16 | * by a new line. An actual list can be then retrieved in Java using
17 | * split("\n"), or any method alike.
18 | *
19 | * The chunk size was obtained by profiling the execution time over several
20 | * classes.dex extracted from apks. The best observed value was 16k.
21 | */
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "mercury-native", __VA_ARGS__)
30 |
31 | #ifdef __cplusplus
32 | extern "C" {
33 | #endif
34 |
35 | #define CHUNK_SIZE 16348
36 | #define LIST_START_SIZE 4096
37 |
38 | #define MAX_STR_SIZE 4096
39 | #define MIN_STR_SIZE 4
40 |
41 | char read_buffer[CHUNK_SIZE];
42 | unsigned bytes_in_buffer;
43 | unsigned read_ptr;
44 | unsigned eof;
45 |
46 | char* string_list = NULL;
47 |
48 | /*
49 | * Function: Read a new chunk from the target file
50 | * Parameters: file - open file descriptor to the target
51 | */
52 | void reset_buffer(FILE* file) {
53 | bytes_in_buffer = fread(read_buffer,1,CHUNK_SIZE,file);
54 | read_ptr = 0;
55 | eof = 0;
56 | }
57 |
58 | /*
59 | * Function: Read a byte from the file buffer
60 | * Parameters: file - open file descriptor to the target
61 | * Return: Byte read
62 | */
63 | char read_char(FILE* file) {
64 | if (bytes_in_buffer != CHUNK_SIZE && read_ptr >= bytes_in_buffer) {
65 | eof = 1;
66 | return 0xff;
67 | }
68 |
69 | if (read_ptr == CHUNK_SIZE) {
70 | reset_buffer(file);
71 | }
72 |
73 | return read_buffer[read_ptr++];
74 | }
75 |
76 | /*
77 | * Function: Extract Strings from file
78 | * Parameters: path - taget file
79 | * Return: Number of uris found
80 | */
81 | int strings_file(const char* path) {
82 | FILE* file = fopen(path,"r");
83 |
84 | unsigned max_size = LIST_START_SIZE;
85 | unsigned cur_size = 0;
86 |
87 | char buffer[MAX_STR_SIZE];
88 | char* next_str;
89 | unsigned char c_byte;
90 | unsigned length;
91 |
92 | unsigned num_strings = 0;
93 |
94 | if (file == NULL) {
95 | LOGE("Error opening file : %s",path);
96 | return -1;
97 | }
98 |
99 | string_list = (char*) malloc(sizeof(char)*max_size);
100 |
101 | reset_buffer(file);
102 |
103 | c_byte = read_char(file);
104 | length = 0;
105 | while (!eof) {
106 | /* check if character is printable */
107 | while (0x20 <= c_byte && c_byte <= 0x7E && length < MAX_STR_SIZE - 1 && !eof) {
108 | buffer[length++] = c_byte;
109 | c_byte = read_char(file);
110 | }
111 |
112 | if (length >= MIN_STR_SIZE) {
113 | /* grow string list buffer if needed */
114 | if (cur_size+length >= max_size) {
115 | string_list = (char*) realloc(string_list, sizeof(char)*max_size*2);
116 | if (string_list == NULL) {
117 | LOGE("Error: Failed to allocate memory!");
118 | return -1;
119 | }
120 | max_size *= 2;
121 | }
122 |
123 | next_str = &string_list[cur_size];
124 | strncpy(next_str,buffer,length);
125 | next_str[length] = '\n';
126 |
127 | cur_size+=length+1;
128 |
129 | num_strings++;
130 | }
131 |
132 | /* start a new string */
133 | length = 0;
134 |
135 | c_byte = read_char(file);
136 | }
137 |
138 | string_list[cur_size] = '\0';
139 |
140 | fclose(file);
141 |
142 | return num_strings;
143 | }
144 |
145 | /*
146 | * Class: com_mwr_droidhg_util_Strings
147 | * Method: strings
148 | * Signature: (Ljava/lang/String;)[Ljava/lang/String;
149 | */
150 | JNIEXPORT jstring JNICALL Java_com_mwr_jdiesel_util_Strings_get
151 | (JNIEnv *env, jclass obj, jstring jpath)
152 | {
153 | const char *path = env->GetStringUTFChars(jpath, 0);
154 | int num;
155 |
156 | /* Get string list */
157 | num = strings_file(path);
158 |
159 | if (num <= 0) return NULL;
160 |
161 | /* Convert to a Java String */
162 | env->ReleaseStringUTFChars(jpath, path);
163 | jstring ret = env->NewStringUTF(string_list);
164 |
165 | free(string_list);
166 |
167 | return ret;
168 | }
169 |
170 | #ifdef __cplusplus
171 | }
172 | #endif
173 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/APIVersionException.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api;
2 |
3 | public class APIVersionException extends Exception {
4 |
5 | private static final long serialVersionUID = 6223917687313162316L;
6 |
7 | public APIVersionException(String message) {
8 | super(message);
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/DeviceInfo.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api;
2 |
3 | public class DeviceInfo {
4 |
5 | private String android_id;
6 | private String manufacturer;
7 | private String model;
8 | private String software;
9 |
10 | public DeviceInfo(String android_id, String manufacturer, String model, String software) {
11 | this.android_id = android_id;
12 | this.manufacturer = manufacturer;
13 | this.model = model;
14 | this.software = software;
15 | }
16 |
17 | public String getAndroidID() {
18 | return this.android_id;
19 | }
20 |
21 | public String getManufacturer() {
22 | return this.manufacturer;
23 | }
24 |
25 | public String getModel() {
26 | return this.model;
27 | }
28 |
29 | public String getSoftware() {
30 | return this.software;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/Frame.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.nio.ByteBuffer;
6 |
7 | import com.mwr.jdiesel.api.Protobuf.Message;
8 |
9 | public class Frame {
10 |
11 | private static final int SIZE_SIZE = 4; // bytes
12 | private static final int VERSION_SIZE = 4; // bytes
13 | private static final int HEADER_SIZE = VERSION_SIZE + SIZE_SIZE;
14 |
15 | private static final int VERSION = 2;
16 |
17 | private int version;
18 | private Message payload;
19 | private int size;
20 |
21 | public Frame(Message payload) {
22 | this.version = VERSION;
23 | this.setPayload(payload);
24 | }
25 |
26 | public Frame(int version, Message payload) {
27 | this.version = version;
28 | this.setPayload(payload);
29 | }
30 |
31 | public Message getPayload() {
32 | return this.payload;
33 | }
34 |
35 | public int getSize() {
36 | return this.size;
37 | }
38 |
39 | public int getVersion() {
40 | return this.version;
41 | }
42 |
43 | public static Frame readFrom(InputStream in) throws IOException, APIVersionException {
44 | byte[] bytes = new byte[HEADER_SIZE];
45 | int length = in.read(bytes);
46 |
47 | if(length == -1)
48 | throw new IOException("invalid input stream");
49 | else if(length != HEADER_SIZE)
50 | return null;
51 |
52 | ByteBuffer buf = ByteBuffer.wrap(bytes);
53 |
54 | int version = buf.getInt();
55 | int size = buf.getInt();
56 |
57 | if(version != VERSION)
58 | throw new APIVersionException("expected version " + VERSION + ", got " + version);
59 |
60 | byte[] message = new byte[size];
61 |
62 | int bytes_read = 0;
63 | while(bytes_read < size)
64 | bytes_read += in.read(message, bytes_read, size - bytes_read);
65 |
66 | return new Frame(version, Message.parseFrom(message));
67 | }
68 |
69 | private void setPayload(Message payload) {
70 | this.payload = payload;
71 | this.size = payload.toByteArray().length;
72 | }
73 |
74 | public byte[] toByteArray() {
75 | byte[] bytes = new byte[HEADER_SIZE + this.getSize()];
76 |
77 | ByteBuffer buf = ByteBuffer.wrap(bytes);
78 |
79 | buf.putInt(this.getVersion());
80 | buf.putInt(this.getSize());
81 | buf.put(this.payload.toByteArray());
82 |
83 | return bytes;
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/InvalidMessageException.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api;
2 |
3 | import java.util.Locale;
4 |
5 | import com.mwr.jdiesel.api.Protobuf.Message;
6 |
7 | public class InvalidMessageException extends RuntimeException {
8 |
9 | private Message invalid_message = null;
10 | private static final long serialVersionUID = -3727783632022708351L;
11 |
12 | public InvalidMessageException(Message invalid_message) {
13 | this.invalid_message = invalid_message;
14 | }
15 |
16 | public Message getInvalidMessage() {
17 | return this.invalid_message;
18 | }
19 |
20 | public String toString() {
21 | return String.format(Locale.ENGLISH, "Invalid message: %s", this.invalid_message.toString());
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/UnexpectedMessageException.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api;
2 |
3 | import java.util.Locale;
4 |
5 | import com.mwr.jdiesel.api.Protobuf.Message.MessageType;
6 |
7 | public class UnexpectedMessageException extends RuntimeException {
8 |
9 | private static final long serialVersionUID = 2323712339351270587L;
10 |
11 | private MessageType type;
12 |
13 | public UnexpectedMessageException(MessageType type) {
14 | this.type = type;
15 | }
16 |
17 | public String toString() {
18 | return String.format(Locale.ENGLISH, "Unexpected MessageType: %d", this.type.getNumber());
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/builders/MessageFactory.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.builders;
2 |
3 | import com.mwr.jdiesel.api.Protobuf.Message;
4 | import com.mwr.jdiesel.api.Protobuf.Message.ReflectionRequest;
5 | import com.mwr.jdiesel.api.Protobuf.Message.ReflectionResponse;
6 | import com.mwr.jdiesel.api.Protobuf.Message.SystemRequest;
7 | import com.mwr.jdiesel.api.Protobuf.Message.SystemResponse;
8 |
9 | public class MessageFactory {
10 |
11 | Message.Builder builder = null;
12 |
13 | public MessageFactory(ReflectionRequest reflection_request) {
14 | this.builder = Message.newBuilder();
15 |
16 | this.builder.setType(Message.MessageType.REFLECTION_REQUEST);
17 | this.builder.setReflectionRequest(reflection_request);
18 | }
19 |
20 | public MessageFactory(ReflectionResponse reflection_response) {
21 | this.builder = Message.newBuilder();
22 |
23 | this.builder.setType(Message.MessageType.REFLECTION_RESPONSE);
24 | this.builder.setReflectionResponse(reflection_response);
25 | }
26 |
27 | public MessageFactory(ReflectionResponseFactory reflection_response) {
28 | this(reflection_response.build());
29 | }
30 |
31 | public MessageFactory(SystemRequest system_request) {
32 | this.builder = Message.newBuilder();
33 |
34 | this.builder.setType(Message.MessageType.SYSTEM_REQUEST);
35 | this.builder.setSystemRequest(system_request);
36 | }
37 |
38 | public MessageFactory(SystemRequestFactory system_request) {
39 | this(system_request.build());
40 | }
41 |
42 | public MessageFactory(SystemResponse system_response) {
43 | this.builder = Message.newBuilder();
44 |
45 | this.builder.setType(Message.MessageType.SYSTEM_RESPONSE);
46 | this.builder.setSystemResponse(system_response);
47 | }
48 |
49 | public MessageFactory(SystemResponseFactory system_response) {
50 | this(system_response.build());
51 | }
52 |
53 | public Message build() {
54 | return this.builder.build();
55 | }
56 |
57 | public MessageFactory inReplyTo(Message message) {
58 | this.builder.setId(message.getId());
59 |
60 | return this;
61 | }
62 |
63 | public MessageFactory setId(int id) {
64 | this.builder.setId(id);
65 |
66 | return this;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/builders/SystemRequestFactory.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.builders;
2 |
3 | import com.mwr.jdiesel.api.Protobuf.Message;
4 | import com.mwr.jdiesel.api.Protobuf.Message.SystemRequest;
5 |
6 | public class SystemRequestFactory {
7 |
8 | private SystemRequest.Builder builder = null;
9 |
10 | public static SystemRequestFactory bind() {
11 | return new SystemRequestFactory(SystemRequest.RequestType.BIND_DEVICE);
12 | }
13 |
14 | public static SystemRequestFactory unbind() {
15 | return new SystemRequestFactory(SystemRequest.RequestType.UNBIND_DEVICE);
16 | }
17 |
18 | private SystemRequestFactory(SystemRequest.RequestType type) {
19 | this.builder = SystemRequest.newBuilder().setType(type);
20 | }
21 |
22 | public SystemRequest build() {
23 | return this.builder.build();
24 | }
25 |
26 | public SystemRequestFactory setDevice(String device_id, String manufacturer, String model, String software) {
27 | this.builder.setDevice(Message.Device.newBuilder()
28 | .setId(device_id)
29 | .setManufacturer(manufacturer)
30 | .setModel(model)
31 | .setSoftware(software));
32 |
33 | return this;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/builders/SystemResponseFactory.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.builders;
2 |
3 | import com.mwr.jdiesel.api.Protobuf.Message;
4 | import com.mwr.jdiesel.api.Protobuf.Message.SystemResponse;
5 |
6 | public class SystemResponseFactory {
7 |
8 | private SystemResponse.Builder builder = null;
9 |
10 | public static SystemResponseFactory deviceList(Message request) {
11 | return new SystemResponseFactory(SystemResponse.ResponseType.DEVICE_LIST, SystemResponse.ResponseStatus.SUCCESS);
12 | }
13 |
14 | public static SystemResponseFactory pong(Message ping) {
15 | return new SystemResponseFactory(SystemResponse.ResponseType.PONG, SystemResponse.ResponseStatus.SUCCESS);
16 | }
17 |
18 | public static SystemResponseFactory session(String session_id) {
19 | return new SystemResponseFactory(SystemResponse.ResponseType.SESSION_ID, SystemResponse.ResponseStatus.SUCCESS).setSessionId(session_id);
20 | }
21 |
22 | private SystemResponseFactory(SystemResponse.ResponseType type, SystemResponse.ResponseStatus status) {
23 | this.builder = SystemResponse.newBuilder().setType(type).setStatus(status);
24 | }
25 |
26 | public SystemResponseFactory addDevice(String device_id, String manufacturer, String model, String software) {
27 | this.builder.addDevices(Message.Device.newBuilder()
28 | .setId(device_id)
29 | .setManufacturer(manufacturer)
30 | .setModel(model)
31 | .setSoftware(software));
32 |
33 | return this;
34 | }
35 |
36 | public SystemResponse build() {
37 | return this.builder.build();
38 | }
39 |
40 | public SystemResponseFactory isError() {
41 | this.builder.setStatus(SystemResponse.ResponseStatus.ERROR);
42 |
43 | return this;
44 | }
45 |
46 | public SystemResponseFactory isSuccess() {
47 | this.builder.setStatus(SystemResponse.ResponseStatus.SUCCESS);
48 |
49 | return this;
50 | }
51 |
52 | public static SystemResponseFactory sessionList(Message request) {
53 | return new SystemResponseFactory(SystemResponse.ResponseType.SESSION_LIST, SystemResponse.ResponseStatus.SUCCESS);//addDevice();
54 | }
55 |
56 | public SystemResponseFactory setSessionId(String session_id) {
57 | this.builder.setSessionId(session_id);
58 |
59 | return this;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/connectors/Connector.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.connectors;
2 |
3 | import java.util.Observable;
4 |
5 | import com.mwr.jdiesel.logger.Logger;
6 |
7 | public abstract class Connector extends Observable {
8 |
9 | public static final String CONNECTOR_CONNECTED = "connector:connected";
10 | public static final String CONNECTOR_ENABLED = "connector:enabled";
11 | public static final String CONNECTOR_LOG_MESSAGE = "connector:logmessage";
12 | public static final String CONNECTOR_OPEN_SESSIONS = "connector:opensessions";
13 | public static final String CONNECTOR_SSL_FINGERPRINT = "certificate:fingerprint";
14 |
15 | public enum Status { ACTIVE, CONNECTING, UNKNOWN, UPDATING, ONLINE, OFFLINE };
16 |
17 | public volatile boolean enabled = false;
18 | public volatile Status status = Status.UNKNOWN;
19 |
20 | private Logger logger = new Logger(this);
21 |
22 | public synchronized boolean isEnabled() {
23 | return this.enabled;
24 | }
25 |
26 | public Logger getLogger() {
27 | return this.logger;
28 | }
29 |
30 | public synchronized Status getStatus() {
31 | return this.status;
32 | }
33 |
34 | public synchronized void setStatus(Status status) {
35 | if(this.status != status) {
36 | this.status = status;
37 |
38 | this.setChanged();
39 | this.notifyObservers();
40 | }
41 | }
42 |
43 | public abstract boolean verifyPassword(String password);
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/connectors/EndpointSocketFactory.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.connectors;
2 |
3 | import java.io.IOException;
4 | import java.net.InetAddress;
5 | import java.net.Socket;
6 | import java.net.UnknownHostException;
7 | import java.security.KeyManagementException;
8 | import java.security.NoSuchAlgorithmException;
9 | import java.security.SecureRandom;
10 |
11 | import javax.net.ssl.KeyManager;
12 | import javax.net.ssl.SSLContext;
13 | import javax.net.ssl.SSLSocketFactory;
14 | import javax.net.ssl.TrustManager;
15 |
16 |
17 | /**
18 | * The EndpointSocketFactory builds Socket objects from a given Endpoint.
19 | *
20 | * If the given Endpoint has SSL enabled, an SSLSocket will be returned that has
21 | * been initialised with the Endpoint's TrustManager.
22 | */
23 | public class EndpointSocketFactory {
24 |
25 | public Socket createSocket(Endpoint endpoint) throws IOException, KeyManagementException, UnknownHostException {
26 | if(endpoint.isSSL())
27 | return this.createSSLSocket(endpoint.toInetAddress(), endpoint.getPort(), endpoint.getTrustManager());
28 | else
29 | return this.createSocket(endpoint.toInetAddress(), endpoint.getPort());
30 | }
31 |
32 | public Socket createSocket(InetAddress host, int port) throws IOException {
33 | return new Socket(host, port);
34 | }
35 |
36 | public Socket createSSLSocket(InetAddress host, int port, TrustManager trust_manager) throws IOException, KeyManagementException {
37 | try {
38 | SSLContext context = SSLContext.getInstance("TLS");
39 | context.init(new KeyManager[0], new TrustManager[] { trust_manager }, new SecureRandom());
40 |
41 | return ((SSLSocketFactory)context.getSocketFactory()).createSocket(host, port);
42 | }
43 | catch(NoSuchAlgorithmException e) {
44 | throw new RuntimeException("no such algorithm TLS");
45 | }
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/connectors/Server.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.connectors;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.security.KeyStore;
7 | import java.security.cert.CertificateException;
8 | import java.security.KeyStoreException;
9 | import java.security.NoSuchAlgorithmException;
10 | import java.security.UnrecoverableKeyException;
11 |
12 | import javax.net.ssl.KeyManager;
13 | import javax.net.ssl.KeyManagerFactory;
14 |
15 | import android.os.Bundle;
16 |
17 | public class Server extends Connector {
18 |
19 | public static final String SERVER_KEY_PASSWORD = "server:key:password";
20 | public static final String SERVER_KEYSTORE_PASSWORD = "server:ks:password";
21 | public static final String SERVER_KEYSTORE_PATH = "server:ks:path";
22 | public static final String SERVER_PASSWORD = "server:password";
23 | public static final String SERVER_PORT = "server:port";
24 | public static final String SERVER_SSL = "server:ssl";
25 |
26 | public interface OnChangeListener {
27 |
28 | public void onChange(Server parameters);
29 |
30 | }
31 |
32 | public interface OnDetailedStatusListener {
33 |
34 | public void onDetailedStatus(Bundle status);
35 |
36 | }
37 |
38 | private KeyManager[] key_managers = null;
39 | private char[] key_password = null;
40 | private String keystore_path = null;
41 | private char[] keystore_password = null;
42 | private OnChangeListener on_change_listener = null;
43 | private String password = null;
44 | private int port = 31415;
45 | private boolean ssl = false;
46 |
47 | private OnDetailedStatusListener on_detailed_status_listener;
48 |
49 | public Server() {}
50 |
51 | // public Server(int port) {
52 | // this.setPort(port);
53 | // }
54 |
55 | public KeyManager[] getKeyManagers() throws CertificateException, FileNotFoundException, IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
56 | if (this.key_managers == null) {
57 | KeyStore key_store = KeyStore.getInstance("BKS");
58 | key_store.load(new FileInputStream(this.keystore_path), this.keystore_password);
59 |
60 | KeyManagerFactory key_manager_factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
61 | key_manager_factory.init(key_store, this.key_password);
62 |
63 | this.key_managers = key_manager_factory.getKeyManagers();
64 | }
65 |
66 | return this.key_managers;
67 | }
68 |
69 | public String getPassword() {
70 | return this.password;
71 | }
72 |
73 | public int getPort() {
74 | return this.port;
75 | }
76 |
77 | public boolean hasPassword() {
78 | return this.password != null && this.password != "";
79 | }
80 |
81 | public boolean isSSL() {
82 | return this.ssl;
83 | }
84 |
85 | public void resetKeyManagerFactory() {
86 | this.key_managers = null;
87 | }
88 |
89 | public void setDetailedStatus(Bundle status) {
90 | if(this.on_detailed_status_listener != null)
91 | this.on_detailed_status_listener.onDetailedStatus(status);
92 | }
93 |
94 | public void setKeyPassword(char[] password) {
95 | this.key_password = password;
96 | }
97 |
98 | public void setKeyStorePassword(char[] password) {
99 | this.keystore_password = password;
100 | }
101 |
102 | public void setKeyStorePath(String path) {
103 | this.keystore_path = path;
104 | }
105 |
106 | public void setOnChangeListener(OnChangeListener listener) {
107 | this.on_change_listener = listener;
108 | }
109 |
110 | public void setOnDetailedStatusListener(OnDetailedStatusListener listener) {
111 | this.on_detailed_status_listener = listener;
112 | }
113 |
114 | public void setPassword(String password) {
115 | this.password = password;
116 |
117 | if(this.on_change_listener != null)
118 | this.on_change_listener.onChange(this);
119 | }
120 |
121 | public void setPort(int port) {
122 | this.port = port;
123 |
124 | if(this.on_change_listener != null)
125 | this.on_change_listener.onChange(this);
126 | }
127 |
128 | public void setSSL(boolean ssl) {
129 | this.ssl = ssl;
130 |
131 | if(this.on_change_listener != null)
132 | this.on_change_listener.onChange(this);
133 | }
134 |
135 | @Override
136 | public boolean verifyPassword(String password) {
137 | return this.getPassword() == null && (password == null || password.equals("")) || password.equals(this.getPassword());
138 | }
139 |
140 | }
141 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/connectors/ServerSocketFactory.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.connectors;
2 |
3 | import java.io.IOException;
4 | import java.net.ServerSocket;
5 | import java.security.KeyManagementException;
6 | import java.security.KeyStoreException;
7 | import java.security.NoSuchAlgorithmException;
8 | import java.security.UnrecoverableKeyException;
9 | import java.security.cert.CertificateException;
10 |
11 | import javax.net.ssl.SSLContext;
12 | import javax.net.ssl.SSLServerSocket;
13 |
14 |
15 | public class ServerSocketFactory {
16 |
17 | public ServerSocket createSocket(Server server) throws CertificateException, IOException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
18 | if(server.isSSL())
19 | return this.createSSLSocket(server);
20 | else
21 | return new ServerSocket(server.getPort());
22 | }
23 |
24 | public SSLServerSocket createSSLSocket(Server server) throws CertificateException, IOException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
25 | try {
26 | SSLContext context = SSLContext.getInstance("TLS");
27 | context.init(server.getKeyManagers(), null, null);
28 |
29 | return (SSLServerSocket) context.getServerSocketFactory().createServerSocket(server.getPort());
30 | }
31 | catch(NoSuchAlgorithmException e) {
32 | throw new RuntimeException("no such algorithm TLS");
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/handlers/FileTransformMessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.handlers;
2 |
3 | import com.google.protobuf.ByteString;
4 | import com.mwr.jdiesel.api.InvalidMessageException;
5 | import com.mwr.jdiesel.api.Protobuf;
6 | import com.mwr.jdiesel.api.sessions.Session;
7 |
8 | import java.io.FileInputStream;
9 | import java.io.FileOutputStream;
10 |
11 | public class FileTransformMessageHandler implements MessageHandler {
12 | private Session session = null;
13 |
14 | public FileTransformMessageHandler(Session session) {
15 | this.session = session;
16 | }
17 |
18 | @Override
19 | public Protobuf.Message handle(Protobuf.Message message) throws InvalidMessageException {
20 | if (message.getType() != Protobuf.Message.MessageType.FILE_TRANSFORM_REQUEST)
21 | throw new InvalidMessageException(message);
22 | if (!message.hasFileTransformRequest())
23 | throw new InvalidMessageException(message);
24 | if (!message.getFileTransformRequest().hasRemoteFilename())
25 | throw new InvalidMessageException(message);
26 |
27 | Protobuf.Message.FileTransformRequest req = message.getFileTransformRequest();
28 | boolean upload = req.getUpload();
29 |
30 | Protobuf.Message.FileTransformResponse.Builder resp = Protobuf.Message.FileTransformResponse.newBuilder();
31 | resp.setSessionId(session.getSessionId());
32 | resp.setSuccess(true);
33 | if (upload) {
34 | if (!req.hasData())
35 | throw new InvalidMessageException(message);
36 |
37 | String remoteFileName = req.getRemoteFilename();
38 | byte[] data = req.getData().toByteArray();
39 |
40 | try {
41 | FileOutputStream outputStream = new FileOutputStream(remoteFileName);
42 | outputStream.write(data);
43 | outputStream.close();
44 | } catch (Exception e) {
45 | resp.setSuccess(false);
46 | }
47 | } else {
48 | String remoteFileName = message.getFileTransformRequest().getRemoteFilename();
49 |
50 | try {
51 | FileInputStream inputStream = new FileInputStream(remoteFileName);
52 | byte[] data = new byte[inputStream.available()];
53 | inputStream.read(data);
54 | inputStream.close();
55 | resp.setData(ByteString.copyFrom(data));
56 | } catch (Exception e) {
57 | resp.setSuccess(false);
58 | }
59 | }
60 | return Protobuf.Message.newBuilder()
61 | .setId(message.getId())
62 | .setType(Protobuf.Message.MessageType.FILE_TRANSFORM_RESPONSE)
63 | .setFileTransformResponse(resp)
64 | .build();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/handlers/MessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.handlers;
2 |
3 | import com.mwr.jdiesel.api.InvalidMessageException;
4 | import com.mwr.jdiesel.api.Protobuf.Message;
5 |
6 | public interface MessageHandler {
7 |
8 | public Message handle(Message message) throws InvalidMessageException;
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/handlers/SystemMessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.handlers;
2 |
3 | import com.mwr.jdiesel.api.DeviceInfo;
4 | import com.mwr.jdiesel.api.InvalidMessageException;
5 | import com.mwr.jdiesel.api.Protobuf.Message;
6 | import com.mwr.jdiesel.api.builders.MessageFactory;
7 | import com.mwr.jdiesel.api.builders.SystemResponseFactory;
8 | import com.mwr.jdiesel.api.connectors.Connection;
9 | import com.mwr.jdiesel.api.sessions.Session;
10 |
11 | public class SystemMessageHandler implements MessageHandler {
12 |
13 | private Connection connection = null;
14 | private DeviceInfo device_info;
15 |
16 | public SystemMessageHandler(Connection connection, DeviceInfo device_info) {
17 | this.connection = connection;
18 | this.device_info = device_info;
19 | }
20 |
21 | @Override
22 | public Message handle(Message message) throws InvalidMessageException {
23 | if(message.getType() != Message.MessageType.SYSTEM_REQUEST)
24 | throw new InvalidMessageException(message);
25 | if(!message.hasSystemRequest())
26 | throw new InvalidMessageException(message);
27 |
28 | switch(message.getSystemRequest().getType()) {
29 | case LIST_DEVICES:
30 | return this.handleListDevices(message);
31 |
32 | case LIST_SESSIONS:
33 | return this.handleListSessions(message);
34 |
35 | case PING:
36 | return this.handlePing(message);
37 |
38 | case START_SESSION:
39 | return this.startSession(message);
40 |
41 | case STOP_SESSION:
42 | return this.stopSession(message);
43 |
44 | default:
45 | throw new InvalidMessageException(message);
46 | }
47 | }
48 |
49 | protected Message handleListDevices(Message message) throws InvalidMessageException {
50 | MessageFactory factory = new MessageFactory(SystemResponseFactory.deviceList(message).addDevice(
51 | this.device_info.getAndroidID(),
52 | this.device_info.getManufacturer(),
53 | this.device_info.getModel(),
54 | this.device_info.getSoftware()));
55 |
56 | factory.inReplyTo(message);
57 |
58 | return factory.build();
59 | }
60 |
61 | protected Message handleListSessions(Message message) throws InvalidMessageException {
62 | SystemResponseFactory response = SystemResponseFactory.sessionList(message);
63 |
64 | //for(Session session : this.connection.getSessions())
65 | // response.addSession(session);
66 |
67 | MessageFactory factory = new MessageFactory(response);
68 |
69 | factory.inReplyTo(message);
70 |
71 | return factory.build();
72 | }
73 |
74 | protected Message handlePing(Message message) throws InvalidMessageException {
75 | MessageFactory factory = new MessageFactory(SystemResponseFactory.pong(message));
76 |
77 | factory.inReplyTo(message);
78 |
79 | return factory.build();
80 | }
81 |
82 | protected Message startSession(Message message) throws InvalidMessageException {
83 | Session session = (Session)this.connection.startSession(message.getSystemRequest().getPassword());
84 |
85 | if(session != null) {
86 | MessageFactory factory = new MessageFactory(SystemResponseFactory.session(session.getSessionId()));
87 |
88 | factory.inReplyTo(message);
89 |
90 | return factory.build();
91 | }
92 | else {
93 | MessageFactory factory = new MessageFactory(SystemResponseFactory.session(Session.nullSession().getSessionId()).isError());
94 |
95 | factory.inReplyTo(message);
96 |
97 | return factory.build();
98 | }
99 | }
100 |
101 | protected Message stopSession(Message message) throws InvalidMessageException {
102 | Session session = (Session)this.connection.stopSession(message.getSystemRequest().getSessionId());
103 |
104 | if(session != null) {
105 | MessageFactory factory = new MessageFactory(SystemResponseFactory.session(session.getSessionId()));
106 |
107 | factory.inReplyTo(message);
108 |
109 | return factory.build();
110 | }
111 | else {
112 | MessageFactory factory = new MessageFactory(SystemResponseFactory.session(Session.nullSession().getSessionId()).isError());
113 |
114 | factory.inReplyTo(message);
115 |
116 | return factory.build();
117 | }
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/links/Client.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.links;
2 |
3 | import java.io.IOException;
4 | import java.net.Socket;
5 | import java.net.UnknownHostException;
6 | import java.security.KeyManagementException;
7 |
8 | import com.mwr.jdiesel.api.DeviceInfo;
9 | import com.mwr.jdiesel.api.connectors.Endpoint;
10 | import com.mwr.jdiesel.api.connectors.EndpointSocketFactory;
11 | import com.mwr.jdiesel.api.connectors.Connector.Status;
12 | import com.mwr.jdiesel.api.transport.SocketTransport;
13 | import com.mwr.jdiesel.connection.SecureConnection;
14 | import com.mwr.jdiesel.logger.LogMessage;
15 |
16 | public class Client extends Link {
17 |
18 | public static final int RESET_TIMEOUT = 5000;
19 |
20 | public Client(Endpoint endpoint, DeviceInfo device_info) {
21 | super(endpoint, device_info);
22 | }
23 |
24 | public String getHostCertificateFingerprint() {
25 | return ((SecureConnection)this.connection).getHostCertificateFingerprint();
26 | }
27 |
28 | public String getPeerCertificateFingerprint() {
29 | return ((SecureConnection)this.connection).getPeerCertificateFingerprint();
30 | }
31 |
32 | @Override
33 | public void resetConnection() {
34 | this.parameters.setStatus(Endpoint.Status.CONNECTING);
35 |
36 | try {
37 | Thread.sleep(RESET_TIMEOUT);
38 | }
39 | catch(InterruptedException e) {}
40 |
41 | super.resetConnection();
42 | }
43 |
44 | @Override
45 | public void run() {
46 | Endpoint endpoint = (Endpoint)this.parameters;
47 |
48 | this.log(LogMessage.INFO, "Starting...");
49 | this.running = true;
50 |
51 | while(this.running) {
52 | try {
53 | if(this.connection == null) {
54 | this.parameters.setStatus(Endpoint.Status.CONNECTING);
55 |
56 | this.log(LogMessage.INFO, "Attempting connection to " + endpoint.toConnectionString() + "...");
57 | Socket socket = new EndpointSocketFactory().createSocket(endpoint);
58 |
59 | if(socket != null) {
60 | this.log(LogMessage.INFO, "Socket connected.");
61 |
62 | this.log(LogMessage.INFO, "Attempting to start drozer thread...");
63 | this.createConnection(new SocketTransport(socket));
64 | }
65 | }
66 | else {
67 | synchronized(this.connection) {
68 | try {
69 | this.connection.wait();
70 | }
71 | catch(InterruptedException e) {}
72 | catch(IllegalMonitorStateException e){}
73 | }
74 |
75 | if(this.connection.started && !this.connection.running) {
76 | this.log(LogMessage.INFO, "Connection was reset.");
77 |
78 | this.resetConnection();
79 | }
80 | }
81 | }
82 | catch(UnknownHostException e) {
83 | this.log(LogMessage.ERROR, "Unknown Host: " + endpoint.getHost());
84 |
85 | this.stopConnector();
86 | }
87 | catch(IOException e) {
88 | this.log(LogMessage.ERROR, "IO Error. Resetting connection.");
89 | this.log(LogMessage.DEBUG, e.getMessage());
90 |
91 | this.resetConnection();
92 | }
93 | catch(KeyManagementException e) {
94 | this.log(LogMessage.ERROR, "Error loading key material for SSL.");
95 |
96 | this.stopConnector();
97 | }
98 | }
99 |
100 | this.log(LogMessage.INFO, "Stopped.");
101 | }
102 |
103 | @Override
104 | public void setStatus(Status status) {
105 | this.parameters.setStatus(status);
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/links/Link.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.links;
2 |
3 | import android.util.Log;
4 |
5 | import com.mwr.jdiesel.api.DeviceInfo;
6 | import com.mwr.jdiesel.api.connectors.Connection;
7 | import com.mwr.jdiesel.api.connectors.Connector;
8 | import com.mwr.jdiesel.api.sessions.Session;
9 | import com.mwr.jdiesel.api.sessions.SessionCollection;
10 | import com.mwr.jdiesel.api.transport.Transport;
11 | import com.mwr.jdiesel.connection.AbstractLink;
12 | import com.mwr.jdiesel.logger.LogMessage;
13 | import com.mwr.jdiesel.logger.Logger;
14 |
15 |
16 | public abstract class Link extends AbstractLink {
17 |
18 | protected Connector parameters = null;
19 | private DeviceInfo device_info;
20 |
21 | private Logger logger = null;
22 |
23 | public Link(Connector parameters, DeviceInfo device_info) {
24 | this.parameters = parameters;
25 | this.device_info = device_info;
26 |
27 | this.setSessionCollection(new SessionCollection(this));
28 | }
29 |
30 | public abstract void setStatus(Connector.Status status);
31 |
32 | @Override
33 | protected void createConnection(Transport transport) {
34 | if(transport.isLive()) {
35 | this.connection = new Connection(this, this.device_info, transport);
36 | this.connection.start();
37 | }
38 | }
39 |
40 | @Override
41 | public Session getSession(String session_id) {
42 | return (Session)super.getSession(session_id);
43 | }
44 |
45 | public void log(int level, String message) {
46 | if(this.logger != null)
47 | this.logger.log(level, message);
48 | else
49 | Log.i("link", message);
50 | }
51 |
52 | public void log(LogMessage message) {
53 | if(this.logger != null)
54 | this.logger.log(message);
55 | else
56 | Log.i("link", message.getMessage());
57 | }
58 |
59 | public void setLogger(Logger logger) {
60 | this.logger = logger;
61 | }
62 |
63 | public Session startSession(String password) {
64 | if(this.parameters.verifyPassword(password))
65 | return (Session)this.createSession();
66 | else
67 | return null;
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/links/Server.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.links;
2 |
3 | import java.io.IOException;
4 | import java.net.ServerSocket;
5 | import java.net.Socket;
6 | import java.security.KeyManagementException;
7 | import java.security.KeyStoreException;
8 | import java.security.UnrecoverableKeyException;
9 | import java.security.cert.CertificateException;
10 |
11 | import com.mwr.jdiesel.api.DeviceInfo;
12 | import com.mwr.jdiesel.api.connectors.ServerSocketFactory;
13 | import com.mwr.jdiesel.api.connectors.Connector.Status;
14 | import com.mwr.jdiesel.api.transport.SocketTransport;
15 | import com.mwr.jdiesel.connection.SecureConnection;
16 | import com.mwr.jdiesel.logger.LogMessage;
17 |
18 | public class Server extends Link {
19 |
20 | private ServerSocket server_socket = null;
21 |
22 | public Server(com.mwr.jdiesel.api.connectors.Server parameters, DeviceInfo device_info) {
23 | super(parameters, device_info);
24 | }
25 |
26 | @Override
27 | public boolean checkForLiveness() { return false; }
28 |
29 | @Override
30 | public boolean dieWithLastSession() { return true; }
31 |
32 | public String getHostCertificateFingerprint() {
33 | return ((SecureConnection)this.connection).getHostCertificateFingerprint();
34 | }
35 |
36 | public String getPeerCertificateFingerprint() {
37 | return ((SecureConnection)this.connection).getPeerCertificateFingerprint();
38 | }
39 |
40 | @Override
41 | public boolean mustBind() { return false; }
42 |
43 | @Override
44 | public void resetConnection() {
45 | this.parameters.setStatus(com.mwr.jdiesel.api.connectors.Server.Status.CONNECTING);
46 |
47 | Thread.yield();
48 |
49 | if(this.server_socket != null) {
50 | try {
51 | this.server_socket.close();
52 |
53 | this.server_socket = null;
54 | }
55 | catch(IOException e) {}
56 | }
57 |
58 | super.resetConnection();
59 | }
60 |
61 | @Override
62 | public void run() {
63 | this.running = true;
64 |
65 | this.log(LogMessage.INFO, "Starting Server...");
66 | while(this.running) {
67 | try {
68 | if(this.connection == null) {
69 | this.parameters.setStatus(com.mwr.jdiesel.api.connectors.Server.Status.CONNECTING);
70 |
71 | this.log(LogMessage.INFO, "Attempting to bind to port " + ((com.mwr.jdiesel.api.connectors.Server)this.parameters).getPort() + "...");
72 | this.server_socket = new ServerSocketFactory().createSocket((com.mwr.jdiesel.api.connectors.Server)this.parameters);
73 |
74 | this.log(LogMessage.INFO, "Waiting for connections...");
75 | Socket socket = this.server_socket.accept();
76 |
77 | if(socket != null) {
78 | this.parameters.setStatus(com.mwr.jdiesel.api.connectors.Server.Status.ONLINE);
79 |
80 | this.log(LogMessage.INFO, "Accepted connection...");
81 |
82 | this.log(LogMessage.INFO, "Starting drozer thread...");
83 | this.createConnection(new SocketTransport(socket));
84 | }
85 | }
86 | else {
87 | synchronized(this.connection) {
88 | try {
89 | this.connection.wait();
90 | }
91 | catch(InterruptedException e) {}
92 | catch(IllegalMonitorStateException e){}
93 | }
94 | // block until connection == null or connection.started && !connection.running
95 |
96 | if(this.connection.started && !this.connection.running) {
97 | this.log(LogMessage.WARN, "Connection was reset.");
98 |
99 | this.resetConnection();
100 | }
101 | }
102 | }
103 | catch(CertificateException e) {
104 | this.log(LogMessage.ERROR, "Error loading key material for SSL.");
105 |
106 | this.stopConnector();
107 | }
108 | catch(IOException e) {
109 | this.log(LogMessage.ERROR, "IO Error. Resetting connection.");
110 | System.out.println("error: " + e.toString());
111 | this.resetConnection();
112 | }
113 | catch(KeyManagementException e) {
114 | this.log(LogMessage.ERROR, "Error loading key material for SSL.");
115 |
116 | this.stopConnector();
117 | }
118 | catch(KeyStoreException e) {
119 | this.log(LogMessage.ERROR, "Error loading key material for SSL.");
120 |
121 | this.stopConnector();
122 | }
123 | catch(UnrecoverableKeyException e) {
124 | this.log(LogMessage.ERROR, "Error loading key material for SSL.");
125 |
126 | this.stopConnector();
127 | }
128 |
129 | }
130 |
131 | this.log(LogMessage.INFO, "Stopped.");
132 | this.parameters.setStatus(com.mwr.jdiesel.api.connectors.Server.Status.OFFLINE);
133 | }
134 |
135 | @Override
136 | public void setStatus(Status status) {
137 | this.parameters.setStatus(status);
138 | }
139 |
140 | public void stopConnector() {
141 | super.stopConnector();
142 |
143 | try {
144 | if(this.server_socket != null) {
145 | this.server_socket.close();
146 | this.server_socket = null;
147 | }
148 | }
149 | catch(IOException e) {}
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/sessions/Session.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.sessions;
2 |
3 | import android.os.Looper;
4 |
5 | import com.mwr.jdiesel.api.InvalidMessageException;
6 | import com.mwr.jdiesel.api.Protobuf.Message;
7 | import com.mwr.jdiesel.api.handlers.FileTransformMessageHandler;
8 | import com.mwr.jdiesel.api.handlers.MessageHandler;
9 | import com.mwr.jdiesel.api.handlers.ReflectionMessageHandler;
10 | import com.mwr.jdiesel.api.links.Link;
11 | import com.mwr.jdiesel.connection.AbstractSession;
12 | import com.mwr.jdiesel.reflection.ObjectStore;
13 |
14 | public class Session extends AbstractSession {
15 |
16 | private Link connector = null;
17 | public ObjectStore object_store = new ObjectStore();
18 | private MessageHandler reflection_message_handler = new ReflectionMessageHandler(this);
19 | private MessageHandler file_transform_message_handler = new FileTransformMessageHandler(this);
20 |
21 | public Session(Link connector) {
22 | super();
23 |
24 | this.connector = connector;
25 | }
26 |
27 | protected Session(String session_id) {
28 | super(session_id);
29 | }
30 |
31 | public static Session nullSession() {
32 | return new Session("null");
33 | }
34 |
35 | @Override
36 | protected Message handleMessage(Message message) throws InvalidMessageException {
37 | if (message.getType() == Message.MessageType.FILE_TRANSFORM_REQUEST)
38 | return this.file_transform_message_handler.handle(message);
39 | else
40 | return this.reflection_message_handler.handle(message);
41 | }
42 |
43 | @Override
44 | public void run(){
45 | Looper.prepare();
46 |
47 | super.run();
48 | }
49 |
50 | @Override
51 | public void send(Message message) {
52 | this.connector.send(message);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/sessions/SessionCollection.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.sessions;
2 |
3 | import com.mwr.jdiesel.api.connectors.Connector.Status;
4 | import com.mwr.jdiesel.api.links.Link;
5 | import com.mwr.jdiesel.connection.AbstractSession;
6 | import com.mwr.jdiesel.connection.AbstractSessionCollection;
7 |
8 | public class SessionCollection extends AbstractSessionCollection {
9 |
10 | private Link connector = null;
11 | // private SessionServiceConnection session_service_connection = null;
12 |
13 | public SessionCollection(Link connector) {
14 | this.connector = connector;
15 | // this.session_service_connection = new SessionServiceConnection();
16 |
17 | // SessionService.startAndBindToService(Agent.getInstance().getMercuryContext(), this.session_service_connection);
18 | }
19 |
20 | @Override
21 | public Session create() {
22 | return (Session)this.storeSession(new Session(this.connector));
23 | }
24 |
25 | // public SessionServiceConnection getSessionService() {
26 | // return this.session_service_connection;
27 | // }
28 |
29 | @Override
30 | public void onSessionStarted(AbstractSession session) {
31 | this.connector.setStatus(Status.ACTIVE);
32 |
33 | // this.getSessionService().notifySessionStarted(session.getSessionId());
34 | }
35 |
36 | @Override
37 | public void onSessionStopped(AbstractSession session) {
38 | // this.getSessionService().notifySessionStopped(session.getSessionId());
39 | this.connector.setStatus(Status.ONLINE);
40 |
41 | if(!this.any())
42 | this.connector.lastSessionStopped();
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/transport/SecureTransport.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.transport;
2 |
3 | public interface SecureTransport {
4 |
5 | public abstract String getHostCertificateFingerprint();
6 | public abstract String getPeerCertificateFingerprint();
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/transport/SocketTransport.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.transport;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.net.Socket;
7 | import java.security.cert.X509Certificate;
8 |
9 | import javax.net.ssl.SSLPeerUnverifiedException;
10 | import javax.net.ssl.SSLSession;
11 | import javax.net.ssl.SSLSocket;
12 |
13 | import com.mwr.common.tls.X509Fingerprint;
14 |
15 | import android.util.Log;
16 |
17 | public class SocketTransport extends Transport implements SecureTransport {
18 |
19 | private static final int SO_TIMEOUT = 5000; // milliseconds
20 |
21 | private InputStream in = null;
22 | private OutputStream out = null;
23 | private Socket socket = null;
24 |
25 | public SocketTransport(Socket socket) {
26 | try {
27 | this.socket = socket;
28 |
29 | this.socket.setSoTimeout(SO_TIMEOUT);
30 |
31 | this.in = socket.getInputStream();
32 | this.out = socket.getOutputStream();
33 | }
34 | catch(IOException e) {
35 | Log.e("SocketConnection", "IOException when grabbing streams: " + e.getMessage());
36 | }
37 | }
38 |
39 | @Override
40 | public void close() {
41 | try {
42 | this.in.close();
43 | this.out.close();
44 | this.socket.close();
45 | } catch (IOException e) {
46 | Log.e("SocketConnection", "IOException when closing socket: " + e.getMessage());
47 | }
48 | }
49 |
50 | @Override
51 | public String getHostCertificateFingerprint() {
52 | SSLSession session = ((SSLSocket)this.socket).getSession();
53 |
54 | return new X509Fingerprint((X509Certificate)session.getLocalCertificates()[0]).toString();
55 | }
56 |
57 | @Override
58 | protected InputStream getInputStream() throws IOException {
59 | return this.in;
60 | }
61 |
62 | @Override
63 | protected OutputStream getOutputStream() throws IOException {
64 | return this.out;
65 | }
66 |
67 | @Override
68 | public String getPeerCertificateFingerprint() {
69 | try {
70 | SSLSession session = ((SSLSocket)this.socket).getSession();
71 |
72 | return new X509Fingerprint((X509Certificate)session.getPeerCertificates()[0]).toString();
73 | }
74 | catch(SSLPeerUnverifiedException e) {
75 | return "No valid peer certificate";
76 | }
77 | }
78 |
79 | @Override
80 | public boolean isLive() {
81 | return !this.socket.isClosed();
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/transport/Transport.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.transport;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 |
7 | import com.mwr.jdiesel.api.APIVersionException;
8 | import com.mwr.jdiesel.api.Frame;
9 |
10 | public abstract class Transport {
11 |
12 | public abstract void close();
13 | protected abstract InputStream getInputStream() throws IOException;
14 | protected abstract OutputStream getOutputStream() throws IOException;
15 | public abstract boolean isLive();
16 |
17 | public Frame receive() throws APIVersionException, IOException, TransportDisconnectedException {
18 | if(this.getInputStream() != null)
19 | return Frame.readFrom(this.getInputStream());
20 | else
21 | throw new TransportDisconnectedException();
22 | }
23 |
24 | public void send(Frame frame) throws IOException {
25 | this.getOutputStream().write(frame.toByteArray());
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/api/transport/TransportDisconnectedException.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.api.transport;
2 |
3 | public class TransportDisconnectedException extends Exception {
4 |
5 | private static final long serialVersionUID = -8654251407371633543L;
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/connection/AbstractLink.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.connection;
2 |
3 | import com.mwr.jdiesel.api.Protobuf.Message;
4 | import com.mwr.jdiesel.api.transport.Transport;
5 |
6 | public abstract class AbstractLink extends Thread {
7 |
8 | public volatile boolean running = false;
9 | protected volatile AbstractConnection connection = null;
10 | private AbstractSessionCollection sessions;
11 |
12 | public boolean checkForLiveness() { return true; }
13 |
14 | protected abstract void createConnection(Transport transport);
15 |
16 | protected AbstractSession createSession() {
17 | return this.sessions.create();
18 | }
19 |
20 | public boolean dieWithLastSession() { return false; }
21 | public boolean mustBind() { return true; }
22 |
23 | public AbstractSession getSession(String session_id) {
24 | return this.sessions.get(session_id);
25 | }
26 |
27 | public boolean hasSessions() {
28 | return this.sessions.any();
29 | }
30 |
31 | public void lastSessionStopped() {
32 | if(this.dieWithLastSession())
33 | this.stopConnection();
34 | }
35 |
36 | public void send(Message message) {
37 | this.connection.send(message);
38 | }
39 |
40 | public AbstractSession startSession() {
41 | return this.startSession(null);
42 | }
43 |
44 | public abstract AbstractSession startSession(String password);
45 |
46 | public void resetConnection() {
47 | this.connection = null;
48 | }
49 |
50 | protected void setSessionCollection(AbstractSessionCollection sessions) {
51 | this.sessions = sessions;
52 | }
53 |
54 | protected void stopConnection() {
55 | if(this.connection != null)
56 | this.connection.stopConnection();
57 | }
58 |
59 | public void stopConnector() {
60 | this.running = false;
61 |
62 | this.stopConnection();
63 | }
64 |
65 | public AbstractSession stopSession(String session_id) {
66 | return (AbstractSession)this.sessions.stop(session_id);
67 | }
68 |
69 | public void stopSessions() {
70 | this.sessions.stopAll();
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/connection/AbstractSession.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.connection;
2 |
3 | import java.math.BigInteger;
4 | import java.security.SecureRandom;
5 | import java.util.HashSet;
6 | import java.util.Set;
7 | import java.util.concurrent.BlockingQueue;
8 | import java.util.concurrent.LinkedBlockingQueue;
9 |
10 | import com.mwr.jdiesel.api.InvalidMessageException;
11 | import com.mwr.jdiesel.api.Protobuf.Message;
12 |
13 | public abstract class AbstractSession extends Thread {
14 |
15 | public interface OnSessionStatusListener {
16 |
17 | public void onSessionStarted(AbstractSession session);
18 |
19 | public void onSessionStopped(AbstractSession session);
20 |
21 | }
22 |
23 | private BlockingQueue messages = new LinkedBlockingQueue();
24 | private String session_id = null;
25 | public volatile boolean running = false;
26 |
27 | private Set on_session_status_listeners = new HashSet();
28 |
29 | public AbstractSession() {
30 | this.session_id = this.generateSessionId();
31 | }
32 |
33 | protected AbstractSession(String session_id) {
34 | this.session_id = session_id;
35 | }
36 |
37 | public void addOnSessionStatusListener(OnSessionStatusListener listener) {
38 | this.on_session_status_listeners.add(listener);
39 | }
40 |
41 | public void deliverMessage(Message message) {
42 | this.messages.offer(message);
43 | }
44 |
45 | private String generateSessionId() {
46 | return new BigInteger(130, new SecureRandom()).toString(32);
47 | }
48 |
49 | public String getSessionId() {
50 | return this.session_id;
51 | }
52 |
53 | protected abstract Message handleMessage(Message message) throws InvalidMessageException;
54 |
55 | public void removeOnSessionStatusListener(OnSessionStatusListener listener) {
56 | this.on_session_status_listeners.remove(listener);
57 | }
58 |
59 | @Override
60 | public void run() {
61 | this.running = true;
62 |
63 | for(OnSessionStatusListener l : this.on_session_status_listeners)
64 | l.onSessionStarted(this);
65 |
66 | while(this.running) {
67 | Message message = null;
68 |
69 | try {
70 | message = this.messages.take();
71 | }
72 | catch (InterruptedException e) {}
73 |
74 | if(message != null) {
75 | try {
76 | Message response = this.handleMessage(message);
77 |
78 | if(response != null)
79 | this.send(response);
80 | }
81 | catch(InvalidMessageException e) {}
82 | }
83 | }
84 |
85 | for(OnSessionStatusListener l : this.on_session_status_listeners)
86 | l.onSessionStopped(this);
87 | }
88 |
89 | public abstract void send(Message message);
90 |
91 | public void stopSession() {
92 | this.running = false;
93 |
94 | this.interrupt();
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/connection/AbstractSessionCollection.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.connection;
2 |
3 | import java.util.Collection;
4 | import java.util.HashMap;
5 |
6 | import com.mwr.jdiesel.connection.AbstractSession.OnSessionStatusListener;
7 |
8 | public abstract class AbstractSessionCollection implements OnSessionStatusListener {
9 |
10 | private HashMap sessions = new HashMap();
11 |
12 | public Collection all() {
13 | return this.sessions.values();
14 | }
15 |
16 | public boolean any() {
17 | return !this.sessions.isEmpty();
18 | }
19 |
20 | public abstract AbstractSession create();
21 |
22 | protected AbstractSession storeSession(AbstractSession session) {
23 | this.sessions.put(session.getSessionId(), session);
24 |
25 | session.addOnSessionStatusListener(this);
26 | session.start();
27 |
28 | return session;
29 | }
30 |
31 | public AbstractSession get(String session_id) {
32 | return this.sessions.get(session_id);
33 | }
34 |
35 | public AbstractSession stop(String session_id) {
36 | AbstractSession session = this.sessions.get(session_id);
37 |
38 | if(session != null) {
39 | this.sessions.remove(session_id);
40 |
41 | try {
42 | session.stopSession();
43 | session.join();
44 | }
45 | catch(InterruptedException e) {
46 | e.printStackTrace();
47 | }
48 | }
49 |
50 | return session;
51 | }
52 |
53 | public void stopAll() {
54 | String[] keys = this.sessions.keySet().toArray(new String[] {});
55 |
56 | for(String session_id : keys)
57 | this.stop(session_id);
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/connection/SecureConnection.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.connection;
2 |
3 | public interface SecureConnection {
4 |
5 | public String getHostCertificateFingerprint();
6 | public String getPeerCertificateFingerprint();
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/logger/LogMessage.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.logger;
2 |
3 | import android.os.Bundle;
4 |
5 | public class LogMessage {
6 |
7 | public static final String LEVEL = "log:level";
8 | public static final String MESSAGE = "log:message";
9 |
10 | public static final int VERBOSE = 0x00000002;
11 | public static final int DEBUG = 0x00000003;
12 | public static final int INFO = 0x00000004;
13 | public static final int WARN = 0x00000005;
14 | public static final int ERROR = 0x00000006;
15 | public static final int ASSERT = 0x00000007;
16 |
17 | private int level;
18 | private String message;
19 |
20 | public LogMessage(String message) {
21 | this(LogMessage.INFO, message);
22 | }
23 |
24 | public LogMessage(int level, String message) {
25 | this.level = level;
26 | this.message = message;
27 | }
28 |
29 | public LogMessage(Bundle bundle) {
30 | this(bundle.getInt(LogMessage.LEVEL), bundle.getString(LogMessage.MESSAGE));
31 | }
32 |
33 | public int getLevel() {
34 | return this.level;
35 | }
36 |
37 | public String getMessage() {
38 | return this.message != null ? this.message : "No message.";
39 | }
40 |
41 | public Bundle toBundle() {
42 | Bundle bundle = new Bundle();
43 |
44 | bundle.putInt(LogMessage.LEVEL, this.getLevel());
45 | bundle.putString(LogMessage.MESSAGE, this.getMessage());
46 |
47 | return bundle;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/logger/Logger.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.logger;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashSet;
5 | import java.util.List;
6 | import java.util.Set;
7 |
8 | public class Logger {
9 |
10 | private List log_messages = new ArrayList();
11 | private Set> on_log_message_listeners = new HashSet>();
12 | private T owner;
13 |
14 | public Logger(T owner) {
15 | this.owner = owner;
16 | }
17 |
18 | public void addOnLogMessageListener(OnLogMessageListener listener) {
19 | this.on_log_message_listeners.add(listener);
20 | }
21 |
22 | public List getLogMessages() {
23 | return this.log_messages;
24 | }
25 |
26 | public T getOwner() {
27 | return this.owner;
28 | }
29 |
30 | public void log(int level, String message) {
31 | this.log(new LogMessage(level, message));
32 | }
33 |
34 | public void log(LogMessage message) {
35 | this.log_messages.add(message);
36 |
37 | for(OnLogMessageListener listener : this.on_log_message_listeners)
38 | listener.onLogMessage(this, message);
39 | }
40 |
41 | public void removeOnLogMessageListener(OnLogMessageListener listener) {
42 | this.on_log_message_listeners.remove(listener);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/logger/OnLogMessageListener.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.logger;
2 |
3 | public interface OnLogMessageListener {
4 |
5 | public void onLogMessage(Logger logger, LogMessage message);
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/jdiesel/src/main/java/com/mwr/jdiesel/reflection/ObjectStore.java:
--------------------------------------------------------------------------------
1 | package com.mwr.jdiesel.reflection;
2 |
3 | import java.util.List;
4 |
5 | import android.util.SparseArray;
6 |
7 | import dalvik.system.DexClassLoader;
8 |
9 | public class ObjectStore {
10 |
11 | private SparseArray