├── .editorconfig
├── .gitignore
├── .idea
├── gradle.xml
└── runConfigurations.xml
├── .tx
└── config
├── LICENSE
├── PGPAuth
├── build.gradle
├── lint.xml
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── org
│ │ └── lf_net
│ │ └── pgpunlocker
│ │ ├── AboutActivity.java
│ │ ├── AutoResetEvent.java
│ │ ├── Logic.java
│ │ ├── MainActivity.java
│ │ ├── PGPKeyPreference.java
│ │ ├── Server.java
│ │ ├── ServerAdapter.java
│ │ ├── ServerDeleteActivity.java
│ │ ├── ServerEditActivity.java
│ │ ├── ServerManager.java
│ │ └── SettingsActivity.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ ├── activity_about.xml
│ ├── activity_main.xml
│ ├── activity_server_delete.xml
│ ├── activity_server_edit.xml
│ └── listview_item_server.xml
│ ├── menu
│ └── mainmenu.xml
│ ├── values-de
│ └── strings.xml
│ ├── values-eo
│ └── strings.xml
│ ├── values-fr
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-ja
│ └── strings.xml
│ ├── values-ru_RU
│ └── strings.xml
│ ├── values-v14
│ └── styles.xml
│ ├── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ └── preferences.xml
├── README.md
├── build.gradle
└── settings.gradle
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 | charset = utf-8
8 | indent_style = space
9 | indent_size = 4
10 | curly_bracket_next_line = true
11 | indent_brace_style = GNU
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | /*/build/
3 |
4 | # Crashlytics configuations
5 | com_crashlytics_export_strings.xml
6 |
7 | # Local configuration file (sdk path, etc)
8 | local.properties
9 |
10 | # Gradle generated files
11 | .gradle/
12 |
13 | # Signing files
14 | .signing/
15 |
16 | # User-specific configurations
17 | .idea/libraries/
18 | .idea/workspace.xml
19 | .idea/tasks.xml
20 | .idea/.name
21 | .idea/compiler.xml
22 | .idea/copyright/profiles_settings.xml
23 | .idea/encodings.xml
24 | .idea/misc.xml
25 | .idea/modules.xml
26 | .idea/scopes/scope_settings.xml
27 | .idea/vcs.xml
28 | *.iml
29 |
30 | # OS-specific files
31 | .DS_Store
32 | .DS_Store?
33 | ._*
34 | .Spotlight-V100
35 | .Trashes
36 | ehthumbs.db
37 | Thumbs.db
38 |
39 | # language-specific strings (managed by transifex)
40 | # XXX: translations are added to repo at the moment
41 | # to allow automated builds in F-Droid
42 | #PGPAuth/src/main/res/values-*/strings.xml
43 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.tx/config:
--------------------------------------------------------------------------------
1 | [main]
2 | host = https://www.transifex.com
3 |
4 | [pgpauth.Strings]
5 | file_filter = PGPAuth/src/main/res/values-/strings.xml
6 | source_file = PGPAuth/src/main/res/values/strings.xml
7 | source_lang = en
8 | type = Android
9 |
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Addition to the MIT-license for PGPAuth:
2 | It is not neccessary, but it would be really great if you would let me know
3 | when you are creating a product with PGPAuth.
4 |
5 |
6 |
7 |
8 | The MIT License (MIT)
9 |
10 | Copyright (c) 2013-2016 Moritz Grosch (LittleFox)
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining a copy
13 | of this software and associated documentation files (the "Software"), to deal
14 | in the Software without restriction, including without limitation the rights
15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 | copies of the Software, and to permit persons to whom the Software is
17 | furnished to do so, subject to the following conditions:
18 |
19 | The above copyright notice and this permission notice shall be included in
20 | all copies or substantial portions of the Software.
21 |
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 | THE SOFTWARE.
29 |
30 |
--------------------------------------------------------------------------------
/PGPAuth/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 18
5 | buildToolsVersion '25.0.0'
6 |
7 | defaultConfig {
8 | applicationId "org.lf_net.pgpunlocker"
9 | minSdkVersion 9
10 | targetSdkVersion 18
11 | }
12 |
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile 'com.android.support:support-v4:18.0.0'
23 | compile 'org.sufficientlysecure:openpgp-api:11.0'
24 | }
25 |
--------------------------------------------------------------------------------
/PGPAuth/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
39 |
40 |
44 |
47 |
48 |
52 |
55 |
56 |
60 | android:parentActivityName=".MainActivity" >
61 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/AboutActivity.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Bundle;
7 | import android.view.View;
8 |
9 | public class AboutActivity extends Activity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_about);
15 | }
16 |
17 | public void onWebsiteClick(View view) {
18 | Intent showWebsite = new Intent(Intent.ACTION_VIEW);
19 | showWebsite.setData(Uri.parse((String) view.getTag()));
20 | startActivity(showWebsite);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/AutoResetEvent.java:
--------------------------------------------------------------------------------
1 | /// From http://stackoverflow.com/a/13838191
2 |
3 | package org.lf_net.pgpunlocker;
4 |
5 | public class AutoResetEvent {
6 | private final Object _monitor = new Object();
7 | private volatile boolean _isOpen = false;
8 |
9 | public AutoResetEvent(boolean open) {
10 | _isOpen = open;
11 | }
12 |
13 | public void waitOne() throws InterruptedException {
14 | synchronized (_monitor) {
15 | while (!_isOpen) {
16 | _monitor.wait();
17 | }
18 | _isOpen = false;
19 | }
20 | }
21 |
22 | public void waitOne(long timeout) throws InterruptedException {
23 | synchronized (_monitor) {
24 | long t = System.currentTimeMillis();
25 | while (!_isOpen) {
26 | _monitor.wait(timeout);
27 | // Check for timeout
28 | if (System.currentTimeMillis() - t >= timeout)
29 | break;
30 | }
31 | _isOpen = false;
32 | }
33 | }
34 |
35 | public void set() {
36 | synchronized (_monitor) {
37 | _isOpen = true;
38 | _monitor.notify();
39 | }
40 | }
41 |
42 | public void reset() {
43 | _isOpen = false;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/Logic.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.InputStream;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import org.apache.http.HttpResponse;
10 | import org.apache.http.NameValuePair;
11 | import org.apache.http.client.HttpClient;
12 | import org.apache.http.client.entity.UrlEncodedFormEntity;
13 | import org.apache.http.client.methods.HttpPost;
14 | import org.apache.http.impl.client.DefaultHttpClient;
15 | import org.apache.http.message.BasicNameValuePair;
16 | import org.openintents.openpgp.OpenPgpError;
17 | import org.openintents.openpgp.util.OpenPgpApi;
18 | import org.openintents.openpgp.util.OpenPgpServiceConnection;
19 |
20 | import android.app.PendingIntent;
21 | import android.content.Context;
22 | import android.content.Intent;
23 | import android.content.IntentSender;
24 | import android.content.pm.PackageInfo;
25 | import android.content.pm.PackageManager.NameNotFoundException;
26 | import android.webkit.URLUtil;
27 |
28 | public class Logic {
29 |
30 | OpenPgpServiceConnection _serviceConnection = null;
31 | Context _context;
32 | String _signedData = null;
33 | AutoResetEvent _event = new AutoResetEvent(false);
34 | GuiHelper _guiHelper;
35 |
36 | public static Logic Logic;
37 |
38 | public abstract class GuiHelper {
39 | public abstract void startActivityForResult(Intent intent, int requestCode);
40 |
41 | public abstract void startIntentSenderForResult(IntentSender intentSender, int requestCode);
42 |
43 | public abstract void showUserFeedback(String feedback);
44 | }
45 |
46 | public Logic(Context context, boolean forceAPG) {
47 | _context = context;
48 |
49 | boolean hasAPG = detectApg();
50 | boolean hasOpenKeychain = detectOpenKeyChain();
51 |
52 | if (hasOpenKeychain && !forceAPG) {
53 | _serviceConnection = new OpenPgpServiceConnection(context, "org.sufficientlysecure.keychain");
54 | _serviceConnection.bindToService();
55 | }
56 |
57 | if (!hasAPG && forceAPG) {
58 | throw new RuntimeException((String) context.getText(R.string.apg_forced_but_not_installed));
59 | }
60 |
61 | if (!hasAPG && !hasOpenKeychain) {
62 | throw new RuntimeException((String) context.getText(R.string.apg_and_opengpg_keychain_not_installed));
63 | }
64 |
65 | _event = new AutoResetEvent(false);
66 | }
67 |
68 | public void close() {
69 | if (_serviceConnection != null && _serviceConnection.isBound()) {
70 | _serviceConnection.unbindFromService();
71 | }
72 | }
73 |
74 | public void doActionOnServerWithFeedback(String action, String server, String keyAPG) {
75 | String ret = doActionOnServer(action, server, keyAPG);
76 | _guiHelper.showUserFeedback(ret);
77 | }
78 |
79 | public String doActionOnServer(String action, String server, String keyAPG) {
80 | if (server == "" || !URLUtil.isValidUrl(server)) {
81 | if (server == "") {
82 | return _context.getString(R.string.no_server_set);
83 | } else if (!URLUtil.isValidUrl(server)) {
84 | return _context.getString(R.string.invalid_server_set);
85 | } else {
86 | return _context.getString(R.string.unknown_error);
87 | }
88 | }
89 |
90 | long timestamp = System.currentTimeMillis() / 1000;
91 | String request = action + ":" + timestamp;
92 |
93 | if (_serviceConnection == null) {
94 | Intent intent = new Intent("org.thialfihar.android.apg.intent.ENCRYPT_AND_RETURN");
95 | intent.putExtra("intentVersion", 1);
96 | intent.setType("text/plain");
97 | intent.putExtra("text", request);
98 | intent.putExtra("ascii_armor", true);
99 |
100 | if (keyAPG != "") {
101 | intent.putExtra("signatureKeyId", Long.parseLong(keyAPG));
102 | }
103 |
104 | _guiHelper.startActivityForResult(intent, 1);
105 | } else {
106 | Intent intent = new Intent();
107 | intent.setAction(OpenPgpApi.ACTION_SIGN);
108 | intent.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
109 | intent.putExtra("PGPAuth_SIGNDATA", request);
110 |
111 | try {
112 | sendOpenKeychainIntent(intent);
113 | } catch (Exception e) {
114 | return e.getLocalizedMessage();
115 | }
116 | }
117 |
118 | try {
119 | _event.waitOne();
120 | } catch (InterruptedException e1) {
121 | return e1.getLocalizedMessage();
122 | }
123 |
124 | if (_signedData == null) {
125 | return _context.getString(R.string.unknown_error);
126 | }
127 |
128 | try {
129 | HttpClient client = new DefaultHttpClient();
130 | HttpPost req = new HttpPost(server);
131 | List httpParams = new ArrayList();
132 | httpParams.add(new BasicNameValuePair("data", _signedData));
133 | req.setEntity(new UrlEncodedFormEntity(httpParams));
134 |
135 | HttpResponse response = client.execute(req);
136 |
137 | if (response.getStatusLine().getStatusCode() != 200) {
138 | return response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase();
139 | } else {
140 | return _context.getResources().getString(android.R.string.ok);
141 | }
142 | } catch (Exception e) {
143 | return e.getMessage();
144 | } finally {
145 | _signedData = null;
146 | _event.reset();
147 | }
148 | }
149 |
150 | public void postResult(int requestCode, int resultCode, Intent data) {
151 | switch (requestCode) {
152 | case 1: {
153 | if (data != null && data.hasExtra("encryptedMessage")) {
154 | _signedData = data.getStringExtra("encryptedMessage");
155 | } else {
156 | _signedData = null;
157 | }
158 |
159 | _event.set();
160 |
161 | break;
162 | }
163 | case 2: {
164 | try {
165 | sendOpenKeychainIntent(data);
166 | } catch (Exception e) {
167 | _signedData = null;
168 | _event.set();
169 | }
170 | break;
171 | }
172 | }
173 | }
174 |
175 | public void setGuiHelper(GuiHelper guiHelper) {
176 | _guiHelper = guiHelper;
177 | }
178 |
179 | private boolean detectApg() {
180 | try {
181 | PackageInfo pi = _context.getPackageManager().getPackageInfo("org.thialfihar.android.apg", 0);
182 | if (pi.versionCode >= 16) {
183 | return true;
184 | }
185 | } catch (NameNotFoundException e) {
186 | // not found
187 | }
188 |
189 | return false;
190 | }
191 |
192 | private boolean detectOpenKeyChain() {
193 | try {
194 | PackageInfo pi = _context.getPackageManager().getPackageInfo("org.sufficientlysecure.keychain", 0);
195 |
196 | if (pi.versionCode > 20000) {
197 | return true;
198 | }
199 | } catch (NameNotFoundException e) {
200 | // not found
201 | }
202 |
203 | return false;
204 | }
205 |
206 | private void sendOpenKeychainIntent(Intent data) throws Exception {
207 | InputStream is = new ByteArrayInputStream(data.getExtras().getString("PGPAuth_SIGNDATA").getBytes());
208 | ByteArrayOutputStream os = new ByteArrayOutputStream();
209 |
210 | OpenPgpApi api = new OpenPgpApi(_context, _serviceConnection.getService());
211 | Intent result = api.executeApi(data, is, os);
212 |
213 | switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
214 | case OpenPgpApi.RESULT_CODE_SUCCESS: {
215 | _signedData = os.toString("UTF-8");
216 | _event.set();
217 | break;
218 | }
219 | case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
220 | PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
221 | _guiHelper.startIntentSenderForResult(pi.getIntentSender(), 2);
222 | break;
223 | }
224 | case OpenPgpApi.RESULT_CODE_ERROR: {
225 | OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
226 | throw new RuntimeException(error.getMessage());
227 | }
228 | }
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/MainActivity.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.content.IntentSender;
6 | import android.content.IntentSender.SendIntentException;
7 | import android.content.SharedPreferences;
8 | import android.net.Uri;
9 | import android.os.Bundle;
10 | import android.preference.PreferenceManager;
11 | import android.view.ContextMenu;
12 | import android.view.ContextMenu.ContextMenuInfo;
13 | import android.view.Menu;
14 | import android.view.MenuInflater;
15 | import android.view.MenuItem;
16 | import android.view.View;
17 | import android.widget.AdapterView.AdapterContextMenuInfo;
18 | import android.widget.ListView;
19 | import android.widget.Toast;
20 |
21 | public class MainActivity extends Activity {
22 | /**
23 | * Called when the activity is first created.
24 | */
25 | @Override
26 | public void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 |
29 | ServerManager.loadFromFile(this);
30 |
31 | Uri serverConfig = getIntent().getData();
32 |
33 | if (serverConfig != null) {
34 | Intent intent = new Intent(this, ServerEditActivity.class);
35 | intent.setData(serverConfig);
36 | startActivity(intent);
37 | }
38 |
39 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
40 |
41 | setContentView(R.layout.activity_main);
42 |
43 | ListView listViewServers = (ListView) findViewById(R.id.listViewServers);
44 | ServerAdapter adapter = new ServerAdapter(this, R.layout.listview_item_server);
45 | listViewServers.setAdapter(adapter);
46 |
47 | registerForContextMenu(listViewServers);
48 |
49 | try {
50 | Logic.Logic = new Logic(this, prefs.getBoolean("pref_forceapg", false));
51 |
52 | Logic.GuiHelper guiHelper = Logic.Logic.new GuiHelper() {
53 | public void startActivityForResult(Intent intent, int requestCode) {
54 | MainActivity.this.startActivityForResult(intent, requestCode + 0x0000B000);
55 | }
56 |
57 | public void startIntentSenderForResult(IntentSender intentSender, int requestCode) {
58 | try {
59 | MainActivity.this.startIntentSenderForResult(intentSender, requestCode + 0x0000B000, null, 0, 0, 0);
60 | } catch (SendIntentException e) {
61 | // just fuck you
62 | }
63 | }
64 |
65 | public void showUserFeedback(final String feedback) {
66 | runOnUiThread(new Runnable() {
67 | public void run() {
68 | Toast.makeText(MainActivity.this, feedback, Toast.LENGTH_LONG).show();
69 | }
70 | });
71 | }
72 | };
73 |
74 | Logic.Logic.setGuiHelper(guiHelper);
75 | } catch (Exception e) {
76 | Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
77 | Intent intent = new Intent(this, SettingsActivity.class);
78 | startActivityForResult(intent, 0x0000A001);
79 |
80 | Toast.makeText(this, R.string.invalid_settings_detected, Toast.LENGTH_LONG).show();
81 | }
82 | }
83 |
84 | @Override
85 | public void onDestroy() {
86 | if (Logic.Logic != null) {
87 | Logic.Logic.close();
88 | }
89 |
90 | ServerManager.saveToFile(this);
91 |
92 | super.onDestroy();
93 | }
94 |
95 | @Override
96 | public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo info) {
97 | super.onCreateContextMenu(menu, v, info);
98 |
99 | if (v == findViewById(R.id.listViewServers)) {
100 | AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) info;
101 | int index = menuInfo.position;
102 |
103 | Intent editIntent = new Intent(this, ServerEditActivity.class);
104 | editIntent.putExtra("ServerIndex", index);
105 |
106 | Intent deleteIntent = new Intent(this, ServerDeleteActivity.class);
107 | deleteIntent.putExtra("ServerIndex", index);
108 |
109 | Intent shareIntent = new Intent(Intent.ACTION_SEND);
110 | shareIntent.putExtra(Intent.EXTRA_TEXT, ServerManager.serverAtIndex(index).serializeForURL());
111 | shareIntent.setType("text/plain");
112 |
113 | menu.setHeaderTitle(R.string.contextmenu_title);
114 |
115 | MenuItem editItem = menu.add(0, v.getId(), 0, R.string.action_edit);
116 | editItem.setIntent(editIntent);
117 |
118 | MenuItem deleteItem = menu.add(0, v.getId(), 1, R.string.action_delete);
119 | deleteItem.setIntent(deleteIntent);
120 |
121 | MenuItem shareItem = menu.add(0, v.getId(), 2, R.string.action_share);
122 | shareItem.setIntent(Intent.createChooser(shareIntent, getText(R.string.action_share)));
123 | }
124 | }
125 |
126 | @Override
127 | public boolean onCreateOptionsMenu(Menu menu) {
128 | MenuInflater inflater = getMenuInflater();
129 | inflater.inflate(R.menu.mainmenu, menu);
130 | return true;
131 | }
132 |
133 | @Override
134 | public boolean onOptionsItemSelected(MenuItem item) {
135 | switch (item.getItemId()) {
136 | case R.id.menuItemAbout: {
137 | Intent intent = new Intent(this, AboutActivity.class);
138 | startActivity(intent);
139 | break;
140 | }
141 | case R.id.menuItemAddServer: {
142 | ServerManager.addServer();
143 |
144 | Intent intent = new Intent(this, ServerEditActivity.class);
145 | intent.putExtra("ServerIndex", ServerManager.count() - 1);
146 | startActivity(intent);
147 | break;
148 | }
149 | case R.id.menuItemSettings: {
150 | Intent intent = new Intent(this, SettingsActivity.class);
151 | startActivityForResult(intent, 0x0000A001);
152 | break;
153 | }
154 | default:
155 | return false;
156 | }
157 |
158 | return true;
159 | }
160 |
161 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
162 |
163 | if (requestCode == 0x0000A001) {
164 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
165 |
166 | if (Logic.Logic != null) {
167 | Logic.Logic.close();
168 | }
169 |
170 | try {
171 | Logic.Logic = new Logic(this, prefs.getBoolean("pref_forceapg", false));
172 | } catch (Exception e) {
173 | Logic.Logic = null;
174 | Intent intent = new Intent(this, SettingsActivity.class);
175 | startActivityForResult(intent, 0x0000A001);
176 |
177 | Toast.makeText(this, R.string.invalid_settings_detected, Toast.LENGTH_LONG).show();
178 | }
179 | } else if (requestCode > 0x0000B000 && requestCode < 0x0000C0000) {
180 | Logic.Logic.postResult(requestCode - 0x0000B000, resultCode, data);
181 | } else {
182 | super.onActivityResult(requestCode, resultCode, data);
183 | }
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/PGPKeyPreference.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.media.RingtoneManager;
6 | import android.preference.*;
7 | import android.util.AttributeSet;
8 |
9 | //Why I'm using a RingtonePreference? Because all the others don't have onActivityResult ...
10 | //http://yenliangl.blogspot.de/2011/04/preference-that-receives-activity.html
11 | public class PGPKeyPreference extends RingtonePreference {
12 |
13 | Context _context;
14 |
15 | public PGPKeyPreference(Context context) {
16 | super(context);
17 | _context = context;
18 | }
19 |
20 | public PGPKeyPreference(Context context, AttributeSet attr) {
21 | super(context, attr);
22 | _context = context;
23 | }
24 |
25 | public PGPKeyPreference(Context context, AttributeSet attr, int defStyle) {
26 | super(context, attr, defStyle);
27 | _context = context;
28 | }
29 |
30 | @Override
31 | protected void onPrepareRingtonePickerIntent(Intent intent) {
32 | // Remove all extras already placed by RingtonePreference
33 | intent.setAction(null);
34 | intent.removeExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI);
35 | intent.removeExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT);
36 | intent.removeExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI);
37 | intent.removeExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT);
38 | intent.removeExtra(RingtoneManager.EXTRA_RINGTONE_TYPE);
39 |
40 | intent.setAction("org.thialfihar.android.apg.intent.SELECT_SECRET_KEY");
41 | intent.putExtra("intentVersion", 1);
42 | }
43 |
44 | @Override
45 | public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
46 | if (super.onActivityResult(requestCode, resultCode, data)) {
47 | if (data != null && data.hasExtra("keyId")) {
48 | persistString(String.valueOf(data.getLongExtra("keyId", 0)));
49 | }
50 | }
51 |
52 | return false;
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/Server.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import java.net.URLDecoder;
4 | import java.net.URLEncoder;
5 |
6 | import org.json.JSONException;
7 | import org.json.JSONObject;
8 |
9 | public class Server {
10 | final static String ServerConfigBaseURL = "https://pgpauth.lf-net.org/serverConfig?config=";
11 |
12 | String _name;
13 | String _url;
14 | String _apgKey;
15 |
16 | public Server(String name, String url) {
17 | this(name, url, "");
18 | }
19 |
20 | public Server(String name, String url, String apgKey) {
21 | _name = name;
22 | _url = url;
23 | _apgKey = apgKey;
24 | }
25 |
26 | public String name() {
27 | return _name;
28 | }
29 |
30 | public String url() {
31 | return _url;
32 | }
33 |
34 | public String apgKey() {
35 | return _apgKey;
36 | }
37 |
38 | public void setName(String name) {
39 | _name = name;
40 | }
41 |
42 | public void setUrl(String url) {
43 | _url = url;
44 | }
45 |
46 | public void setApgKey(String apgKey) {
47 | _apgKey = apgKey;
48 | }
49 |
50 | public boolean isEmpty() {
51 | return _name == "" && _url == "";
52 | }
53 |
54 | @Deprecated
55 | public static Server deserialize(String serialized) {
56 | String[] parts = serialized.split("\t");
57 |
58 | if (parts.length == 2) {
59 | return new Server(parts[0], parts[1]);
60 | }
61 |
62 | if (parts.length == 3) {
63 | return new Server(parts[0], parts[1], parts[2]);
64 | }
65 |
66 | return null;
67 | }
68 |
69 | public JSONObject serializeJSON() {
70 | JSONObject ret = new JSONObject();
71 |
72 | try {
73 | ret.put("name", _name);
74 | ret.put("url", _url);
75 | ret.put("apgKey", _apgKey);
76 | } catch (JSONException e) {
77 | // should not happen as we just serialize a bunch of strings
78 | return null;
79 | }
80 |
81 | return ret;
82 | }
83 |
84 | public static Server deserializeJSON(JSONObject obj) throws JSONException {
85 | try {
86 | String name = obj.getString("name");
87 | String url = obj.getString("url");
88 | String apgKey = obj.getString("apgKey");
89 |
90 | return new Server(name, url, apgKey);
91 | } catch (JSONException e) {
92 | // should not happen as we just serialize a bunch of strings
93 | throw e;
94 | }
95 | }
96 |
97 | public String serializeForURL() {
98 | JSONObject ret = new JSONObject();
99 |
100 | try {
101 | ret.put("name", _name);
102 | ret.put("url", _url);
103 |
104 | String jsonString = ret.toString();
105 | String encoded = URLEncoder.encode(jsonString, "utf-8");
106 |
107 | return ServerConfigBaseURL + encoded;
108 | } catch (Exception e) {
109 | return null;
110 | }
111 | }
112 |
113 | public static Server deserializeFromURL(String configUrl) {
114 | try {
115 | String encoded = configUrl.substring(ServerConfigBaseURL.length());
116 | String jsonString = URLDecoder.decode(encoded, "utf-8");
117 |
118 | JSONObject obj = new JSONObject(jsonString);
119 |
120 | String name = obj.getString("name");
121 | String url = obj.getString("url");
122 |
123 | return new Server(name, url);
124 | } catch (Exception e) {
125 | return null;
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/ServerAdapter.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Looper;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.View.OnClickListener;
10 | import android.view.ViewGroup;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.Button;
13 | import android.widget.TextView;
14 | import android.widget.Toast;
15 |
16 | public class ServerAdapter extends ArrayAdapter {
17 | Context _context;
18 | int _layoutResourceId;
19 |
20 | public ServerAdapter(Context context, int layoutResourceId) {
21 | super(context, layoutResourceId);
22 |
23 | _context = context;
24 | _layoutResourceId = layoutResourceId;
25 |
26 | ServerManager.setObserver(new ServerManager.ServerManagerObserver() {
27 | @Override
28 | public void onSomethingChanged() {
29 | ServerAdapter.this.notifyDataSetChanged();
30 | }
31 | });
32 | }
33 |
34 | @Override
35 | public int getCount() {
36 | return ServerManager.count();
37 | }
38 |
39 | @Override
40 | public View getView(int position, View convertView, ViewGroup parent) {
41 | View row = convertView;
42 | ServerHolder holder = null;
43 |
44 | if (row == null) {
45 | LayoutInflater inflater = ((Activity) _context).getLayoutInflater();
46 | row = inflater.inflate(_layoutResourceId, parent, false);
47 |
48 | holder = new ServerHolder();
49 | holder.nameView = (TextView) row.findViewById(R.id.textViewServerName);
50 | holder.urlView = (TextView) row.findViewById(R.id.textViewServerURL);
51 | holder.lockButton = (Button) row.findViewById(R.id.buttonLock);
52 | holder.unlockButton = (Button) row.findViewById(R.id.buttonUnlock);
53 |
54 | row.setTag(holder);
55 | row.setClickable(true);
56 | row.setLongClickable(true);
57 | } else {
58 | holder = (ServerHolder) row.getTag();
59 | }
60 |
61 | Server server = ServerManager.serverAtIndex(position);
62 | holder.nameView.setText(server.name());
63 | holder.urlView.setText(server.url());
64 | holder.lockButton.setTag(server);
65 | holder.unlockButton.setTag(server);
66 | holder.index = position;
67 |
68 | holder.lockButton.setOnClickListener(new OnClickListener() {
69 | @Override
70 | public void onClick(View v) {
71 | final Server server = (Server) v.getTag();
72 |
73 | Thread runThread = new Thread(new Runnable() {
74 | @Override
75 | public void run() {
76 | Logic.Logic.doActionOnServerWithFeedback("close", server.url(), server.apgKey());
77 | }
78 | });
79 |
80 | runThread.start();
81 | }
82 | });
83 |
84 | holder.unlockButton.setOnClickListener(new OnClickListener() {
85 | @Override
86 | public void onClick(View v) {
87 | final Server server = (Server) v.getTag();
88 |
89 | Thread runThread = new Thread(new Runnable() {
90 | @Override
91 | public void run() {
92 | Logic.Logic.doActionOnServerWithFeedback("open", server.url(), server.apgKey());
93 | }
94 | });
95 |
96 | runThread.start();
97 | }
98 | });
99 |
100 | row.setOnClickListener(new OnClickListener() {
101 | @Override
102 | public void onClick(View v) {
103 | ServerHolder holder = (ServerHolder) v.getTag();
104 |
105 | Intent i = new Intent(_context, ServerEditActivity.class);
106 | i.putExtra("ServerIndex", holder.index);
107 | _context.startActivity(i);
108 | }
109 | });
110 |
111 | return row;
112 | }
113 |
114 | public static class ServerHolder {
115 | TextView nameView;
116 | TextView urlView;
117 | Button lockButton;
118 | Button unlockButton;
119 |
120 | int index;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/ServerDeleteActivity.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 |
7 | public class ServerDeleteActivity extends Activity {
8 |
9 | int _serverIndex;
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_server_delete);
15 |
16 | Bundle extras = getIntent().getExtras();
17 | if (extras != null) {
18 | _serverIndex = extras.getInt("ServerIndex");
19 | }
20 | }
21 |
22 | public void onDeleteClicked(View view) {
23 | ServerManager.deleteServer(_serverIndex);
24 | ServerManager.saveToFile(this);
25 | finish();
26 | }
27 |
28 | public void onCancelClicked(View view) {
29 | finish();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/ServerEditActivity.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import android.app.Activity;
4 | import android.net.Uri;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.EditText;
8 |
9 | public class ServerEditActivity extends Activity {
10 |
11 | EditText _editTextName;
12 | EditText _editTextURL;
13 |
14 | Server _server;
15 | int _serverIndex;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_server_edit);
21 |
22 | _editTextName = (EditText) findViewById(R.id.editTextName);
23 | _editTextURL = (EditText) findViewById(R.id.editTextURL);
24 |
25 | Bundle extras = getIntent().getExtras();
26 | if (extras != null) {
27 | _serverIndex = extras.getInt("ServerIndex");
28 | _server = ServerManager.serverAtIndex(_serverIndex);
29 | }
30 |
31 | Uri serverConfig = getIntent().getData();
32 | if (serverConfig != null) {
33 | ServerManager.addServer();
34 | _serverIndex = ServerManager.count() - 1;
35 | _server = Server.deserializeFromURL(serverConfig.toString());
36 | }
37 |
38 | if (_server != null) {
39 | _editTextName.setText(_server.name());
40 | _editTextURL.setText(_server.url());
41 | }
42 | }
43 |
44 | public void saveClicked(View view) {
45 | _server.setName(_editTextName.getText().toString());
46 | _server.setUrl(_editTextURL.getText().toString());
47 |
48 | ServerManager.replaceServer(_serverIndex, _server);
49 | ServerManager.saveToFile(this);
50 |
51 | finish();
52 | }
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/ServerManager.java:
--------------------------------------------------------------------------------
1 | package org.lf_net.pgpunlocker;
2 |
3 | import java.io.*;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import org.json.JSONArray;
8 | import org.json.JSONObject;
9 |
10 | import android.content.Context;
11 | import android.content.SharedPreferences;
12 | import android.preference.PreferenceManager;
13 |
14 | public class ServerManager {
15 | static public class ServerManagerObserver {
16 | public void onServerAdded(Server server) {
17 | }
18 |
19 | public void onServerReplaced(int serverIndex, Server newServer) {
20 | }
21 |
22 | public void onServerDeleted(int serverIndex) {
23 | }
24 |
25 | public void onSomethingChanged() {
26 | }
27 | }
28 |
29 | private static List _servers = new ArrayList();
30 | private static ServerManagerObserver _observer;
31 |
32 | @SuppressWarnings("deprecation")
33 | public static void loadFromFileOld(Context context) {
34 | try {
35 | _servers.clear();
36 |
37 | FileInputStream fileStream = context.openFileInput("Servers");
38 | BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream));
39 |
40 | String line;
41 |
42 | do {
43 | line = reader.readLine();
44 |
45 | if (line == null) {
46 | break;
47 | }
48 |
49 | Server server = Server.deserialize(line);
50 |
51 | if (server != null) {
52 | _servers.add(server);
53 |
54 | if (_observer != null) {
55 | _observer.onServerAdded(server);
56 | }
57 | }
58 |
59 | } while (line != null);
60 |
61 | reader.close();
62 | fileStream.close();
63 |
64 | if (_observer != null) {
65 | _observer.onSomethingChanged();
66 | }
67 |
68 | } catch (FileNotFoundException e) {
69 | // maybe there was an even older version of PGPAuth installed ...
70 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
71 | String server = prefs.getString("pref_server", "");
72 |
73 | if (server != "") {
74 | // there was an old version \o/
75 | _servers.add(new Server("Migrated from old version", server));
76 | }
77 | } catch (Exception e) {
78 | // shit happens
79 | }
80 | }
81 |
82 | public static void loadFromFile(Context context) {
83 | try {
84 | _servers.clear();
85 |
86 | FileInputStream fileStream = context.openFileInput("Servers.json");
87 | BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream));
88 |
89 | String jsonString = "";
90 | while (reader.ready()) {
91 | jsonString += reader.readLine() + "\n";
92 | }
93 |
94 | JSONObject obj = new JSONObject(jsonString);
95 | JSONArray serverArray = obj.getJSONArray("servers");
96 |
97 | for (int i = 0; i < serverArray.length(); i++) {
98 | Server server = Server.deserializeJSON(serverArray.optJSONObject(i));
99 |
100 | if (server != null && !server.isEmpty()) {
101 | _servers.add(server);
102 | }
103 | }
104 |
105 | reader.close();
106 |
107 | } catch (FileNotFoundException e) {
108 | // old PGPAuth?
109 | loadFromFileOld(context);
110 | } catch (Exception e) {
111 | // a lot of shit happens
112 | }
113 |
114 | }
115 |
116 | public static void saveToFile(Context context) {
117 | try {
118 | FileOutputStream fileStream = context.openFileOutput("Servers.json", Context.MODE_PRIVATE);
119 | BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fileStream));
120 |
121 | JSONArray serversArray = new JSONArray();
122 |
123 | for (int i = 0; i < _servers.size(); i++) {
124 | serversArray.put(i, _servers.get(i).serializeJSON());
125 | }
126 |
127 | JSONObject rootObject = new JSONObject();
128 | rootObject.put("servers", serversArray);
129 |
130 | writer.write(rootObject.toString());
131 |
132 | writer.close();
133 |
134 | // delete old Servers-config - just in case it existed.
135 | context.deleteFile("Servers");
136 | } catch (Exception e) {
137 | // more shit happens
138 | }
139 | }
140 |
141 | public static int count() {
142 | return _servers.size();
143 | }
144 |
145 | public static Server serverAtIndex(int index) {
146 | return _servers.get(index);
147 | }
148 |
149 | public static void addServer() {
150 | _servers.add(new Server("", ""));
151 |
152 | if (_observer != null) {
153 | _observer.onServerAdded(_servers.get(count() - 1));
154 | _observer.onSomethingChanged();
155 | }
156 | }
157 |
158 | public static void replaceServer(int index, Server server) {
159 | _servers.set(index, server);
160 |
161 | if (_observer != null) {
162 | _observer.onServerReplaced(index, server);
163 | _observer.onSomethingChanged();
164 | }
165 | }
166 |
167 | public static void deleteServer(int index) {
168 | _servers.remove(index);
169 |
170 | if (_observer != null) {
171 | _observer.onServerDeleted(index);
172 | _observer.onSomethingChanged();
173 | }
174 | }
175 |
176 | public static void setObserver(ServerManagerObserver observer) {
177 | _observer = observer;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/java/org/lf_net/pgpunlocker/SettingsActivity.java:
--------------------------------------------------------------------------------
1 |
2 | package org.lf_net.pgpunlocker;
3 |
4 | import android.os.Bundle;
5 | import android.preference.PreferenceActivity;
6 |
7 | public class SettingsActivity extends PreferenceActivity {
8 | @SuppressWarnings("deprecation")
9 | @Override
10 | public void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | addPreferencesFromResource(R.xml.preferences);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PGPAuth/PGPAuth_Android/cb430207fce90873c536eaa6da8deb0d8b19166f/PGPAuth/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PGPAuth/PGPAuth_Android/cb430207fce90873c536eaa6da8deb0d8b19166f/PGPAuth/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PGPAuth/PGPAuth_Android/cb430207fce90873c536eaa6da8deb0d8b19166f/PGPAuth/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PGPAuth/PGPAuth_Android/cb430207fce90873c536eaa6da8deb0d8b19166f/PGPAuth/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
16 |
17 |
24 |
25 |
30 |
31 |
36 |
37 |
44 |
45 |
48 |
49 |
57 |
58 |
66 |
67 |
75 |
76 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/layout/activity_server_delete.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
17 |
18 |
24 |
25 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/layout/activity_server_edit.xml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
18 |
19 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
41 |
42 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/layout/listview_item_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
30 |
31 |
32 |
33 |
36 |
37 |
42 |
43 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/menu/mainmenu.xml:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PGP-Key
5 | Der zum Signieren zu verwendende Schlüssel (nur APG)
6 | APG erzwingen
7 | Verwende APG auch wenn OpenKeychain installiert ist.
8 |
9 | Einstellungen
10 | Server entfernen
11 | Über PGPAuth
12 | Server bearbeiten
13 |
14 | Aktion auswählen
15 | Einstellungen
16 | Server hinzufügen
17 | Löschen
18 | Bearbeiten
19 | Teilen
20 |
21 | Weder APG noch OpenKeychain sind installiert!
22 | APG-Version wird nicht unterstützt!
23 | APG kann nur erzwungen werden, wenn es installiert ist ...
24 | Bitte einen Server einstellen!
25 | Der eingestellte Server scheint ungültig zu sein!
26 | Unbekannter Fehler!
27 | Ungültige Einstellungen erkannt! Bitte Einstellungen überprüfen.
28 |
29 | Öffnen
30 | Schließen
31 | Dies kann nicht rückgängig gemacht werden!
32 | Name:
33 | Adresse:
34 | Diese App sendet PGP-signierte Anfragen an einen definierten Server.\nDiese Anfragen bestehen aus einer Aktion (momentan öffnen oder schließen) und einem Zeitstempel, um das Abfangen und erneute Senden der Anfrage zu unterbinden.\n\nDer Server prüft die Aktion der Anfrage, den Zeitstempel, die Gültigkeit der Signatur und die Autorisierung des verwendeten Schlüssels bis er schließlich die Aktion ausführt.
35 |
36 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values-eo/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PGP ŝlosilo
5 | La PGP ŝlosilo estos uzata por subskribi (nur APG)
6 | forto APG
7 |
8 | Agordoj
9 |
10 | Agordoj
11 |
12 | Nek APG ankoraŭ OpenKeychain estas instalitaj!
13 | La APG instalita versio ne estas subtenata!
14 |
15 | ŝlosi
16 | malŝlosi
17 |
18 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Chiave PGP
5 | La chiave usata per segnare (soltanto APG)
6 | Forzare APG
7 | Usa APG anche quando OpenKeychain è installato
8 |
9 | Impostazioni
10 | Cancella server
11 | Su PGPAuth
12 | Modifica server
13 |
14 | Scegli azione
15 | Impostazioni
16 | Nuovo server
17 | Cancella
18 | Modifica
19 | Condividi
20 |
21 | Hai né APG nè OpenPGP Keychani installato!
22 | Versione APG non supportato!
23 | Non è possibile forzare APG quando non è installato ...
24 | Per favore impostare un server!
25 | La tua configurazione server URL sembra d\'essere non valida!
26 | Errore sconosciuto!
27 | Impostazioni non valide. Controllare le preferenze.
28 |
29 | Bloccare
30 | Sbloccare
31 | Questo non può essere annullato!
32 | Nome:
33 | URL:
34 | Questa applicazione invia le richieste firmate PGP ad un server definito.\nLe richieste contengono un\'azione (apertura o chiusura) e un timestamp, per la protezione contro gli attacchi di ripetizione.\n\nIl server quindi controlla l\'azione, il timestamp, la validità della firma e la autorizzazione della chiave utilizzata. Dopo tutti questi controlli, l\'azione viene eseguita dal server.
35 |
36 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PGPキー
5 | 署名に使用するキー (APGのみ)
6 | APG を強制
7 | OpenKeychainがインストールされている場合も、APGを使用します
8 |
9 | 設定
10 | サーバーを削除
11 | PGPAuth について
12 | サーバーを編集
13 |
14 | アクションを選択
15 | 設定
16 | 新しいサーバー
17 | 削除
18 | 編集
19 | 共有
20 |
21 | APG と OpenPGP Keychain のどちらもインストールされていません!
22 | APG のバージョンがサポートされていません!
23 | インストールされていない時にAPGを強制することはできません …
24 | サーバーを設定してください!
25 | 設定されたサーバーのURLが正しくないようです!
26 | 不明なエラー!
27 | 無効な設定が検出されました。設定を確認してください。
28 |
29 | ロック
30 | ロック解除
31 | これは元に戻すことはできません!
32 | 名前:
33 | URL:
34 | このアプリは、定義されたサーバーへPGP署名されたリクエストを送信します。\nこのリクエストは、リプレイ攻撃から保護するために、アクション (現在オープンまたはクローズ) とタイムスタンプが含まれています。\nこのサーバーは、アクション、タイムスタンプ、署名の有効性を確認し、使用されたキーの認証を行います。これらをすべてチェックした後で、サーバーでアクションが実行されます。
35 |
36 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values-ru_RU/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PGPAuth
5 | Homepage
6 | Store
7 | Google+
8 | Twitter
9 | Facebook
10 |
11 |
12 | PGP-Key
13 | The key used for signing (APG only)
14 |
15 | Force APG
16 | Use APG even when OpenKeychain is installed
17 |
18 |
19 | Settings
20 | Delete Server
21 | About PGPAuth
22 | Edit Server
23 |
24 |
25 | Choose action
26 | Settings
27 | New Server
28 | Delete
29 | Edit
30 | Share
31 |
32 |
33 | You have neither APG nor OpenPGP Keychain installed!
34 | APG version is not supported!
35 | You cannot force APG when it is not installed …
36 |
37 | Please set a server!
38 | Your configured server-URL seems to be invalid!
39 | Unknown error!
40 | Invalid settings detected. Please check the preferences.
41 |
42 |
43 | Lock
44 | Unlock
45 | This cannot be undone!
46 | Name:
47 | URL:
48 |
49 | This app sends PGP-signed requests to an defined server.\nThe requests contains an action (currently open or close) and a timestamp, to protect against replay-attacks.\n\nThe server then checks the action, the timestamp, the validity of the signature and the autorization of the used key. After all these checks, the action is done by the server.
50 |
51 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/PGPAuth/src/main/res/xml/preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PGPAuth
2 | [](http://badge.fury.io/gh/PGPAuth%2FPGPAuth_Android)
3 |
4 | ## What is it?
5 | PGPAuth is an App to send PGP signed requests to servers.
6 |
7 | Currently the actions to send are hardcoded to "open" and "close", but this is planned to be configurable on the server. If you want this feature, please comment in #3.
8 |
9 | ## Use cases
10 |
11 | * digital key for doors (i.e. for small organizations or hacker spaces)
12 | * beer taps (configure one server per tap and have IoT beer taps)
13 | * people actually did that
14 |
15 | ## How to use it?
16 |
17 | The smartphones having this app installed need direct access to the server in question. Communication is done over HTTP(S).
18 |
19 | Requests are POSTed to the server. For details, please look at the reference implementation at https://github.com/PGPAuth/PGPAuth_CGI.
20 |
21 |
22 | ## How can I help?
23 | * use it and provide feedback
24 | * help with translation: https://www.transifex.com/projects/p/pgpauth/
25 | * work on reported issues
26 | * write docs
27 | * create implementations for other systems
28 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | }
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:2.3.3'
8 | }
9 | }
10 |
11 | allprojects {
12 | repositories {
13 | jcenter()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':PGPAuth'
2 |
--------------------------------------------------------------------------------