Merge branch 'develope' into 'master'

Merge to master

See merge request its-wg/overview/overview-ubo/misp-auth!2
pull/5/head
Felix Prahl-Kamps 2018-07-22 20:27:31 +02:00
commit 49b5af5a05
34 changed files with 305 additions and 79 deletions

View File

@ -1,33 +1,33 @@
![MispBump Logo](./images/mispbump.svg)
# MISPBump
With MISPBump it is easy to share events on your MISP instance with other instances. Instead of generating organisations, sync-users and sync-servers you scan only two QR-Codes and the job is done.
With MISPBump it is easy to synchronise events on different MISP instances. Instead of generating organisations, sync-users and sync-servers you only have to scan two QR-Codes and you are ready for syncing.
# Security
A key agreement is realized with Diffie Hellman (Elliptic Curve 256 Bit), sensible data is encrypted with AES.
(how are credentials stored in app, keystore?)
TODO: how are credentials stored in app, keystore?
# How does it work?
1. Main screen (no changes)
1. Gather your organisation information from your MISP instance
![Gather Information](./Screenshots/sync-profile.png)
![Gather Information](./images/Screenshots/sync-profile.png)
1. Scan your partners generated public key and at the same time share yours
![Scan Public Key](./Screenshots/scan-pub-key.png)
![Scan Public Key](./images/Screenshots/scan-pub-key.png)
2. Validate the public key you scanned
![Public Key Received](./Screenshots/pub-key-received.png)
![Public Key Received](./images/Screenshots/pub-key-received.png)
3. After another scan the information you need to synchronise is securely transmitted to your phone
![Secure Info Received](./Screenshots/org-info-received.png)
![Secure Info Received](./images/Screenshots/org-info-received.png)
4. Upload the information to your own MISP instance
![Upload](./Screenshots/upload.png)
![Upload](./images/Screenshots/upload.png)
5. That's it! You are ready to share events across your instances
![Main Screen](./Screenshots/main.png)
![Main Screen](./images/Screenshots/main.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

View File

@ -7,9 +7,9 @@
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:icon="@mipmap/launcher_handshake_square"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:roundIcon="@mipmap/launcher_handshake_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
@ -17,7 +17,6 @@
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

View File

@ -10,6 +10,9 @@ import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
@ -22,15 +25,20 @@ import android.widget.CompoundButton;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.volley.VolleyError;
import de.overview.wg.its.mispauth.adapter.OrganisationInfoEntryAdapter;
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
import de.overview.wg.its.mispauth.cam.DialogFactory;
import de.overview.wg.its.mispauth.model.Organisation;
import de.overview.wg.its.mispauth.model.StringPair;
import de.overview.wg.its.mispauth.model.User;
import de.overview.wg.its.mispauth.network.MispRequest;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("ConstantConditions")
@SuppressLint("SetTextI18n")
public class CredentialsActivity extends AppCompatActivity implements View.OnClickListener {
@ -42,12 +50,16 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
private TextInputLayout urlLayout, apiLayout;
private TextView emptyView;
private ViewGroup organisationView;
// private ViewGroup organisationView;
private ProgressBar progressBar;
private Organisation myOrganisation;
private User myUser;
private RecyclerView recyclerView;
private OrganisationInfoEntryAdapter adapter;
private List<StringPair> orgInfoEntries = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -120,10 +132,17 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
urlLayout = findViewById(R.id.input_layout_server_url);
apiLayout = findViewById(R.id.input_layout_api_key);
emptyView = findViewById(R.id.empty);
organisationView = findViewById(R.id.myOrganisationView);
// organisationView = findViewById(R.id.myOrganisationView);
FloatingActionButton fab = findViewById(R.id.fab_download_own_org_info);
fab.setOnClickListener(this);
recyclerView = findViewById(R.id.recyclerView);
adapter = new OrganisationInfoEntryAdapter();
RecyclerView.LayoutManager manager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(manager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
}
/**
@ -141,15 +160,16 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
if (myOrganisation == null) {
emptyView.setVisibility(View.VISIBLE);
organisationView.setVisibility(View.GONE);
// organisationView.setVisibility(View.GONE);
recyclerView.setVisibility(View.GONE);
} else {
emptyView.setVisibility(View.GONE);
organisationView.setVisibility(View.VISIBLE);
// organisationView.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.VISIBLE);
visualizeOrganisation();
}
}
private void savePreferences() {
@ -164,7 +184,10 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
}
if (myUser != null) {
myUser.clearForStorage();
preferenceManager.setMyUser(myUser);
}
if (myOrganisation != null) {
@ -243,20 +266,13 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
private void downloadOrgInfo() {
if (myOrganisation != null) {
DialogInterface.OnClickListener pos = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
downloadOrgInfo();
}
};
new DialogFactory(this).createOverrideDialog(pos, null).show();
} else {
downloadOrgInfo();
}
if (!validCredentials()) {
@ -294,7 +310,8 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
return;
}
organisationView.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.VISIBLE);
// organisationView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
@ -305,7 +322,8 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
public void onError(VolleyError volleyError) {
makeSnackBar(ReadableError.toReadable(volleyError));
progressBar.setVisibility(View.GONE);
organisationView.setVisibility(View.GONE);
recyclerView.setVisibility(View.GONE);
// organisationView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
}
});
@ -315,7 +333,8 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
public void onError(VolleyError volleyError) {
makeSnackBar(ReadableError.toReadable(volleyError));
progressBar.setVisibility(View.GONE);
organisationView.setVisibility(View.GONE);
recyclerView.setVisibility(View.GONE);
// organisationView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
}
});
@ -324,25 +343,32 @@ public class CredentialsActivity extends AppCompatActivity implements View.OnCli
private void visualizeOrganisation() {
TextView title = organisationView.findViewById(R.id.organisation_title);
title.setText(myOrganisation.getName());
orgInfoEntries.add(new StringPair("Name", myOrganisation.getName()));
// TextView title = organisationView.findViewById(R.id.organisation_title);
// TextView title = findViewById(R.id.org_title);
// title.setText(myOrganisation.getName());
TextView uuid = organisationView.findViewById(R.id.organisation_uuid);
uuid.setText(myOrganisation.getUuid());
orgInfoEntries.add(new StringPair("UUID", myOrganisation.getUuid()));
// TextView uuid = organisationView.findViewById(R.id.organisation_uuid);
// uuid.setText(myOrganisation.getUuid());
TextView description = organisationView.findViewById(R.id.organisation_description);
description.setText(myOrganisation.getDescription());
orgInfoEntries.add(new StringPair("Description", myOrganisation.getDescription()));
// TextView description = organisationView.findViewById(R.id.organisation_description);
// description.setText(myOrganisation.getDescription());
TextView nationality = organisationView.findViewById(R.id.organisation_nationality);
nationality.setText(myOrganisation.getNationality());
orgInfoEntries.add(new StringPair("Nationality", myOrganisation.getNationality()));
// TextView nationality = organisationView.findViewById(R.id.organisation_nationality);
// nationality.setText(myOrganisation.getNationality());
TextView sector = findViewById(R.id.organisation_sector);
sector.setText(myOrganisation.getSector());
orgInfoEntries.add(new StringPair("Sector", myOrganisation.getSector()));
// TextView sector = findViewById(R.id.organisation_sector);
// sector.setText(myOrganisation.getSector());
TextView users = findViewById(R.id.organisation_user_count);
users.setText("" + myOrganisation.getUserCount());
orgInfoEntries.add(new StringPair("User Count", "" + myOrganisation.getUserCount()));
// TextView users = findViewById(R.id.organisation_user_count);
// users.setText("" + myOrganisation.getUserCount());
adapter.setList(orgInfoEntries);
}
private void exitSafely() {

View File

@ -91,7 +91,7 @@ public class MainActivity extends AppCompatActivity {
emptyPartnerListView = findViewById(R.id.empty);
syncedPartnerRecyclerView = findViewById(R.id.recyclerView);
syncedPartnerAdapter = new SyncedPartnerAdapter(this, syncedPartnerList);
syncedPartnerAdapter = new SyncedPartnerAdapter(syncedPartnerList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
syncedPartnerRecyclerView.setLayoutManager(mLayoutManager);
syncedPartnerRecyclerView.setItemAnimator(new DefaultItemAnimator());

View File

@ -92,17 +92,16 @@ public class UploadActivity extends AppCompatActivity implements View.OnClickLis
}
private List<UploadState> syncUploadStates = new ArrayList<>();
private void SyncUpload() {
partnerOrganisation = partnerInformation.getOrganisation();
partnerSyncUser = partnerInformation.getUser();
partnerServer = partnerInformation.getServer();
syncUploadStates.add(new UploadState("Add local organisation"));
syncUploadStates.add(new UploadState("Add sync user to organisation"));
syncUploadStates.add(new UploadState("Add external organisation"));
syncUploadStates.add(new UploadState("Add sync server"));
syncUploadStates.add(new UploadState("Create local organisation"));
syncUploadStates.add(new UploadState("Create sync user & add to organisation"));
syncUploadStates.add(new UploadState("Create external organisation"));
syncUploadStates.add(new UploadState("Create sync server"));
uploadStateAdapter.setStateList(syncUploadStates);

View File

@ -0,0 +1,53 @@
package de.overview.wg.its.mispauth.adapter;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import de.overview.wg.its.mispauth.R;
import de.overview.wg.its.mispauth.model.StringPair;
import java.util.*;
public class OrganisationInfoEntryAdapter extends RecyclerView.Adapter<OrganisationInfoEntryAdapter.MyViewHolder> {
private List<StringPair> list = new ArrayList<>();
class MyViewHolder extends RecyclerView.ViewHolder {
TextView title, value;
private MyViewHolder(View view) {
super(view);
this.title = view.findViewById(R.id.title);
this.value = view.findViewById(R.id.value);
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_org_info_entry, parent, false);
return new OrganisationInfoEntryAdapter.MyViewHolder(row);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.title.setText(list.get(position).key);
holder.value.setText(list.get(position).value);
}
@Override
public int getItemCount() {
return list.size();
}
public void setList(List<StringPair> list) {
this.list = list;
notifyDataSetChanged();
}
}

View File

@ -36,13 +36,11 @@ public class Organisation {
private int createdBy;
private int userCount;
public Organisation() {
}
public Organisation() {}
public Organisation(JSONObject json) throws JSONException {
fromJSON(json);
}
public void fromJSON(JSONObject org) throws JSONException {
id = org.optInt(ID_KEY, -1);
@ -65,7 +63,6 @@ public class Organisation {
public JSONObject toJSON() {
return toJSON(false);
}
public JSONObject toJSON(boolean minimal) {
JSONObject org = new JSONObject();
@ -99,7 +96,6 @@ public class Organisation {
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@ -107,7 +103,6 @@ public class Organisation {
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@ -115,7 +110,6 @@ public class Organisation {
public String getSector() {
return sector;
}
public void setSector(String sector) {
this.sector = sector;
}
@ -123,7 +117,6 @@ public class Organisation {
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
@ -131,7 +124,6 @@ public class Organisation {
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@ -139,7 +131,6 @@ public class Organisation {
public String getDateCreated() {
return dateCreated;
}
public void setDateCreated(String dateCreated) {
this.dateCreated = dateCreated;
}
@ -147,7 +138,6 @@ public class Organisation {
public String getDateModified() {
return dateModified;
}
public void setDateModified(String dateModified) {
this.dateModified = dateModified;
}
@ -155,7 +145,6 @@ public class Organisation {
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@ -163,7 +152,6 @@ public class Organisation {
public String getContacts() {
return contacts;
}
public void setContacts(String contacts) {
this.contacts = contacts;
}
@ -171,7 +159,6 @@ public class Organisation {
public boolean isLocal() {
return local;
}
public void setLocal(boolean local) {
this.local = local;
}
@ -179,7 +166,6 @@ public class Organisation {
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@ -187,7 +173,6 @@ public class Organisation {
public String getRestrictedToDomain() {
return restrictedToDomain;
}
public void setRestrictedToDomain(String restrictedToDomain) {
this.restrictedToDomain = restrictedToDomain;
}
@ -195,7 +180,6 @@ public class Organisation {
public int getCreatedBy() {
return createdBy;
}
public void setCreatedBy(int createdBy) {
this.createdBy = createdBy;
}
@ -203,7 +187,6 @@ public class Organisation {
public int getUserCount() {
return userCount;
}
public void setUserCount(int userCount) {
this.userCount = userCount;
}

View File

@ -0,0 +1,11 @@
package de.overview.wg.its.mispauth.model;
public class StringPair {
public String key, value;
public StringPair(String key, String value) {
this.key = key;
this.value = value;
}
}

View File

@ -63,8 +63,8 @@ public class User {
private String dateCreated;
private String dateModified;
public User() {
}
public User() {}
public User(JSONObject user) throws JSONException {
fromJSON(user);
}
@ -138,6 +138,12 @@ public class User {
return user;
}
public void clearForStorage() {
setAuthkey("");
setGpgKey("");
setCertifPublic("");
}
public int getId() {
return id;

View File

@ -48,7 +48,7 @@
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingEnd="16dp"
android:paddingBottom="42dp"
android:paddingBottom="32dp"
app:passwordToggleEnabled="true"
app:passwordToggleTint="#FFF"
android:layout_width="match_parent"
@ -70,18 +70,41 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:layout_width="0dp"
<!--<include-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="0dp"-->
<!--layout="@layout/view_organisation"-->
<!--app:layout_constraintStart_toStartOf="parent"-->
<!--android:layout_marginStart="16dp"-->
<!--app:layout_constraintTop_toTopOf="parent"-->
<!--android:layout_marginTop="32dp"-->
<!--app:layout_constraintEnd_toEndOf="parent"-->
<!--android:layout_marginEnd="16dp"-->
<!--app:layout_constraintBottom_toBottomOf="parent"-->
<!--android:layout_marginBottom="16dp"/>-->
<!--<TextView-->
<!--android:id="@+id/org_title"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_marginTop="32dp"-->
<!--app:layout_constraintStart_toStartOf="parent"-->
<!--app:layout_constraintEnd_toEndOf="parent"-->
<!--app:layout_constraintTop_toTopOf="parent"-->
<!--tools:text="Organisation A"-->
<!--android:textAppearance="@android:style/TextAppearance.Material.Title"-->
<!--android:textAlignment="center"/>-->
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
layout="@layout/view_organisation"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="16dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="32dp"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
>
</android.support.v7.widget.RecyclerView>
<TextView
android:id="@+id/empty"

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="16dp"
android:textColor="#000"
android:text="Test Title" android:textSize="17sp" android:textStyle="normal"/>
<TextView
android:layout_marginStart="20dp"
android:layout_marginBottom="16dp"
android:id="@+id/value"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/title"
android:text="Test Subtitle"/>
<View
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_below="@id/value"
android:layout_width="match_parent" android:layout_height="1dp"
android:background="#11000000"/>
</RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

Before

Width:  |  Height:  |  Size: 343 KiB

After

Width:  |  Height:  |  Size: 343 KiB

View File

Before

Width:  |  Height:  |  Size: 380 KiB

After

Width:  |  Height:  |  Size: 380 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

96
images/mispbump.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.0 KiB