From 4378f8f871f6a47321352f90a59cfaad7f52279b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 9 May 2015 12:24:48 +0200 Subject: linked-ids: code cleanup, handle all lint errors --- .../keychain/pgp/linked/LinkedCookieResource.java | 196 ----------------- .../keychain/pgp/linked/LinkedIdentity.java | 88 -------- .../keychain/pgp/linked/LinkedResource.java | 122 ----------- .../keychain/pgp/linked/RawLinkedIdentity.java | 41 ---- .../keychain/pgp/linked/resources/DnsResource.java | 127 ----------- .../pgp/linked/resources/GenericHttpsResource.java | 98 --------- .../pgp/linked/resources/GithubResource.java | 215 ------------------ .../pgp/linked/resources/TwitterResource.java | 241 --------------------- 8 files changed, 1128 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GithubResource.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java deleted file mode 100644 index 37265b2b5..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedCookieResource.java +++ /dev/null @@ -1,196 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked; - -import android.content.Context; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.params.BasicHttpParams; -import org.json.JSONException; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult; -import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.MalformedURLException; -import java.net.URI; -import java.util.HashMap; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Matcher; - -public abstract class LinkedCookieResource extends LinkedResource { - - protected LinkedCookieResource(Set flags, HashMap params, URI uri) { - super(flags, params, uri); - } - - public URI toUri () { - - StringBuilder b = new StringBuilder(); - b.append("openpgpid+cookie:"); - - // add flags - if (mFlags != null) { - boolean first = true; - for (String flag : mFlags) { - if (!first) { - b.append(";"); - } - first = false; - b.append(flag); - } - } - - // add parameters - if (mParams != null) { - boolean first = true; - for (Entry stringStringEntry : mParams.entrySet()) { - if (!first) { - b.append(";"); - } - first = false; - b.append(stringStringEntry.getKey()).append("=").append(stringStringEntry.getValue()); - } - } - - b.append("@"); - b.append(mSubUri); - - return URI.create(b.toString()); - - } - - public URI getSubUri () { - return mSubUri; - } - - public static String generate (Context context, byte[] fingerprint) { - return String.format("[Verifying my OpenPGP key: openpgp4fpr:%s]", - KeyFormattingUtils.convertFingerprintToHex(fingerprint)); - } - - public static String generatePreview () { - return "[Verifying my OpenPGP key: openpgp4fpr:0x…]"; - } - - public LinkedVerifyResult verify(byte[] fingerprint) { - - OperationLog log = new OperationLog(); - log.add(LogType.MSG_LV, 0); - - // Try to fetch resource. Logs for itself - String res = null; - try { - res = fetchResource(log, 1); - } catch (HttpStatusException e) { - // log verbose output to logcat - Log.e(Constants.TAG, "http error (" + e.getStatus() + "): " + e.getReason()); - log.add(LogType.MSG_LV_FETCH_ERROR, 2, Integer.toString(e.getStatus())); - } catch (MalformedURLException e) { - log.add(LogType.MSG_LV_FETCH_ERROR_URL, 2); - } catch (IOException e) { - Log.e(Constants.TAG, "io error", e); - log.add(LogType.MSG_LV_FETCH_ERROR_IO, 2); - } catch (JSONException e) { - Log.e(Constants.TAG, "json error", e); - log.add(LogType.MSG_LV_FETCH_ERROR_FORMAT, 2); - } - - if (res == null) { - // if this is null, an error was recorded in fetchResource above - return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); - } - - Log.d(Constants.TAG, "Resource data: '" + res + "'"); - - return verifyString(log, 1, res, fingerprint); - - } - - protected abstract String fetchResource (OperationLog log, int indent) throws HttpStatusException, IOException, - JSONException; - - protected Matcher matchResource (OperationLog log, int indent, String res) { - return magicPattern.matcher(res); - } - - protected LinkedVerifyResult verifyString (OperationLog log, int indent, - String res, - byte[] fingerprint) { - - log.add(LogType.MSG_LV_MATCH, indent); - Matcher match = matchResource(log, indent+1, res); - if (!match.find()) { - log.add(LogType.MSG_LV_MATCH_ERROR, 2); - return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); - } - - String candidateFp = match.group(1).toLowerCase(); - String fp = KeyFormattingUtils.convertFingerprintToHex(fingerprint); - if (!fp.equals(candidateFp)) { - log.add(LogType.MSG_LV_FP_ERROR, indent); - return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); - } - log.add(LogType.MSG_LV_FP_OK, indent); - - return new LinkedVerifyResult(LinkedVerifyResult.RESULT_OK, log); - - } - - public static String getResponseBody(HttpRequestBase request) throws IOException, HttpStatusException { - StringBuilder sb = new StringBuilder(); - - request.setHeader("User-Agent", "Open Keychain"); - - DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams()); - HttpResponse response = httpClient.execute(request); - int statusCode = response.getStatusLine().getStatusCode(); - String reason = response.getStatusLine().getReasonPhrase(); - - if (statusCode != 200) { - throw new HttpStatusException(statusCode, reason); - } - - HttpEntity entity = response.getEntity(); - InputStream inputStream = entity.getContent(); - - BufferedReader bReader = new BufferedReader( - new InputStreamReader(inputStream, "UTF-8"), 8); - String line; - while ((line = bReader.readLine()) != null) { - sb.append(line); - } - - return sb.toString(); - } - - public static class HttpStatusException extends Throwable { - - private final int mStatusCode; - private final String mReason; - - HttpStatusException(int statusCode, String reason) { - super("http status " + statusCode + ": " + reason); - mStatusCode = statusCode; - mReason = reason; - } - - public int getStatus() { - return mStatusCode; - } - - public String getReason() { - return mReason; - } - - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java deleted file mode 100644 index ed3031b84..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedIdentity.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked; - -import org.spongycastle.bcpg.UserAttributeSubpacket; -import org.spongycastle.util.Strings; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.IOException; -import java.net.URI; - -import android.content.Context; -import android.support.annotation.DrawableRes; - - -public class LinkedIdentity extends RawLinkedIdentity { - - public final LinkedResource mResource; - - protected LinkedIdentity(URI uri, LinkedResource resource) { - super(uri); - if (resource == null) { - throw new AssertionError("resource must not be null in a LinkedIdentity!"); - } - mResource = resource; - } - - public static RawLinkedIdentity fromAttributeData(byte[] data) throws IOException { - WrappedUserAttribute att = WrappedUserAttribute.fromData(data); - - byte[][] subpackets = att.getSubpackets(); - if (subpackets.length >= 1) { - return fromSubpacketData(subpackets[0]); - } - - throw new IOException("no subpacket data"); - } - - /** This method parses a linked id from a UserAttributeSubpacket, or returns null if the - * subpacket can not be parsed as a valid linked id. - */ - static RawLinkedIdentity fromAttributeSubpacket(UserAttributeSubpacket subpacket) { - if (subpacket.getType() != 101) { - return null; - } - - byte[] data = subpacket.getData(); - - return fromSubpacketData(data); - } - - static RawLinkedIdentity fromSubpacketData(byte[] data) { - - try { - String uriStr = Strings.fromUTF8ByteArray(data); - URI uri = URI.create(uriStr); - - LinkedResource res = LinkedResource.fromUri(uri); - if (res == null) { - return new RawLinkedIdentity(uri); - } - - return new LinkedIdentity(uri, res); - - } catch (IllegalArgumentException e) { - Log.e(Constants.TAG, "error parsing uri in (suspected) linked id packet"); - return null; - } - } - - public static RawLinkedIdentity fromResource (LinkedCookieResource res) { - return new RawLinkedIdentity(res.toUri()); - } - - - public @DrawableRes int getDisplayIcon() { - return mResource.getDisplayIcon(); - } - - public String getDisplayTitle(Context context) { - return mResource.getDisplayTitle(context); - } - - public String getDisplayComment(Context context) { - return mResource.getDisplayComment(context); - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java deleted file mode 100644 index 26fc9f4cf..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/LinkedResource.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource; -import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource; -import org.sufficientlysecure.keychain.pgp.linked.resources.GithubResource; -import org.sufficientlysecure.keychain.pgp.linked.resources.TwitterResource; -import org.sufficientlysecure.keychain.util.Log; - -import java.net.URI; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Pattern; - -import android.content.Context; -import android.content.Intent; -import android.support.annotation.DrawableRes; -import android.support.annotation.StringRes; - - -public abstract class LinkedResource { - - protected final URI mSubUri; - protected final Set mFlags; - protected final HashMap mParams; - - public static Pattern magicPattern = - Pattern.compile("\\[Verifying my (?:Open)?PGP key: openpgp4fpr:([a-zA-Z0-9]+)]"); - - protected LinkedResource(Set flags, HashMap params, URI uri) { - mFlags = flags; - mParams = params; - mSubUri = uri; - } - - public Set getFlags () { - return new HashSet<>(mFlags); - } - - public HashMap getParams () { - return new HashMap<>(mParams); - } - - protected static LinkedCookieResource fromUri (URI uri) { - - if (!"openpgpid+cookie".equals(uri.getScheme())) { - Log.e(Constants.TAG, "unknown uri scheme in (suspected) linked id packet"); - return null; - } - - if (!uri.isOpaque()) { - Log.e(Constants.TAG, "non-opaque uri in (suspected) linked id packet"); - return null; - } - - String specific = uri.getSchemeSpecificPart(); - if (!specific.contains("@")) { - Log.e(Constants.TAG, "unknown uri scheme in linked id packet"); - return null; - } - - String[] pieces = specific.split("@", 2); - URI subUri = URI.create(pieces[1]); - - Set flags = new HashSet<>(); - HashMap params = new HashMap<>(); - if (!pieces[0].isEmpty()) { - String[] rawParams = pieces[0].split(";"); - for (String param : rawParams) { - String[] p = param.split("=", 2); - if (p.length == 1) { - flags.add(param); - } else { - params.put(p[0], p[1]); - } - } - } - - return findResourceType(flags, params, subUri); - - } - - protected static LinkedCookieResource findResourceType (Set flags, - HashMap params, - URI subUri) { - - LinkedCookieResource res; - - res = GenericHttpsResource.create(flags, params, subUri); - if (res != null) { - return res; - } - res = DnsResource.create(flags, params, subUri); - if (res != null) { - return res; - } - res = TwitterResource.create(flags, params, subUri); - if (res != null) { - return res; - } - res = GithubResource.create(flags, params, subUri); - if (res != null) { - return res; - } - - return null; - - } - - public abstract @DrawableRes int getDisplayIcon(); - public abstract @StringRes int getVerifiedText(boolean isSecret); - public abstract String getDisplayTitle(Context context); - public abstract String getDisplayComment(Context context); - public boolean isViewable() { - return false; - } - public Intent getViewIntent() { - return null; - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java deleted file mode 100644 index b3acc6790..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/RawLinkedIdentity.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked; - -import org.spongycastle.util.Strings; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; - -import java.net.URI; - -import android.content.Context; -import android.support.annotation.DrawableRes; - -/** The RawLinkedIdentity contains raw parsed data from a Linked Identity subpacket. */ -public class RawLinkedIdentity { - - public final URI mUri; - - protected RawLinkedIdentity(URI uri) { - mUri = uri; - } - - public byte[] getEncoded() { - return Strings.toUTF8ByteArray(mUri.toASCIIString()); - } - - public WrappedUserAttribute toUserAttribute () { - return WrappedUserAttribute.fromSubpacket(WrappedUserAttribute.UAT_LINKED_ID, getEncoded()); - } - - public @DrawableRes int getDisplayIcon() { - return R.drawable.ic_warning_grey_24dp; - } - - public String getDisplayTitle(Context context) { - return "unknown"; - } - - public String getDisplayComment(Context context) { - return null; - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java deleted file mode 100644 index 3ca71c74b..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/DnsResource.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked.resources; - -import android.content.Context; -import android.support.annotation.DrawableRes; -import android.support.annotation.StringRes; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; - -import java.net.URI; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import de.measite.minidns.Client; -import de.measite.minidns.DNSMessage; -import de.measite.minidns.Question; -import de.measite.minidns.Record; -import de.measite.minidns.Record.CLASS; -import de.measite.minidns.Record.TYPE; -import de.measite.minidns.record.TXT; - -public class DnsResource extends LinkedCookieResource { - - final static Pattern magicPattern = - Pattern.compile("openpgpid\\+cookie=([a-zA-Z0-9]+)(?:#|;)([a-zA-Z0-9]+)"); - - String mFqdn; - CLASS mClass; - TYPE mType; - - DnsResource(Set flags, HashMap params, URI uri, - String fqdn, CLASS clazz, TYPE type) { - super(flags, params, uri); - - mFqdn = fqdn; - mClass = clazz; - mType = type; - } - - public static String generateText (Context context, byte[] fingerprint) { - - return String.format("openpgpid+cookie=%s", - KeyFormattingUtils.convertFingerprintToHex(fingerprint)); - - } - - public static DnsResource createNew (String domain) { - HashSet flags = new HashSet(); - HashMap params = new HashMap(); - URI uri = URI.create("dns:" + domain); - return create(flags, params, uri); - } - - public static DnsResource create(Set flags, HashMap params, URI uri) { - if ( ! ("dns".equals(uri.getScheme()) - && (flags == null || flags.isEmpty()) - && (params == null || params.isEmpty()))) { - return null; - } - - // - String spec = uri.getSchemeSpecificPart(); - // If there are // at the beginning, this includes an authority - we don't support those! - if (spec.startsWith("//")) { - return null; - } - - String[] pieces = spec.split("\\?", 2); - // In either case, part before a ? is the fqdn - String fqdn = pieces[0]; - // There may be a query part - if (pieces.length > 1) { - // TODO parse CLASS and TYPE query paramters - } - - CLASS clazz = CLASS.IN; - TYPE type = TYPE.TXT; - - return new DnsResource(flags, params, uri, fqdn, clazz, type); - } - - public String getFqdn() { - return mFqdn; - } - - @Override - protected String fetchResource (OperationLog log, int indent) { - - Client c = new Client(); - DNSMessage msg = c.query(new Question(mFqdn, mType, mClass)); - Record aw = msg.getAnswers()[0]; - TXT txt = (TXT) aw.getPayload(); - return txt.getText().toLowerCase(); - - } - - @Override - protected Matcher matchResource(OperationLog log, int indent, String res) { - return magicPattern.matcher(res); - } - - @Override - public @StringRes - int getVerifiedText(boolean isSecret) { - return isSecret ? R.string.linked_verified_secret_dns : R.string.linked_verified_dns; - } - - @Override - public @DrawableRes int getDisplayIcon() { - return R.drawable.linked_dns; - } - - @Override - public String getDisplayTitle(Context context) { - return context.getString(R.string.linked_title_dns); - } - - @Override - public String getDisplayComment(Context context) { - return mFqdn; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java deleted file mode 100644 index 8f5c0f8c2..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GenericHttpsResource.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked.resources; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.support.annotation.DrawableRes; -import android.support.annotation.StringRes; - -import org.apache.http.client.methods.HttpGet; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; - -import java.io.IOException; -import java.net.URI; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - - -public class GenericHttpsResource extends LinkedCookieResource { - - GenericHttpsResource(Set flags, HashMap params, URI uri) { - super(flags, params, uri); - } - - public static String generateText (Context context, byte[] fingerprint) { - String cookie = LinkedCookieResource.generate(context, fingerprint); - - return String.format(context.getResources().getString(R.string.linked_id_generic_text), - cookie, "0x" + KeyFormattingUtils.convertFingerprintToHex(fingerprint).substring(24)); - } - - @Override - protected String fetchResource (OperationLog log, int indent) throws HttpStatusException, IOException { - - log.add(LogType.MSG_LV_FETCH, indent, mSubUri.toString()); - indent += 1; - - HttpGet httpGet = new HttpGet(mSubUri); - return getResponseBody(httpGet); - - // log.add(LogType.MSG_LV_FETCH_REDIR, indent, url.toString()); - - } - - public static GenericHttpsResource createNew (URI uri) { - HashSet flags = new HashSet<>(); - flags.add("generic"); - HashMap params = new HashMap<>(); - return create(flags, params, uri); - } - - public static GenericHttpsResource create(Set flags, HashMap params, URI uri) { - if ( ! ("https".equals(uri.getScheme()) - && flags != null && flags.size() == 1 && flags.contains("generic") - && (params == null || params.isEmpty()))) { - return null; - } - return new GenericHttpsResource(flags, params, uri); - } - - @Override - public @DrawableRes - int getDisplayIcon() { - return R.drawable.linked_https; - } - - @Override - public @StringRes - int getVerifiedText(boolean isSecret) { - return isSecret ? R.string.linked_verified_secret_https : R.string.linked_verified_https; - } - - @Override - public String getDisplayTitle(Context context) { - return context.getString(R.string.linked_title_https); - } - - @Override - public String getDisplayComment(Context context) { - return mSubUri.toString(); - } - - @Override - public boolean isViewable() { - return true; - } - - @Override - public Intent getViewIntent() { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(mSubUri.toString())); - return intent; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GithubResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GithubResource.java deleted file mode 100644 index d411395a3..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/GithubResource.java +++ /dev/null @@ -1,215 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked.resources; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.support.annotation.DrawableRes; -import android.support.annotation.StringRes; - -import org.apache.http.client.methods.HttpGet; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - - -public class GithubResource extends LinkedCookieResource { - - final String mHandle; - final String mGistId; - - GithubResource(Set flags, HashMap params, URI uri, - String handle, String gistId) { - super(flags, params, uri); - - mHandle = handle; - mGistId = gistId; - } - - public static String generate(Context context, byte[] fingerprint) { - String cookie = LinkedCookieResource.generate(context, fingerprint); - - return String.format(context.getResources().getString(R.string.linked_id_github_text), cookie); - } - - @Override - protected String fetchResource (OperationLog log, int indent) - throws HttpStatusException, IOException, JSONException { - - log.add(LogType.MSG_LV_FETCH, indent, mSubUri.toString()); - indent += 1; - - HttpGet httpGet = new HttpGet("https://api.github.com/gists/" + mGistId); - String response = getResponseBody(httpGet); - - JSONObject obj = new JSONObject(response); - - JSONObject owner = obj.getJSONObject("owner"); - if (!mHandle.equals(owner.getString("login"))) { - log.add(LogType.MSG_LV_ERROR_GITHUB_HANDLE, indent); - return null; - } - - JSONObject files = obj.getJSONObject("files"); - Iterator it = files.keys(); - if (it.hasNext()) { - // TODO can there be multiple candidates? - JSONObject file = files.getJSONObject(it.next()); - return file.getString("content"); - } - - log.add(LogType.MSG_LV_ERROR_GITHUB_NOT_FOUND, indent); - return null; - - } - - public static GithubResource searchInGithubStream(String screenName, String needle, - OperationLog log) { - - // narrow the needle down to important part - Matcher matcher = magicPattern.matcher(needle); - if (!matcher.find()) { - throw new AssertionError("Needle must contain cookie pattern! This is a programming error, please report."); - } - needle = matcher.group(); - - try { - - JSONArray array; { - HttpGet httpGet = - new HttpGet("https://api.github.com/users/" + screenName + "/gists"); - httpGet.setHeader("Content-Type", "application/json"); - httpGet.setHeader("User-Agent", "OpenKeychain"); - - String response = getResponseBody(httpGet); - array = new JSONArray(response); - } - - for (int i = 0, j = Math.min(array.length(), 5); i < j; i++) { - JSONObject obj = array.getJSONObject(i); - - JSONObject files = obj.getJSONObject("files"); - Iterator it = files.keys(); - if (it.hasNext()) { - - JSONObject file = files.getJSONObject(it.next()); - String type = file.getString("type"); - if (!"text/plain".equals(type)) { - continue; - } - String id = obj.getString("id"); - HttpGet httpGet = new HttpGet("https://api.github.com/gists/" + id); - httpGet.setHeader("User-Agent", "OpenKeychain"); - - JSONObject gistObj = new JSONObject(getResponseBody(httpGet)); - JSONObject gistFiles = gistObj.getJSONObject("files"); - Iterator gistIt = gistFiles.keys(); - if (!gistIt.hasNext()) { - continue; - } - // TODO can there be multiple candidates? - JSONObject gistFile = gistFiles.getJSONObject(gistIt.next()); - String content = gistFile.getString("content"); - if (!content.contains(needle)) { - continue; - } - - URI uri = URI.create("https://gist.github.com/" + screenName + "/" + id); - return create(uri); - } - } - - // update the results with the body of the response - log.add(LogType.MSG_LV_FETCH_ERROR_NOTHING, 2); - return null; - - } catch (HttpStatusException e) { - // log verbose output to logcat - Log.e(Constants.TAG, "http error (" + e.getStatus() + "): " + e.getReason()); - log.add(LogType.MSG_LV_FETCH_ERROR, 2, Integer.toString(e.getStatus())); - } catch (MalformedURLException e) { - log.add(LogType.MSG_LV_FETCH_ERROR_URL, 2); - } catch (IOException e) { - Log.e(Constants.TAG, "io error", e); - log.add(LogType.MSG_LV_FETCH_ERROR_IO, 2); - } catch (JSONException e) { - Log.e(Constants.TAG, "json error", e); - log.add(LogType.MSG_LV_FETCH_ERROR_FORMAT, 2); - } - - return null; - } - - public static GithubResource create(URI uri) { - return create(new HashSet(), new HashMap(), uri); - } - - public static GithubResource create(Set flags, HashMap params, URI uri) { - - // no params or flags - if (!flags.isEmpty() || !params.isEmpty()) { - return null; - } - - Pattern p = Pattern.compile("https://gist\\.github\\.com/([a-zA-Z0-9_]+)/([0-9a-f]+)"); - Matcher match = p.matcher(uri.toString()); - if (!match.matches()) { - return null; - } - String handle = match.group(1); - String gistId = match.group(2); - - return new GithubResource(flags, params, uri, handle, gistId); - - } - - - @Override - public @DrawableRes - int getDisplayIcon() { - return R.drawable.linked_github; - } - - @Override - public @StringRes - int getVerifiedText(boolean isSecret) { - return isSecret ? R.string.linked_verified_secret_github : R.string.linked_verified_github; - } - - @Override - public String getDisplayTitle(Context context) { - return context.getString(R.string.linked_title_github); - } - - @Override - public String getDisplayComment(Context context) { - return mHandle; - } - - @Override - public boolean isViewable() { - return true; - } - - @Override - public Intent getViewIntent() { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(mSubUri.toString())); - return intent; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java deleted file mode 100644 index 935268da6..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/linked/resources/TwitterResource.java +++ /dev/null @@ -1,241 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.linked.resources; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.support.annotation.DrawableRes; -import android.support.annotation.StringRes; -import android.util.Log; - -import com.textuality.keybase.lib.JWalk; - -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class TwitterResource extends LinkedCookieResource { - - final String mHandle; - final String mTweetId; - - TwitterResource(Set flags, HashMap params, - URI uri, String handle, String tweetId) { - super(flags, params, uri); - - mHandle = handle; - mTweetId = tweetId; - } - - public static TwitterResource create(URI uri) { - return create(new HashSet(), new HashMap(), uri); - } - - public static TwitterResource create(Set flags, HashMap params, URI uri) { - - // no params or flags - if (!flags.isEmpty() || !params.isEmpty()) { - return null; - } - - Pattern p = Pattern.compile("https://twitter\\.com/([a-zA-Z0-9_]+)/status/([0-9]+)"); - Matcher match = p.matcher(uri.toString()); - if (!match.matches()) { - return null; - } - String handle = match.group(1); - String tweetId = match.group(2); - - return new TwitterResource(flags, params, uri, handle, tweetId); - - } - - @Override - protected String fetchResource(OperationLog log, int indent) throws IOException, HttpStatusException, - JSONException { - - String authToken; - try { - authToken = getAuthToken(); - } catch (IOException | HttpStatusException | JSONException e) { - log.add(LogType.MSG_LV_ERROR_TWITTER_AUTH, indent); - return null; - } - - HttpGet httpGet = - new HttpGet("https://api.twitter.com/1.1/statuses/show.json" - + "?id=" + mTweetId - + "&include_entities=false"); - - // construct a normal HTTPS request and include an Authorization - // header with the value of Bearer <> - httpGet.setHeader("Authorization", "Bearer " + authToken); - httpGet.setHeader("Content-Type", "application/json"); - - try { - String response = getResponseBody(httpGet); - JSONObject obj = new JSONObject(response); - JSONObject user = obj.getJSONObject("user"); - if (!mHandle.equalsIgnoreCase(user.getString("screen_name"))) { - log.add(LogType.MSG_LV_ERROR_TWITTER_HANDLE, indent); - return null; - } - - // update the results with the body of the response - return obj.getString("text"); - } catch (JSONException e) { - log.add(LogType.MSG_LV_ERROR_TWITTER_RESPONSE, indent); - return null; - } - - } - - @Override - public @DrawableRes int getDisplayIcon() { - return R.drawable.linked_twitter; - } - - @Override - public @StringRes - int getVerifiedText(boolean isSecret) { - return isSecret ? R.string.linked_verified_secret_twitter : R.string.linked_verified_twitter; - } - - @Override - public String getDisplayTitle(Context context) { - return context.getString(R.string.linked_title_twitter); - } - - @Override - public String getDisplayComment(Context context) { - return "@" + mHandle; - } - - @Override - public boolean isViewable() { - return true; - } - - @Override - public Intent getViewIntent() { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(mSubUri.toString())); - return intent; - } - - public static TwitterResource searchInTwitterStream( - String screenName, String needle, OperationLog log) { - - String authToken; - try { - authToken = getAuthToken(); - } catch (IOException | HttpStatusException | JSONException e) { - log.add(LogType.MSG_LV_ERROR_TWITTER_AUTH, 1); - return null; - } - - HttpGet httpGet = - new HttpGet("https://api.twitter.com/1.1/statuses/user_timeline.json" - + "?screen_name=" + screenName - + "&count=15" - + "&include_rts=false" - + "&trim_user=true" - + "&exclude_replies=true"); - - // construct a normal HTTPS request and include an Authorization - // header with the value of Bearer <> - httpGet.setHeader("Authorization", "Bearer " + authToken); - httpGet.setHeader("Content-Type", "application/json"); - - try { - String response = getResponseBody(httpGet); - JSONArray array = new JSONArray(response); - - for (int i = 0; i < array.length(); i++) { - JSONObject obj = array.getJSONObject(i); - String tweet = obj.getString("text"); - if (tweet.contains(needle)) { - String id = obj.getString("id_str"); - URI uri = URI.create("https://twitter.com/" + screenName + "/status/" + id); - return create(uri); - } - } - - // update the results with the body of the response - log.add(LogType.MSG_LV_FETCH_ERROR_NOTHING, 1); - return null; - - } catch (HttpStatusException e) { - // log verbose output to logcat - Log.e(Constants.TAG, "http error (" + e.getStatus() + "): " + e.getReason()); - log.add(LogType.MSG_LV_FETCH_ERROR, 1, Integer.toString(e.getStatus())); - } catch (MalformedURLException e) { - log.add(LogType.MSG_LV_FETCH_ERROR_URL, 1); - } catch (IOException e) { - Log.e(Constants.TAG, "io error", e); - log.add(LogType.MSG_LV_FETCH_ERROR_IO, 1); - } catch (JSONException e) { - Log.e(Constants.TAG, "json error", e); - log.add(LogType.MSG_LV_FETCH_ERROR_FORMAT, 1); - } - - return null; - } - - private static String cachedAuthToken; - - private static String getAuthToken() throws IOException, HttpStatusException, JSONException { - if (cachedAuthToken != null) { - return cachedAuthToken; - } - String base64Encoded = rot13("D293FQqanH0jH29KIaWJER5DomqSGRE2Ewc1LJACn3cbD1c" - + "Fq1bmqSAQAz5MI2cIHKOuo3cPoRAQI1OyqmIVFJS6LHMXq2g6MRLkIj") + "=="; - - // Step 2: Obtain a bearer token - HttpPost httpPost = new HttpPost("https://api.twitter.com/oauth2/token"); - httpPost.setHeader("Authorization", "Basic " + base64Encoded); - httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); - httpPost.setEntity(new StringEntity("grant_type=client_credentials")); - JSONObject rawAuthorization = new JSONObject(getResponseBody(httpPost)); - - // Applications should verify that the value associated with the - // token_type key of the returned object is bearer - if (!"bearer".equals(JWalk.getString(rawAuthorization, "token_type"))) { - throw new JSONException("Expected bearer token in response!"); - } - - cachedAuthToken = rawAuthorization.getString("access_token"); - return cachedAuthToken; - - } - - public static String rot13(String input) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < input.length(); i++) { - char c = input.charAt(i); - if (c >= 'a' && c <= 'm') c += 13; - else if (c >= 'A' && c <= 'M') c += 13; - else if (c >= 'n' && c <= 'z') c -= 13; - else if (c >= 'N' && c <= 'Z') c -= 13; - sb.append(c); - } - return sb.toString(); - } - -} -- cgit v1.2.3