republish pgp signature when changing status

This commit is contained in:
Daniel Gultsch 2016-05-05 13:17:04 +02:00
parent 12704fa640
commit 6e0ec9b924
10 changed files with 97 additions and 25 deletions

View file

@ -2,6 +2,7 @@ package eu.siacs.conversations.crypto;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.util.Log;
import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi;
@ -16,6 +17,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Contact;
@ -299,7 +301,7 @@ public class PgpEngine {
public void generateSignature(final Account account, String status, public void generateSignature(final Account account, String status,
final UiCallback<Account> callback) { final UiCallback<Account> callback) {
if (account.getPgpId() == -1) { if (account.getPgpId() == 0) {
return; return;
} }
Intent params = new Intent(); Intent params = new Intent();
@ -308,6 +310,7 @@ public class PgpEngine {
params.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, account.getPgpId()); params.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, account.getPgpId());
InputStream is = new ByteArrayInputStream(status.getBytes()); InputStream is = new ByteArrayInputStream(status.getBytes());
final OutputStream os = new ByteArrayOutputStream(); final OutputStream os = new ByteArrayOutputStream();
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": signing status message \""+status+"\"");
api.executeApiAsync(params, is, os, new IOpenPgpCallback() { api.executeApiAsync(params, is, os, new IOpenPgpCallback() {
@Override @Override

View file

@ -478,10 +478,10 @@ public class Account extends AbstractEntity {
try { try {
return keys.getLong(KEY_PGP_ID); return keys.getLong(KEY_PGP_ID);
} catch (JSONException e) { } catch (JSONException e) {
return -1; return 0;
} }
} else { } else {
return -1; return 0;
} }
} }

View file

@ -3258,18 +3258,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
return pending; return pending;
} }
public void changeStatus(Account account, Presence.Status status, String statusMessage) { public void changeStatus(Account account, Presence.Status status, String statusMessage, boolean send) {
if (!statusMessage.isEmpty()) { if (!statusMessage.isEmpty()) {
databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage)); databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage));
} }
changeStatusReal(account, status, statusMessage); changeStatusReal(account, status, statusMessage, send);
} }
private void changeStatusReal(Account account, Presence.Status status, String statusMessage) { private void changeStatusReal(Account account, Presence.Status status, String statusMessage, boolean send) {
account.setPresenceStatus(status); account.setPresenceStatus(status);
account.setPresenceStatusMessage(statusMessage); account.setPresenceStatusMessage(statusMessage);
databaseBackend.updateAccount(account); databaseBackend.updateAccount(account);
if (!account.isOptionSet(Account.OPTION_DISABLED)) { if (!account.isOptionSet(Account.OPTION_DISABLED) && send) {
sendPresence(account); sendPresence(account);
} }
} }
@ -3279,7 +3279,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage)); databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage));
} }
for(Account account : getAccounts()) { for(Account account : getAccounts()) {
changeStatusReal(account, status, statusMessage); changeStatusReal(account, status, statusMessage, true);
} }
} }

View file

@ -825,7 +825,7 @@ public class ConversationActivity extends XmppActivity
conversation.setNextEncryption(Message.ENCRYPTION_PGP); conversation.setNextEncryption(Message.ENCRYPTION_PGP);
item.setChecked(true); item.setChecked(true);
} else { } else {
announcePgp(conversation.getAccount(), conversation); announcePgp(conversation.getAccount(), conversation, onOpenPGPKeyPublished);
} }
} else { } else {
showInstallPgpDialog(); showInstallPgpDialog();
@ -1284,7 +1284,7 @@ public class ConversationActivity extends XmppActivity
// associate selected PGP keyId with the account // associate selected PGP keyId with the account
mSelectedConversation.getAccount().setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID)); mSelectedConversation.getAccount().setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID));
// we need to announce the key as described in XEP-027 // we need to announce the key as described in XEP-027
announcePgp(mSelectedConversation.getAccount(), null); announcePgp(mSelectedConversation.getAccount(), null, onOpenPGPKeyPublished);
} else { } else {
choosePgpSignId(mSelectedConversation.getAccount()); choosePgpSignId(mSelectedConversation.getAccount());
} }
@ -1294,7 +1294,7 @@ public class ConversationActivity extends XmppActivity
} }
} else if (requestCode == REQUEST_ANNOUNCE_PGP) { } else if (requestCode == REQUEST_ANNOUNCE_PGP) {
if (xmppConnectionServiceBound) { if (xmppConnectionServiceBound) {
announcePgp(mSelectedConversation.getAccount(), mSelectedConversation); announcePgp(mSelectedConversation.getAccount(), mSelectedConversation, onOpenPGPKeyPublished);
this.mPostponedActivityResult = null; this.mPostponedActivityResult = null;
} else { } else {
this.mPostponedActivityResult = new Pair<>(requestCode, data); this.mPostponedActivityResult = new Pair<>(requestCode, data);

View file

@ -1188,7 +1188,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
return; return;
} }
if (conversation.getAccount().getPgpSignature() == null) { if (conversation.getAccount().getPgpSignature() == null) {
activity.announcePgp(conversation.getAccount(), conversation); activity.announcePgp(conversation.getAccount(), conversation, activity.onOpenPGPKeyPublished);
return; return;
} }
if (conversation.getMode() == Conversation.MODE_SINGLE) { if (conversation.getMode() == Conversation.MODE_SINGLE) {

View file

@ -328,7 +328,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
private void publishOpenPGPPublicKey(Account account) { private void publishOpenPGPPublicKey(Account account) {
if (ManageAccountActivity.this.hasPgp()) { if (ManageAccountActivity.this.hasPgp()) {
choosePgpSignId(selectedAccount); announcePgp(selectedAccount, null, onOpenPGPKeyPublished);
} else { } else {
this.showInstallPgpDialog(); this.showInstallPgpDialog();
} }
@ -360,12 +360,12 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
if (requestCode == REQUEST_CHOOSE_PGP_ID) { if (requestCode == REQUEST_CHOOSE_PGP_ID) {
if (data.getExtras().containsKey(OpenPgpApi.EXTRA_SIGN_KEY_ID)) { if (data.getExtras().containsKey(OpenPgpApi.EXTRA_SIGN_KEY_ID)) {
selectedAccount.setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID)); selectedAccount.setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID));
announcePgp(selectedAccount, null); announcePgp(selectedAccount, null, onOpenPGPKeyPublished);
} else { } else {
choosePgpSignId(selectedAccount); choosePgpSignId(selectedAccount);
} }
} else if (requestCode == REQUEST_ANNOUNCE_PGP) { } else if (requestCode == REQUEST_ANNOUNCE_PGP) {
announcePgp(selectedAccount, null); announcePgp(selectedAccount, null, onOpenPGPKeyPublished);
} }
this.mPostponedActivityResult = null; this.mPostponedActivityResult = null;
} else { } else {

View file

@ -1,7 +1,9 @@
package eu.siacs.conversations.ui; package eu.siacs.conversations.ui;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -18,6 +20,8 @@ import android.widget.TextView;
import android.util.Log; import android.util.Log;
import org.openintents.openpgp.util.OpenPgpApi;
import java.util.List; import java.util.List;
import java.util.concurrent.RunnableFuture; import java.util.concurrent.RunnableFuture;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -42,6 +46,14 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
protected Spinner mShowSpinner; protected Spinner mShowSpinner;
protected CheckBox mAllAccounts; protected CheckBox mAllAccounts;
protected LinearLayout mTemplatesView; protected LinearLayout mTemplatesView;
private Pair<Integer, Intent> mPostponedActivityResult;
private Runnable onPresenceChanged = new Runnable() {
@Override
public void run() {
finish();
}
};
protected void onCreate(final Bundle savedInstanceState) { protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -83,16 +95,37 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
} }
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (xmppConnectionServiceBound && mAccount != null) {
if (requestCode == REQUEST_ANNOUNCE_PGP) {
announcePgp(mAccount, null, onPresenceChanged);
}
this.mPostponedActivityResult = null;
} else {
this.mPostponedActivityResult = new Pair<>(requestCode, data);
}
}
}
private void executeChangePresence() { private void executeChangePresence() {
Presence.Status status = getStatusFromSpinner(); Presence.Status status = getStatusFromSpinner();
boolean allAccounts = mAllAccounts.isChecked(); boolean allAccounts = mAllAccounts.isChecked();
String statusMessage = mStatusMessage.getText().toString().trim(); String statusMessage = mStatusMessage.getText().toString().trim();
if (allAccounts) { if (allAccounts && noAccountUsesPgp()) {
xmppConnectionService.changeStatus(status, statusMessage); xmppConnectionService.changeStatus(status, statusMessage);
} else if (mAccount != null) {
xmppConnectionService.changeStatus(mAccount, status, statusMessage);
}
finish(); finish();
} else if (mAccount != null) {
if (mAccount.getPgpId() == 0) {
xmppConnectionService.changeStatus(mAccount, status, statusMessage, true);
finish();
} else {
xmppConnectionService.changeStatus(mAccount, status, statusMessage, false);
announcePgp(mAccount, null, onPresenceChanged);
}
}
} }
private Presence.Status getStatusFromSpinner() { private Presence.Status getStatusFromSpinner() {
@ -145,6 +178,12 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
mStatusMessage.append(message); mStatusMessage.append(message);
} }
mTemplates = xmppConnectionService.databaseBackend.getPresenceTemplates(); mTemplates = xmppConnectionService.databaseBackend.getPresenceTemplates();
if (this.mPostponedActivityResult != null) {
this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
}
boolean e = noAccountUsesPgp();
mAllAccounts.setEnabled(e);
mAllAccounts.setTextColor(e ? getPrimaryTextColor() : getSecondaryTextColor());
} }
redrawTemplates(); redrawTemplates();
} }

View file

@ -187,6 +187,9 @@ public class SettingsActivity extends XmppActivity implements
|| name.equals("manually_change_presence")) { || name.equals("manually_change_presence")) {
xmppConnectionService.toggleScreenEventReceiver(); xmppConnectionService.toggleScreenEventReceiver();
} }
if (name.equals("manually_change_presence") && !noAccountUsesPgp()) {
Toast.makeText(this, R.string.republish_pgp_keys, Toast.LENGTH_LONG).show();
}
xmppConnectionService.refreshAllPresences(); xmppConnectionService.refreshAllPresences();
} }
} else if (name.equals("dont_trust_system_cas")) { } else if (name.equals("dont_trust_system_cas")) {

View file

@ -68,6 +68,7 @@ import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RunnableFuture;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
@ -118,6 +119,13 @@ public abstract class XmppActivity extends Activity {
protected int mTheme; protected int mTheme;
protected boolean mUsingEnterKey = false; protected boolean mUsingEnterKey = false;
protected Runnable onOpenPGPKeyPublished = new Runnable() {
@Override
public void run() {
Toast.makeText(XmppActivity.this,R.string.openpgp_has_been_published, Toast.LENGTH_SHORT).show();
}
};
private long mLastUiRefresh = 0; private long mLastUiRefresh = 0;
private Handler mRefreshUiHandler = new Handler(); private Handler mRefreshUiHandler = new Handler();
private Runnable mRefreshUiRunnable = new Runnable() { private Runnable mRefreshUiRunnable = new Runnable() {
@ -489,18 +497,23 @@ public abstract class XmppActivity extends Activity {
startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION); startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION);
} }
protected void announcePgp(Account account, final Conversation conversation) { protected void announcePgp(Account account, final Conversation conversation, final Runnable onSuccess) {
if (account.getPgpId() == -1) { if (account.getPgpId() == 0) {
choosePgpSignId(account); choosePgpSignId(account);
} else { } else {
xmppConnectionService.getPgpEngine().generateSignature(account, "", new UiCallback<Account>() { String status = null;
if (manuallyChangePresence()) {
status = account.getPresenceStatusMessage();
}
if (status == null) {
status = "";
}
xmppConnectionService.getPgpEngine().generateSignature(account, status, new UiCallback<Account>() {
@Override @Override
public void userInputRequried(PendingIntent pi, public void userInputRequried(PendingIntent pi, Account account) {
Account account) {
try { try {
startIntentSenderForResult(pi.getIntentSender(), startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
} catch (final SendIntentException ignored) { } catch (final SendIntentException ignored) {
} }
} }
@ -513,6 +526,9 @@ public abstract class XmppActivity extends Activity {
conversation.setNextEncryption(Message.ENCRYPTION_PGP); conversation.setNextEncryption(Message.ENCRYPTION_PGP);
xmppConnectionService.databaseBackend.updateConversation(conversation); xmppConnectionService.databaseBackend.updateConversation(conversation);
} }
if (onSuccess != null) {
runOnUiThread(onSuccess);
}
} }
@Override @Override
@ -523,6 +539,15 @@ public abstract class XmppActivity extends Activity {
} }
} }
protected boolean noAccountUsesPgp() {
for(Account account : xmppConnectionService.getAccounts()) {
if (account.getPgpId() != 0) {
return false;
}
}
return true;
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
protected void setListItemBackgroundOnView(View view) { protected void setListItemBackgroundOnView(View view) {

View file

@ -167,6 +167,8 @@
<string name="mgmt_account_disable">Temporarily disable</string> <string name="mgmt_account_disable">Temporarily disable</string>
<string name="mgmt_account_publish_avatar">Publish avatar</string> <string name="mgmt_account_publish_avatar">Publish avatar</string>
<string name="mgmt_account_publish_pgp">Publish OpenPGP public key</string> <string name="mgmt_account_publish_pgp">Publish OpenPGP public key</string>
<string name="openpgp_has_been_published">OpenPGP public key has been published.</string>
<string name="republish_pgp_keys">Remember to republish your OpenPGP public keys!</string>
<string name="mgmt_account_enable">Enable account</string> <string name="mgmt_account_enable">Enable account</string>
<string name="mgmt_account_are_you_sure">Are you sure?</string> <string name="mgmt_account_are_you_sure">Are you sure?</string>
<string name="mgmt_account_delete_confirm_text">If you delete your account your entire conversation history will be lost</string> <string name="mgmt_account_delete_confirm_text">If you delete your account your entire conversation history will be lost</string>