diff options
Diffstat (limited to 'src')
42 files changed, 0 insertions, 9996 deletions
diff --git a/src/org/jboss/security/srp/SRPParameters.java b/src/org/jboss/security/srp/SRPParameters.java deleted file mode 100644 index 4b188cb3..00000000 --- a/src/org/jboss/security/srp/SRPParameters.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, Red Hat Middleware LLC, and individual contributors - * as indicated by the @author tags. See the copyright.txt file in the - * distribution for a full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.jboss.security.srp; - -import java.io.Serializable; -import java.util.Arrays; - -import org.spongycastle.util.encoders.Base64; - -/** The RFC2945 algorithm session parameters that the client and server -agree to use. In addition to the base RFC2945 parameters, one can choose an -alternate hash algorithm for the private session key. - -@author Scott.Stark@jboss.org -@version $Revision: 57210 $ -*/ -public class SRPParameters implements Cloneable, Serializable -{ -   /** The serial version ID. -    * @since 1.2.4.1 -    */ -   private static final long serialVersionUID = 6438772808805276693L; - -   /** The algorithm safe-prime modulus */ -   public final byte[] N; -   /** The algorithm primitive generator */ -   public final byte[] g; -   /** The random password salt originally used to verify the password */ -   public final byte[] s; -   /** The algorithm to hash the session key to produce K. To be consistent -    with the RFC2945 description this must be SHA_Interleave as implemented -    by the JBossSX security provider. For compatibility with earlier JBossSX -    SRP releases the algorithm must be SHA_ReverseInterleave. This name is -    passed to java.security.MessageDigest.getInstance(). */ -   public final String hashAlgorithm; -   /** The algorithm to use for any encryption of data. -    */ -   public final String cipherAlgorithm; -   /** The cipher intialization vector bytes -    */ -   public byte[] cipherIV; - -   /** Creates a new instance of SRPParameters */ -   public SRPParameters(byte[] N, byte[] g, byte[] s) -   { -      this(N, g, s, "SHA_Interleave", null); -   } -   public SRPParameters(byte[] N, byte[] g, byte[] s, String hashAlgorithm) -   { -      this(N, g, s, hashAlgorithm, null); -   } -   public SRPParameters(byte[] N, byte[] g, byte[] s, String hashAlgorithm, -      String cipherAlgorithm) -   { -      this(N, g, s, hashAlgorithm, cipherAlgorithm, null); -   } -   public SRPParameters(byte[] N, byte[] g, byte[] s, String hashAlgorithm, -      String cipherAlgorithm, byte[] cipherIV) -   { -      this.N = N; -      this.g = g; -      this.s = s; -      if( hashAlgorithm == null ) -         hashAlgorithm = "SHA_Interleave"; -      this.hashAlgorithm = hashAlgorithm; -      this.cipherAlgorithm = cipherAlgorithm; -      this.cipherIV = cipherIV; -   } - -   public Object clone() -   { -      Object clone = null; -      try -      { -          clone = super.clone(); -      } -      catch(CloneNotSupportedException e) -      { -      } -      return clone; -   } - -   public int hashCode() -   { -      int hashCode = hashAlgorithm.hashCode(); -      for(int i = 0; i < N.length; i ++) -         hashCode += N[i]; -      for(int i = 0; i < g.length; i ++) -         hashCode += g[i]; -      for(int i = 0; i < s.length; i ++) -         hashCode += s[i]; -      return hashCode; -   } - -   public boolean equals(Object obj) -   { -      boolean equals = false; -      if( obj instanceof SRPParameters ) -      { -         SRPParameters p = (SRPParameters) obj; -         equals = hashAlgorithm.equals(p.hashAlgorithm); -         if( equals == true ) -            equals = Arrays.equals(N, p.N); -         if( equals == true ) -            equals = Arrays.equals(g, p.g); -         if( equals == true ) -            equals = Arrays.equals(s, p.s); -      } -      return equals; -   } - -   public String toString() -   { -      StringBuffer tmp = new StringBuffer(super.toString()); -      tmp.append('{'); -      tmp.append("N: "); -      tmp.append(Base64.encode(N)); -      tmp.append("|g: "); -      tmp.append(Base64.encode(g)); -      tmp.append("|s: "); -      tmp.append(Base64.encode(s)); -      tmp.append("|hashAlgorithm: "); -      tmp.append(hashAlgorithm); -      tmp.append("|cipherAlgorithm: "); -      tmp.append(cipherAlgorithm); -      tmp.append("|cipherIV: "); -      tmp.append(cipherIV); -      tmp.append('}'); -      return tmp.toString(); -   } -} diff --git a/src/org/spongycastle/util/encoders/Base64.java b/src/org/spongycastle/util/encoders/Base64.java deleted file mode 100644 index 87bd80a0..00000000 --- a/src/org/spongycastle/util/encoders/Base64.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.spongycastle.util.encoders; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -public class Base64 -{ -    private static final Encoder encoder = new Base64Encoder(); -     -    /** -     * encode the input data producing a base 64 encoded byte array. -     * -     * @return a byte array containing the base 64 encoded data. -     */ -    public static byte[] encode( -        byte[]    data) -    { -        int len = (data.length + 2) / 3 * 4; -        ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); -         -        try -        { -            encoder.encode(data, 0, data.length, bOut); -        } -        catch (IOException e) -        { -            throw new RuntimeException("exception encoding base64 string: " + e); -        } -         -        return bOut.toByteArray(); -    } - -    /** -     * Encode the byte data to base 64 writing it to the given output stream. -     * -     * @return the number of bytes produced. -     */ -    public static int encode( -        byte[]                data, -        OutputStream    out) -        throws IOException -    { -        return encoder.encode(data, 0, data.length, out); -    } -     -    /** -     * Encode the byte data to base 64 writing it to the given output stream. -     * -     * @return the number of bytes produced. -     */ -    public static int encode( -        byte[]                data, -        int                    off, -        int                    length, -        OutputStream    out) -        throws IOException -    { -        return encoder.encode(data, off, length, out); -    } -     -    /** -     * decode the base 64 encoded input data. It is assumed the input data is valid. -     * -     * @return a byte array representing the decoded data. -     */ -    public static byte[] decode( -        byte[]    data) -    { -        int len = data.length / 4 * 3; -        ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); -         -        try -        { -            encoder.decode(data, 0, data.length, bOut); -        } -        catch (IOException e) -        { -            throw new RuntimeException("exception decoding base64 string: " + e); -        } -         -        return bOut.toByteArray(); -    } -     -    /** -     * decode the base 64 encoded String data - whitespace will be ignored. -     * -     * @return a byte array representing the decoded data. -     */ -    public static byte[] decode( -        String    data) -    { -        int len = data.length() / 4 * 3; -        ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); -         -        try -        { -            encoder.decode(data, bOut); -        } -        catch (IOException e) -        { -            throw new RuntimeException("exception decoding base64 string: " + e); -        } -         -        return bOut.toByteArray(); -    } -     -    /** -     * decode the base 64 encoded String data writing it to the given output stream, -     * whitespace characters will be ignored. -     * -     * @return the number of bytes produced. -     */ -    public static int decode( -        String                data, -        OutputStream    out) -        throws IOException -    { -        return encoder.decode(data, out); -    } -} diff --git a/src/org/spongycastle/util/encoders/Base64Encoder.java b/src/org/spongycastle/util/encoders/Base64Encoder.java deleted file mode 100644 index 84060707..00000000 --- a/src/org/spongycastle/util/encoders/Base64Encoder.java +++ /dev/null @@ -1,298 +0,0 @@ -package org.spongycastle.util.encoders; - -import java.io.IOException; -import java.io.OutputStream; - -public class Base64Encoder -    implements Encoder -{ -    protected final byte[] encodingTable = -        { -            (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', -            (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', -            (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', -            (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', -            (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', -            (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', -            (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', -            (byte)'v', -            (byte)'w', (byte)'x', (byte)'y', (byte)'z', -            (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', -            (byte)'7', (byte)'8', (byte)'9', -            (byte)'+', (byte)'/' -        }; - -    protected byte    padding = (byte)'='; -     -    /* -     * set up the decoding table. -     */ -    protected final byte[] decodingTable = new byte[128]; - -    protected void initialiseDecodingTable() -    { -        for (int i = 0; i < encodingTable.length; i++) -        { -            decodingTable[encodingTable[i]] = (byte)i; -        } -    } -     -    public Base64Encoder() -    { -        initialiseDecodingTable(); -    } -     -    /** -     * encode the input data producing a base 64 output stream. -     * -     * @return the number of bytes produced. -     */ -    public int encode( -        byte[]                data, -        int                    off, -        int                    length, -        OutputStream    out)  -        throws IOException -    { -        int modulus = length % 3; -        int dataLength = (length - modulus); -        int a1, a2, a3; -         -        for (int i = off; i < off + dataLength; i += 3) -        { -            a1 = data[i] & 0xff; -            a2 = data[i + 1] & 0xff; -            a3 = data[i + 2] & 0xff; - -            out.write(encodingTable[(a1 >>> 2) & 0x3f]); -            out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]); -            out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]); -            out.write(encodingTable[a3 & 0x3f]); -        } - -        /* -         * process the tail end. -         */ -        int    b1, b2, b3; -        int    d1, d2; - -        switch (modulus) -        { -        case 0:        /* nothing left to do */ -            break; -        case 1: -            d1 = data[off + dataLength] & 0xff; -            b1 = (d1 >>> 2) & 0x3f; -            b2 = (d1 << 4) & 0x3f; - -            out.write(encodingTable[b1]); -            out.write(encodingTable[b2]); -            out.write(padding); -            out.write(padding); -            break; -        case 2: -            d1 = data[off + dataLength] & 0xff; -            d2 = data[off + dataLength + 1] & 0xff; - -            b1 = (d1 >>> 2) & 0x3f; -            b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f; -            b3 = (d2 << 2) & 0x3f; - -            out.write(encodingTable[b1]); -            out.write(encodingTable[b2]); -            out.write(encodingTable[b3]); -            out.write(padding); -            break; -        } - -        return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4); -    } - -    private boolean ignore( -        char    c) -    { -        return (c == '\n' || c =='\r' || c == '\t' || c == ' '); -    } -     -    /** -     * decode the base 64 encoded byte data writing it to the given output stream, -     * whitespace characters will be ignored. -     * -     * @return the number of bytes produced. -     */ -    public int decode( -        byte[]          data, -        int             off, -        int             length, -        OutputStream    out) -        throws IOException -    { -        byte    b1, b2, b3, b4; -        int     outLen = 0; -         -        int     end = off + length; -         -        while (end > off) -        { -            if (!ignore((char)data[end - 1])) -            { -                break; -            } -             -            end--; -        } -         -        int  i = off; -        int  finish = end - 4; -         -        i = nextI(data, i, finish); - -        while (i < finish) -        { -            b1 = decodingTable[data[i++]]; -             -            i = nextI(data, i, finish); -             -            b2 = decodingTable[data[i++]]; -             -            i = nextI(data, i, finish); -             -            b3 = decodingTable[data[i++]]; -             -            i = nextI(data, i, finish); -             -            b4 = decodingTable[data[i++]]; - -            out.write((b1 << 2) | (b2 >> 4)); -            out.write((b2 << 4) | (b3 >> 2)); -            out.write((b3 << 6) | b4); -             -            outLen += 3; -             -            i = nextI(data, i, finish); -        } - -        outLen += decodeLastBlock(out, (char)data[end - 4], (char)data[end - 3], (char)data[end - 2], (char)data[end - 1]); -         -        return outLen; -    } - -    private int nextI(byte[] data, int i, int finish) -    { -        while ((i < finish) && ignore((char)data[i])) -        { -            i++; -        } -        return i; -    } -     -    /** -     * decode the base 64 encoded String data writing it to the given output stream, -     * whitespace characters will be ignored. -     * -     * @return the number of bytes produced. -     */ -    public int decode( -        String          data, -        OutputStream    out) -        throws IOException -    { -        byte    b1, b2, b3, b4; -        int     length = 0; -         -        int     end = data.length(); -         -        while (end > 0) -        { -            if (!ignore(data.charAt(end - 1))) -            { -                break; -            } -             -            end--; -        } -         -        int  i = 0; -        int  finish = end - 4; -         -        i = nextI(data, i, finish); -         -        while (i < finish) -        { -            b1 = decodingTable[data.charAt(i++)]; -             -            i = nextI(data, i, finish); -             -            b2 = decodingTable[data.charAt(i++)]; -             -            i = nextI(data, i, finish); -             -            b3 = decodingTable[data.charAt(i++)]; -             -            i = nextI(data, i, finish); -             -            b4 = decodingTable[data.charAt(i++)]; - -            out.write((b1 << 2) | (b2 >> 4)); -            out.write((b2 << 4) | (b3 >> 2)); -            out.write((b3 << 6) | b4); -             -            length += 3; -             -            i = nextI(data, i, finish); -        } - -        length += decodeLastBlock(out, data.charAt(end - 4), data.charAt(end - 3), data.charAt(end - 2), data.charAt(end - 1)); - -        return length; -    } - -    private int decodeLastBlock(OutputStream out, char c1, char c2, char c3, char c4)  -        throws IOException -    { -        byte    b1, b2, b3, b4; -         -        if (c3 == padding) -        { -            b1 = decodingTable[c1]; -            b2 = decodingTable[c2]; - -            out.write((b1 << 2) | (b2 >> 4)); -             -            return 1; -        } -        else if (c4 == padding) -        { -            b1 = decodingTable[c1]; -            b2 = decodingTable[c2]; -            b3 = decodingTable[c3]; - -            out.write((b1 << 2) | (b2 >> 4)); -            out.write((b2 << 4) | (b3 >> 2)); -             -            return 2; -        } -        else -        { -            b1 = decodingTable[c1]; -            b2 = decodingTable[c2]; -            b3 = decodingTable[c3]; -            b4 = decodingTable[c4]; - -            out.write((b1 << 2) | (b2 >> 4)); -            out.write((b2 << 4) | (b3 >> 2)); -            out.write((b3 << 6) | b4); -             -            return 3; -        }  -    } - -    private int nextI(String data, int i, int finish) -    { -        while ((i < finish) && ignore(data.charAt(i))) -        { -            i++; -        } -        return i; -    } -} diff --git a/src/org/spongycastle/util/encoders/Encoder.java b/src/org/spongycastle/util/encoders/Encoder.java deleted file mode 100644 index 106c36b7..00000000 --- a/src/org/spongycastle/util/encoders/Encoder.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.spongycastle.util.encoders; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Encode and decode byte arrays (typically from binary to 7-bit ASCII  - * encodings). - */ -public interface Encoder -{ -    int encode(byte[] data, int off, int length, OutputStream out) throws IOException; -     -    int decode(byte[] data, int off, int length, OutputStream out) throws IOException; - -    int decode(String data, OutputStream out) throws IOException; -} diff --git a/src/org/spongycastle/util/io/pem/PemGenerationException.java b/src/org/spongycastle/util/io/pem/PemGenerationException.java deleted file mode 100644 index 0127ca0c..00000000 --- a/src/org/spongycastle/util/io/pem/PemGenerationException.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.spongycastle.util.io.pem; - -import java.io.IOException; - -@SuppressWarnings("serial") -public class PemGenerationException -    extends IOException -{ -    private Throwable cause; - -    public PemGenerationException(String message, Throwable cause) -    { -        super(message); -        this.cause = cause; -    } - -    public PemGenerationException(String message) -    { -        super(message); -    } - -    public Throwable getCause() -    { -        return cause; -    } -} diff --git a/src/org/spongycastle/util/io/pem/PemHeader.java b/src/org/spongycastle/util/io/pem/PemHeader.java deleted file mode 100644 index 4adb815e..00000000 --- a/src/org/spongycastle/util/io/pem/PemHeader.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.spongycastle.util.io.pem; - -public class PemHeader -{ -    private String name; -    private String value; - -    public PemHeader(String name, String value) -    { -        this.name = name; -        this.value = value; -    } - -    public String getName() -    { -        return name; -    } - -    public String getValue() -    { -        return value; -    } - -    public int hashCode() -    { -        return getHashCode(this.name) + 31 * getHashCode(this.value);     -    } - -    public boolean equals(Object o) -    { -        if (!(o instanceof PemHeader)) -        { -            return false; -        } - -        PemHeader other = (PemHeader)o; - -        return other == this || (isEqual(this.name, other.name) && isEqual(this.value, other.value)); -    } - -    private int getHashCode(String s) -    { -        if (s == null) -        { -            return 1; -        } - -        return s.hashCode(); -    } - -    private boolean isEqual(String s1, String s2) -    { -        if (s1 == s2) -        { -            return true; -        } - -        if (s1 == null || s2 == null) -        { -            return false; -        } - -        return s1.equals(s2); -    } - -} diff --git a/src/org/spongycastle/util/io/pem/PemObject.java b/src/org/spongycastle/util/io/pem/PemObject.java deleted file mode 100644 index 6f7c79c5..00000000 --- a/src/org/spongycastle/util/io/pem/PemObject.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.spongycastle.util.io.pem; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -@SuppressWarnings("all") -public class PemObject -    implements PemObjectGenerator -{ -	private static final List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); - -    private String type; -    private List   headers; -    private byte[] content; - -    /** -     * Generic constructor for object without headers. -     * -     * @param type pem object type. -     * @param content the binary content of the object. -     */ -    public PemObject(String type, byte[] content) -    { -        this(type, EMPTY_LIST, content); -    } - -    /** -     * Generic constructor for object with headers. -     * -     * @param type pem object type. -     * @param headers a list of PemHeader objects. -     * @param content the binary content of the object. -     */ -    public PemObject(String type, List headers, byte[] content) -    { -        this.type = type; -        this.headers = Collections.unmodifiableList(headers); -        this.content = content; -    } - -    public String getType() -    { -        return type; -    } - -    public List getHeaders() -    { -        return headers; -    } - -    public byte[] getContent() -    { -        return content; -    } - -    public PemObject generate() -        throws PemGenerationException -    { -        return this; -    } -} diff --git a/src/org/spongycastle/util/io/pem/PemObjectGenerator.java b/src/org/spongycastle/util/io/pem/PemObjectGenerator.java deleted file mode 100644 index 1a8cea6d..00000000 --- a/src/org/spongycastle/util/io/pem/PemObjectGenerator.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.spongycastle.util.io.pem; - -public interface PemObjectGenerator -{ -    PemObject generate() -        throws PemGenerationException; -} diff --git a/src/org/spongycastle/util/io/pem/PemWriter.java b/src/org/spongycastle/util/io/pem/PemWriter.java deleted file mode 100644 index f5a6a363..00000000 --- a/src/org/spongycastle/util/io/pem/PemWriter.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.spongycastle.util.io.pem; - -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.Writer; -import java.util.Iterator; - -import org.spongycastle.util.encoders.Base64; - -/** - * A generic PEM writer, based on RFC 1421 - */ -@SuppressWarnings("all") -public class PemWriter -    extends BufferedWriter -{ -    private static final int LINE_LENGTH = 64; - -    private final int nlLength; -    private char[]  buf = new char[LINE_LENGTH]; - -    /** -     * Base constructor. -     * -     * @param out output stream to use. -     */ -    public PemWriter(Writer out) -    { -        super(out); - -        String nl = System.getProperty("line.separator"); -        if (nl != null) -        { -            nlLength = nl.length(); -        } -        else -        { -            nlLength = 2; -        } -    } - -    /** -     * Return the number of bytes or characters required to contain the -     * passed in object if it is PEM encoded. -     * -     * @param obj pem object to be output -     * @return an estimate of the number of bytes -     */ -    public int getOutputSize(PemObject obj) -    { -        // BEGIN and END boundaries. -        int size = (2 * (obj.getType().length() + 10 + nlLength)) + 6 + 4; - -        if (!obj.getHeaders().isEmpty()) -        { -            for (Iterator it = obj.getHeaders().iterator(); it.hasNext();) -            { -                PemHeader hdr = (PemHeader)it.next(); - -                size += hdr.getName().length() + ": ".length() + hdr.getValue().length() + nlLength; -            } - -            size += nlLength; -        } - -        // base64 encoding -        int dataLen = ((obj.getContent().length + 2) / 3) * 4; -         -        size += dataLen + (((dataLen + LINE_LENGTH - 1) / LINE_LENGTH) * nlLength); - -        return size; -    } -     -    public void writeObject(PemObjectGenerator objGen) -        throws IOException -    { -        PemObject obj = objGen.generate(); - -        writePreEncapsulationBoundary(obj.getType()); - -        if (!obj.getHeaders().isEmpty()) -        { -            for (Iterator it = obj.getHeaders().iterator(); it.hasNext();) -            { -                PemHeader hdr = (PemHeader)it.next(); - -                this.write(hdr.getName()); -                this.write(": "); -                this.write(hdr.getValue()); -                this.newLine(); -            } - -            this.newLine(); -        } -         -        writeEncoded(obj.getContent()); -        writePostEncapsulationBoundary(obj.getType()); -    } - -    private void writeEncoded(byte[] bytes) -        throws IOException -    { -        bytes = Base64.encode(bytes); - -        for (int i = 0; i < bytes.length; i += buf.length) -        { -            int index = 0; - -            while (index != buf.length) -            { -                if ((i + index) >= bytes.length) -                { -                    break; -                } -                buf[index] = (char)bytes[i + index]; -                index++; -            } -            this.write(buf, 0, index); -            this.newLine(); -        } -    } - -    private void writePreEncapsulationBoundary( -        String type) -        throws IOException -    { -        this.write("-----BEGIN " + type + "-----"); -        this.newLine(); -    } - -    private void writePostEncapsulationBoundary( -        String type) -        throws IOException -    { -        this.write("-----END " + type + "-----"); -        this.newLine(); -    } -} diff --git a/src/se/leap/bitmaskclient/AboutActivity.java b/src/se/leap/bitmaskclient/AboutActivity.java deleted file mode 100644 index 6d025422..00000000 --- a/src/se/leap/bitmaskclient/AboutActivity.java +++ /dev/null @@ -1,40 +0,0 @@ -package se.leap.bitmaskclient; - -import android.app.Activity; -import android.app.Fragment; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import se.leap.bitmaskclient.R; - -public class AboutActivity extends Activity  { -	 -    final public static String TAG = "aboutFragment"; -    final public static int VIEWED = 0; - -    @Override -    protected void onCreate(Bundle savedInstanceState) { -    	super.onCreate(savedInstanceState); -    	setContentView(R.layout.about); -    	TextView ver = (TextView) findViewById(R.id.version); -    	 -    	String version; -    	String name="Openvpn"; -		try { -			PackageInfo packageinfo = getPackageManager().getPackageInfo(getPackageName(), 0); -			version = packageinfo.versionName; -			name = getString(R.string.app); -		} catch (NameNotFoundException e) { -			version = "error fetching version"; -		} - -    	 -    	ver.setText(getString(R.string.version_info,name,version)); -    	setResult(VIEWED); -    } - -} diff --git a/src/se/leap/bitmaskclient/ConfigHelper.java b/src/se/leap/bitmaskclient/ConfigHelper.java deleted file mode 100644 index a8bd3b7a..00000000 --- a/src/se/leap/bitmaskclient/ConfigHelper.java +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package se.leap.bitmaskclient; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.io.InputStream; -import java.security.KeyFactory; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.Context; -import android.content.SharedPreferences; -import android.util.Base64; - -/** - * Stores constants, and implements auxiliary methods used across all LEAP Android classes. - *  - * @author parmegv - * @author MeanderingCode - * - */ -public class ConfigHelper { -    private static KeyStore keystore_trusted; - -    final public static String NG_1024 = -    		"eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3"; -    final public static BigInteger G = new BigInteger("2"); -	 -	public static boolean checkErroneousDownload(String downloaded_string) { -		try { -			if(new JSONObject(downloaded_string).has(ProviderAPI.ERRORS) || downloaded_string.isEmpty()) { -				return true; -			} else { -				return false; -			} -		} catch(JSONException e) { -			return false; -		} -	} - -	/** -	 *  Treat the input as the MSB representation of a number, -	 *  and lop off leading zero elements.  For efficiency, the -	 *  input is simply returned if no leading zeroes are found. -	 *   -	 *  @param in array to be trimmed -	 */ -	public static byte[] trim(byte[] in) { -		if(in.length == 0 || in[0] != 0) -			return in; - -		int len = in.length; -		int i = 1; -		while(in[i] == 0 && i < len) -			++i; -		byte[] ret = new byte[len - i]; -		System.arraycopy(in, i, ret, 0, len - i); -		return ret; -	} -	 -	public static X509Certificate parseX509CertificateFromString(String certificate_string) { -		java.security.cert.Certificate certificate = null; -		CertificateFactory cf; -		try { -			cf = CertificateFactory.getInstance("X.509"); - -			certificate_string = certificate_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); -			byte[] cert_bytes = Base64.decode(certificate_string, Base64.DEFAULT); -			InputStream caInput =  new ByteArrayInputStream(cert_bytes); -			try { -				certificate = cf.generateCertificate(caInput); -				System.out.println("ca=" + ((X509Certificate) certificate).getSubjectDN()); -			} finally { -				caInput.close(); -			} -		} catch (CertificateException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (IOException e) { -			return null; -		} -		 -		return (X509Certificate) certificate; -	} -	 -	protected static RSAPrivateKey parseRsaKeyFromString(String RsaKeyString) { -		RSAPrivateKey key = null; -		try { -			KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); -			 -			RsaKeyString = RsaKeyString.replaceFirst("-----BEGIN RSA PRIVATE KEY-----", "").replaceFirst("-----END RSA PRIVATE KEY-----", ""); -			PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( Base64.decode(RsaKeyString, Base64.DEFAULT) ); -			key = (RSAPrivateKey) kf.generatePrivate(keySpec); -		} catch (InvalidKeySpecException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return null; -		} catch (NoSuchAlgorithmException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return null; -		} catch (NoSuchProviderException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return null; -		} -		 -		return key; -	} - -	/** -	 * Adds a new X509 certificate given its input stream and its provider name -	 * @param provider used to store the certificate in the keystore -	 * @param inputStream from which X509 certificate must be generated. -	 */ -	public static void addTrustedCertificate(String provider, InputStream inputStream) { -		CertificateFactory cf; -		try { -			cf = CertificateFactory.getInstance("X.509"); -			X509Certificate cert = -					(X509Certificate)cf.generateCertificate(inputStream); -			keystore_trusted.setCertificateEntry(provider, cert); -		} catch (CertificateException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (KeyStoreException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} -	} - -	/** -	 * Adds a new X509 certificate given in its string from and using its provider name -	 * @param provider used to store the certificate in the keystore -	 * @param certificate -	 */ -	public static void addTrustedCertificate(String provider, String certificate) { - -		try { -			X509Certificate cert = ConfigHelper.parseX509CertificateFromString(certificate); -			if(keystore_trusted == null) { -				keystore_trusted = KeyStore.getInstance("BKS"); -				keystore_trusted.load(null); -			} -			keystore_trusted.setCertificateEntry(provider, cert); -		} catch (KeyStoreException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (NoSuchAlgorithmException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (CertificateException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (IOException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} -	} -	 -	/** -	 * @return class wide keystore -	 */ -	public static KeyStore getKeystore() { -		return keystore_trusted; -	} -} diff --git a/src/se/leap/bitmaskclient/ConfigurationWizard.java b/src/se/leap/bitmaskclient/ConfigurationWizard.java deleted file mode 100644 index f0aac40b..00000000 --- a/src/se/leap/bitmaskclient/ConfigurationWizard.java +++ /dev/null @@ -1,581 +0,0 @@ -/**
 - * Copyright (c) 2013 LEAP Encryption Access Project and contributers
 - * 
 - * This program is free software: you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation, either version 3 of the License, or
 - * (at your option) any later version.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
 - */
 - package se.leap.bitmaskclient;
 -
 - - - -
 -
 -import android.app.Activity;
 -import android.app.DialogFragment;
 -import android.app.Fragment;
 -import android.app.FragmentManager;
 -import android.app.FragmentTransaction;
 -import android.content.BroadcastReceiver;
 -import android.content.Context;
 -import android.content.Intent;
 -import android.content.IntentFilter;
 -import android.content.SharedPreferences;
 -import android.content.res.AssetManager;
 -import android.os.Bundle;
 -import android.os.Handler;
 -import android.util.Log;
 -import android.view.Display;
 -import android.view.Menu;
 -import android.view.MenuItem;
 -import android.view.View.MeasureSpec;
 -import android.view.View;
 -import android.view.ViewGroup;
 -import android.view.WindowManager;
 -import android.widget.ListAdapter;
 -import android.widget.ListView;
 -import android.widget.ProgressBar;
 -import android.widget.ProgressBar;
 -import android.widget.RelativeLayout;
 -import android.widget.TextView;
 -import java.io.IOException;
 -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Iterator;
 -import org.json.JSONException;
 -import org.json.JSONObject;
 -import se.leap.bitmaskclient.DownloadFailedDialog.DownloadFailedDialogInterface; -import se.leap.bitmaskclient.NewProviderDialog.NewProviderDialogInterface; -import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; -import se.leap.bitmaskclient.ProviderDetailFragment.ProviderDetailFragmentInterface; -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; -import se.leap.bitmaskclient.R; -
 -/**
 - * Activity that builds and shows the list of known available providers.
 - * 
 - * It also allows the user to enter custom providers with a button.
 - * 
 - * @author parmegv
 - *
 - */
 -public class ConfigurationWizard extends Activity
 -implements ProviderListFragment.Callbacks, NewProviderDialogInterface, ProviderDetailFragmentInterface, DownloadFailedDialogInterface, Receiver {
 -
 -	private ProgressBar mProgressBar;
 -	private TextView progressbar_description;
 -	private ProviderListFragment provider_list_fragment;
 -	private Intent mConfigState = new Intent();
 -	
 -	final public static String TAG = "se.leap.bitmaskclient.ConfigurationWizard";
 -	final public static String TYPE_OF_CERTIFICATE = "type_of_certificate";
 -	final public static String ANON_CERTIFICATE = "anon_certificate";
 -	final public static String AUTHED_CERTIFICATE = "authed_certificate";
 -
 -	final protected static String PROVIDER_SET = "PROVIDER SET";
 -	final protected static String SERVICES_RETRIEVED = "SERVICES RETRIEVED";
 -    
 -    public ProviderAPIResultReceiver providerAPI_result_receiver;
 -    private ProviderAPIBroadcastReceiver_Update providerAPI_broadcast_receiver_update; - -    private static SharedPreferences preferences;
 -    private static boolean setting_up_provider = false; -    
 -    @Override
 -    protected void onCreate(Bundle savedInstanceState) {
 -        super.onCreate(savedInstanceState);
 -	    preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE);
 -        
 -        setContentView(R.layout.configuration_wizard_activity);
 -	    mProgressBar = (ProgressBar) findViewById(R.id.progressbar_configuration_wizard);
 -	    mProgressBar.setVisibility(ProgressBar.INVISIBLE);
 -	    progressbar_description = (TextView) findViewById(R.id.progressbar_description);
 -	    progressbar_description.setVisibility(TextView.INVISIBLE);
 -        providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler());
 -        providerAPI_result_receiver.setReceiver(this);
 -	    providerAPI_broadcast_receiver_update = new ProviderAPIBroadcastReceiver_Update();
 -	    IntentFilter update_intent_filter = new IntentFilter(ProviderAPI.UPDATE_PROGRESSBAR);
 -	    update_intent_filter.addCategory(Intent.CATEGORY_DEFAULT);
 -	    registerReceiver(providerAPI_broadcast_receiver_update, update_intent_filter);
 -
 -	    loadPreseededProviders();
 -        
 -        // Only create our fragments if we're not restoring a saved instance
 -        if ( savedInstanceState == null ){
 -        	// TODO Some welcome screen?
 -        	// We will need better flow control when we have more Fragments (e.g. user auth)
 -        	provider_list_fragment = ProviderListFragment.newInstance();
 -    		Bundle arguments = new Bundle();
 -    		int configuration_wizard_request_code = getIntent().getIntExtra(Dashboard.REQUEST_CODE, -1);
 -    		if(configuration_wizard_request_code == Dashboard.SWITCH_PROVIDER) {
 -    			arguments.putBoolean(ProviderListFragment.SHOW_ALL_PROVIDERS, true);
 -    		}
 -			provider_list_fragment.setArguments(arguments);
 -
 -    		FragmentManager fragmentManager = getFragmentManager();
 -    		fragmentManager.beginTransaction()
 -    		.replace(R.id.configuration_wizard_layout, provider_list_fragment, ProviderListFragment.TAG)
 -    		.commit();
 -        }
 -
 -        // TODO: If exposing deep links into your app, handle intents here.
 -    }
 -
 -	@Override
 -	protected void onDestroy() {
 -		super.onDestroy();
 -		unregisterReceiver(providerAPI_broadcast_receiver_update);
 -	}
 -
 -    public void refreshProviderList(int top_padding) {
 -    	ProviderListFragment new_provider_list_fragment = new ProviderListFragment();
 -		Bundle top_padding_bundle = new Bundle();
 -		top_padding_bundle.putInt(ProviderListFragment.TOP_PADDING, top_padding);
 -		new_provider_list_fragment.setArguments(top_padding_bundle);
 -		
 -		FragmentManager fragmentManager = getFragmentManager();
 -		fragmentManager.beginTransaction()
 -		.replace(R.id.configuration_wizard_layout, new_provider_list_fragment, ProviderListFragment.TAG)
 -		.commit();
 -    }
 -    
 -	@Override
 -	public void onReceiveResult(int resultCode, Bundle resultData) {
 -		if(resultCode == ProviderAPI.PROVIDER_OK) {
 -				mConfigState.setAction(PROVIDER_SET);
 -
 -				if (preferences.getBoolean(EIP.ALLOWED_ANON, false)){
 -					mConfigState.putExtra(SERVICES_RETRIEVED, true);
 -					downloadAnonCert();
 -				} else {
 -					mProgressBar.incrementProgressBy(1);
 -				    mProgressBar.setVisibility(ProgressBar.GONE);
 -				    progressbar_description.setVisibility(TextView.GONE);
 -					setResult(RESULT_OK); -					showProviderDetails(getCurrentFocus());
 -				} -		} else if(resultCode == ProviderAPI.PROVIDER_NOK) {
 -			//refreshProviderList(0); -			String reason_to_fail = resultData.getString(ProviderAPI.ERRORS);
 -			showDownloadFailedDialog(getCurrentFocus(), reason_to_fail);
 -			mProgressBar.setVisibility(ProgressBar.GONE);
 -			progressbar_description.setVisibility(TextView.GONE); -			preferences.edit().remove(Provider.KEY).commit();
 -			setting_up_provider = false; -			setResult(RESULT_CANCELED, mConfigState);
 -		}
 -		else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) {
 -			mProgressBar.incrementProgressBy(1);
 -		    mProgressBar.setVisibility(ProgressBar.GONE);
 -		    progressbar_description.setVisibility(TextView.GONE);
 -		    //refreshProviderList(0);
 -		    setResult(RESULT_OK);
 -		    showProviderDetails(getCurrentFocus());
 -		} else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) {
 -			//refreshProviderList(0);
 -			mProgressBar.setVisibility(ProgressBar.GONE);
 -		    progressbar_description.setVisibility(TextView.GONE);
 -			//Toast.makeText(getApplicationContext(), R.string.incorrectly_downloaded_certificate_message, Toast.LENGTH_LONG).show();
 -        	setResult(RESULT_CANCELED, mConfigState);
 -		} else if(resultCode == AboutActivity.VIEWED) { -		    // Do nothing, right now -		    // I need this for CW to wait for the About activity to end before going back to Dashboard. -		} -	}
 -
 -	/**
 -     * Callback method from {@link ProviderListFragment.Callbacks}
 -     * indicating that the item with the given ID was selected.
 -     */
 -    @Override
 -    public void onItemSelected(String id) {
 -	    //TODO Code 2 pane view
 -	//	resetOldConnection();
 -	    ProviderItem selected_provider = getProvider(id);
 -	    int provider_index = getProviderIndex(id);
 - - -	    startProgressBar(provider_index+1); -	    provider_list_fragment.hideAllBut(provider_index); - -	    boolean danger_on = true; -	    if(preferences.contains(ProviderItem.DANGER_ON)) -	    	danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, false); -	    setUpProvider(selected_provider.providerMainUrl(), danger_on); -    }
 -    
 -    @Override
 -    public void onBackPressed() {
 -    	if(setting_up_provider) { -    		stopSettingUpProvider(); -    	} else {
 -    		usualBackButton(); -    	} -    } -    
 -    private void stopSettingUpProvider() {
 -		ProviderAPI.stop();
 -		mProgressBar.setVisibility(ProgressBar.GONE);
 -		mProgressBar.setProgress(0);
 -		progressbar_description.setVisibility(TextView.GONE);
 -		getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit().remove(Provider.KEY).commit();
 -    	setting_up_provider = false;
 -	showAllProviders(); -    }
 -    
 -    private void usualBackButton() {
 -		try {
 -			boolean is_provider_set_up = new JSONObject(preferences.getString(Provider.KEY, "no provider")) != null ? true : false;
 -			boolean is_provider_set_up_truly = new JSONObject(preferences.getString(Provider.KEY, "no provider")).length() != 0 ? true : false;
 -			if(!is_provider_set_up || !is_provider_set_up_truly) {
 -				askDashboardToQuitApp();
 -			} else {
 -				setResult(RESULT_OK);
 -			}
 -		} catch (JSONException e) {
 -			askDashboardToQuitApp();
 -			super.onBackPressed();
 -			e.printStackTrace();
 -		}
 -		super.onBackPressed();
 -    }
 -    private void askDashboardToQuitApp() {
 -		Intent ask_quit = new Intent();
 -		ask_quit.putExtra(Dashboard.ACTION_QUIT, Dashboard.ACTION_QUIT);
 -		setResult(RESULT_CANCELED, ask_quit);
 -    }
 -
 -    private ProviderItem getProvider(String name) {
 -	    Iterator<ProviderItem> providers_iterator = ProviderListContent.ITEMS.iterator();
 -	    while(providers_iterator.hasNext()) {
 -		    ProviderItem provider = providers_iterator.next();
 -		    if(provider.name().equalsIgnoreCase(name)) {
 -			    return provider;
 -		    }
 -	    }
 -	    return null;
 -    }
 -    
 -    private String getId(String provider_main_url_string) { -	try { -	URL provider_url = new URL(provider_main_url_string); -	URL aux_provider_url; -	Iterator<ProviderItem> providers_iterator = ProviderListContent.ITEMS.iterator(); -	while(providers_iterator.hasNext()) { -	    ProviderItem provider = providers_iterator.next(); -	    aux_provider_url = new URL(provider.providerMainUrl()); -	    if(isSameURL(provider_url, aux_provider_url)) { -		return provider.name(); -	    } -	} -	} catch (MalformedURLException e) { -	    e.printStackTrace(); -	} -	return ""; -    }
 - -    /** -     * Checks, whether 2 urls are pointing to the same location. -     * -     * @param url a url -     * @param baseUrl an other url, that should be compared. -     * @return true, if the urls point to the same host and port and use the  -     *         same protocol, false otherwise. -     */ -    private boolean isSameURL(final URL url, final URL baseUrl) { -	if (!url.getProtocol().equals(baseUrl.getProtocol())) { -	    return false; -	} -	if (!url.getHost().equals(baseUrl.getHost())) { -	    return false; -	} -	if (url.getPort() != baseUrl.getPort()) { -	    return false; -	} -	return true; -    } -	
 -	private void startProgressBar() {
 -	    mProgressBar.setVisibility(ProgressBar.VISIBLE);
 -	    mProgressBar.setProgress(0);
 -	    mProgressBar.setMax(3);
 -	}
 -	
 -	private void startProgressBar(int list_item_index) {
 -	    mProgressBar.setVisibility(ProgressBar.VISIBLE);
 -	    progressbar_description.setVisibility(TextView.VISIBLE);
 -	    mProgressBar.setProgress(0);
 -	    mProgressBar.setMax(3);
 -	    int measured_height = listItemHeight(list_item_index);
 -	    mProgressBar.setTranslationY(measured_height);
 -	    progressbar_description.setTranslationY(measured_height + mProgressBar.getHeight());
 -	}
 -
 -    private int getProviderIndex(String id) {
 -    	int index = 0;
 -	    Iterator<ProviderItem> providers_iterator = ProviderListContent.ITEMS.iterator();
 -	    while(providers_iterator.hasNext()) {
 -		    ProviderItem provider = providers_iterator.next();
 -		    if(provider.name().equalsIgnoreCase(id)) {
 -			    break;
 -		    } else index++; -	    }
 -	    return index;
 -    }
 -    
 -    private int listItemHeight(int list_item_index) {
 -        ListView provider_list_view = (ListView)findViewById(android.R.id.list);
 -        ListAdapter provider_list_adapter = provider_list_view.getAdapter();
 -        View listItem = provider_list_adapter.getView(0, null, provider_list_view);
 -        listItem.setLayoutParams(new RelativeLayout.LayoutParams(
 -                    RelativeLayout.LayoutParams.WRAP_CONTENT,
 -                    RelativeLayout.LayoutParams.WRAP_CONTENT));
 -        WindowManager wm = (WindowManager) getApplicationContext()
 -                    .getSystemService(Context.WINDOW_SERVICE);
 -        Display display = wm.getDefaultDisplay();
 -        int screenWidth = display.getWidth(); // deprecated
 -
 -        int listViewWidth = screenWidth - 10 - 10;
 -        int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth,
 -                    MeasureSpec.AT_MOST);
 -        listItem.measure(widthSpec, 0);
 -
 -        return listItem.getMeasuredHeight();
 -}
 -	
 -    /**
 -     * Loads providers data from url file contained in the project 
 -     * @return true if the file was read correctly
 -     */
 -    private boolean loadPreseededProviders() {
 -    	boolean loaded_preseeded_providers = false;
 -        AssetManager asset_manager = getAssets();
 -        String[] urls_filepaths = null;
 -		try {
 -			String url_files_folder = "urls";
 -			//TODO Put that folder in a better place (also inside the "for")
 -			urls_filepaths = asset_manager.list(url_files_folder); 
 -			String provider_name = "";
 -	        for(String url_filepath : urls_filepaths)
 -	        {
 -	        	boolean custom = false;
 -	        	provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString();
 -	        	if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list
 -	        		ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath))); -	        	loaded_preseeded_providers = true;
 -	        }
 -		} catch (IOException e) {
 -			loaded_preseeded_providers = false;
 -		}
 -		
 -		return loaded_preseeded_providers;
 -	}
 -	
 -	/**
 -	 * Asks ProviderAPI to download an anonymous (anon) VPN certificate.
 -	 */
 -	private void downloadAnonCert() {
 -		Intent provider_API_command = new Intent(this, ProviderAPI.class);
 -
 -		Bundle parameters = new Bundle();
 -
 -		parameters.putString(TYPE_OF_CERTIFICATE, ANON_CERTIFICATE);
 -
 -		provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE);
 -		provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
 -		provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
 -
 -		startService(provider_API_command);
 -	}
 -	
 -	/**
 -	 * Open the new provider dialog
 -	 */
 -	public void addAndSelectNewProvider() {
 -		FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
 -		Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG);
 -		if (previous_new_provider_dialog != null) {
 -			fragment_transaction.remove(previous_new_provider_dialog);
 -		}
 -		fragment_transaction.addToBackStack(null);
 -		
 -		DialogFragment newFragment = NewProviderDialog.newInstance();
 -		newFragment.show(fragment_transaction, NewProviderDialog.TAG);
 -	}
 -	
 -	/**
 -	 * Open the new provider dialog with data
 -	 */
 -	public void addAndSelectNewProvider(String main_url, boolean danger_on) {
 -		FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
 -		Fragment previous_new_provider_dialog = getFragmentManager().findFragmentByTag(NewProviderDialog.TAG);
 -		if (previous_new_provider_dialog != null) {
 -			fragment_transaction.remove(previous_new_provider_dialog);
 -		}
 -		
 -		DialogFragment newFragment = NewProviderDialog.newInstance();
 -		Bundle data = new Bundle();
 -		data.putString(Provider.MAIN_URL, main_url);
 -		data.putBoolean(ProviderItem.DANGER_ON, danger_on);
 -		newFragment.setArguments(data);
 -		newFragment.show(fragment_transaction, NewProviderDialog.TAG);
 -	}
 -	
 -	/**
 -	 * Once selected a provider, this fragment offers the user to log in, 
 -	 * use it anonymously (if possible) 
 -	 * or cancel his/her election pressing the back button.
 -	 * @param view
 -	 * @param reason_to_fail 
 -	 */
 -	public void showDownloadFailedDialog(View view, String reason_to_fail) {
 -		FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
 -		Fragment previous_provider_details_dialog = getFragmentManager().findFragmentByTag(DownloadFailedDialog.TAG);
 -		if (previous_provider_details_dialog != null) {
 -			fragment_transaction.remove(previous_provider_details_dialog);
 -		}
 -		fragment_transaction.addToBackStack(null);
 -		
 -		DialogFragment newFragment = DownloadFailedDialog.newInstance(reason_to_fail);
 -		newFragment.show(fragment_transaction, DownloadFailedDialog.TAG);
 -	}
 -	
 -	/**
 -	 * Once selected a provider, this fragment offers the user to log in, 
 -	 * use it anonymously (if possible) 
 -	 * or cancel his/her election pressing the back button.
 -	 * @param view
 -	 */
 -	public void showProviderDetails(View view) {
 -		if(setting_up_provider) {
 -			FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
 -			Fragment previous_provider_details_dialog = getFragmentManager().findFragmentByTag(ProviderDetailFragment.TAG);
 -			if (previous_provider_details_dialog != null) {
 -				fragment_transaction.remove(previous_provider_details_dialog);
 -			}
 -			fragment_transaction.addToBackStack(null);
 -
 -			DialogFragment newFragment = ProviderDetailFragment.newInstance();
 -			newFragment.show(fragment_transaction, ProviderDetailFragment.TAG);
 -		}
 -	}
 -
 -	public void showAndSelectProvider(String provider_main_url, boolean danger_on) {
 -	    if(getId(provider_main_url).isEmpty()) -		showProvider(provider_main_url, danger_on);
 -	    autoSelectProvider(provider_main_url, danger_on); -	}
 -	
 -	private void showProvider(final String provider_main_url, final boolean danger_on) {
 -		String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_");
 -		ProviderItem added_provider = new ProviderItem(provider_name, provider_main_url);
 -		provider_list_fragment.addItem(added_provider);
 -	}
 -	
 -	private void autoSelectProvider(String provider_main_url, boolean danger_on) {
 -		getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(ProviderItem.DANGER_ON, danger_on).commit();
 -		onItemSelected(getId(provider_main_url));
 -	}
 -	
 -	/**
 -	 * Asks ProviderAPI to download a new provider.json file
 -	 * @param provider_name
 -	 * @param provider_main_url
 -	 * @param danger_on tells if HTTPS client should bypass certificate errors
 -	 */
 -	public void setUpProvider(String provider_main_url, boolean danger_on) {
 -		Intent provider_API_command = new Intent(this, ProviderAPI.class);
 -		Bundle parameters = new Bundle();
 -		parameters.putString(Provider.MAIN_URL, provider_main_url);
 -		parameters.putBoolean(ProviderItem.DANGER_ON, danger_on);
 -
 -		provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER);
 -		provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
 -		provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - -		startService(provider_API_command);
 -		setting_up_provider = true; -	} - -	public void retrySetUpProvider() { -		cancelSettingUpProvider(); -		if(!ProviderAPI.caCertDownloaded()) { -			addAndSelectNewProvider(ProviderAPI.lastProviderMainUrl(), ProviderAPI.lastDangerOn()); -		} else { -			Intent provider_API_command = new Intent(this, ProviderAPI.class); - -			provider_API_command.setAction(ProviderAPI.SET_UP_PROVIDER); -			provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); - -			startService(provider_API_command); -		} -	} -	@Override
 -	public boolean onCreateOptionsMenu(Menu menu) {
 -		getMenuInflater().inflate(R.menu.configuration_wizard_activity, menu);
 -		return true;
 -	}
 -	
 -	@Override
 -	public boolean onOptionsItemSelected(MenuItem item){
 -		switch (item.getItemId()){
 -		case R.id.about_leap: -		    startActivityForResult(new Intent(this, AboutActivity.class), 0); -			return true; -		case R.id.new_provider:
 -			addAndSelectNewProvider();
 -			return true;
 -		default:
 -			return super.onOptionsItemSelected(item);
 -		}
 -	}
 -		
 -	public void showAllProviders() {
 -		provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG);
 -		if(provider_list_fragment != null)
 -			provider_list_fragment.unhideAll();
 -	}
 -	
 -	public void cancelSettingUpProvider() {
 -		provider_list_fragment = (ProviderListFragment) getFragmentManager().findFragmentByTag(ProviderListFragment.TAG);
 -		if(provider_list_fragment != null && preferences.contains(ProviderItem.DANGER_ON)) {
 -			provider_list_fragment.removeLastItem();
 -		}
 -		preferences.edit().remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit();
 -	}
 -
 -	@Override
 -	public void login() {
 -		Intent ask_login = new Intent();
 -		ask_login.putExtra(LogInDialog.VERB, LogInDialog.VERB);
 -		setResult(RESULT_OK, ask_login);
 -		setting_up_provider = false;
 -		finish();
 -	}
 -
 -	@Override
 -	public void use_anonymously() {
 -		setResult(RESULT_OK);
 -		setting_up_provider = false;
 -		finish();
 -	}
 -
 -	public class ProviderAPIBroadcastReceiver_Update extends BroadcastReceiver {
 -
 -		@Override
 -		public void onReceive(Context context, Intent intent) {
 -			int update = intent.getIntExtra(ProviderAPI.CURRENT_PROGRESS, 0);
 -			mProgressBar.setProgress(update);
 -		}
 -	}
 -}
 diff --git a/src/se/leap/bitmaskclient/Dashboard.java b/src/se/leap/bitmaskclient/Dashboard.java deleted file mode 100644 index b388b84a..00000000 --- a/src/se/leap/bitmaskclient/Dashboard.java +++ /dev/null @@ -1,479 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - package se.leap.bitmaskclient; - -import org.json.JSONException; -import org.json.JSONObject; - -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentManager; -import android.app.FragmentTransaction; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; - -/** - * The main user facing Activity of LEAP Android, consisting of status, controls, - * and access to preferences. - *  - * @author Sean Leonard <meanderingcode@aetherislands.net> - * @author parmegv - */ -public class Dashboard extends Activity implements LogInDialog.LogInDialogInterface,Receiver { - -	protected static final int CONFIGURE_LEAP = 0; -	protected static final int SWITCH_PROVIDER = 1; - -    final public static String SHARED_PREFERENCES = "LEAPPreferences"; -    final public static String ACTION_QUIT = "quit"; -	public static final String REQUEST_CODE = "request_code"; -	 -	private ProgressBar mProgressBar; -	private TextView eipStatus; -	private static Context app; -	private static SharedPreferences preferences; -	private static Provider provider; - -	private TextView providerNameTV; - -	private boolean authed_eip = false; - -    public ProviderAPIResultReceiver providerAPI_result_receiver; - -	@Override -	protected void onCreate(Bundle savedInstanceState) { -		super.onCreate(savedInstanceState); -		 -		app = this; -		 -		PRNGFixes.apply(); -	//	mProgressBar = (ProgressBar) findViewById(R.id.progressbar_dashboard); -	//    mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); -	//	eipStatus = (TextView) findViewById(R.id.eipStatus); - -	    mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); -	     -	    preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); - -	    authed_eip = preferences.getBoolean(EIP.AUTHED_EIP, false); -		if (preferences.getString(Provider.KEY, "").isEmpty()) -			startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); -		else -			buildDashboard(); -	} - -	@Override -	protected void onDestroy() { -		super.onDestroy(); -	} -	 -	@Override -	protected void onActivityResult(int requestCode, int resultCode, Intent data){ -		if ( requestCode == CONFIGURE_LEAP || requestCode == SWITCH_PROVIDER) { -		// It should be equivalent: if ( (requestCode == CONFIGURE_LEAP) || (data!= null && data.hasExtra(STOP_FIRST))) { -			if ( resultCode == RESULT_OK ){ -				getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(EIP.PARSED_SERIAL, 0).commit(); -				getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); -				Intent updateEIP = new Intent(getApplicationContext(), EIP.class); -				updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE); -				startService(updateEIP); -				buildDashboard(); -				invalidateOptionsMenu(); -				if(data != null && data.hasExtra(LogInDialog.VERB)) { -					View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); -					logInDialog(view, Bundle.EMPTY); -				} -			} else if(resultCode == RESULT_CANCELED && data.hasExtra(ACTION_QUIT)) { -				finish(); -			} else -				configErrorDialog(); -		} -	} - -	/** -	 * Dialog shown when encountering a configuration error.  Such errors require -	 * reconfiguring LEAP or aborting the application. -	 */ -	private void configErrorDialog() { -		AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getAppContext()); -		alertBuilder.setTitle(getResources().getString(R.string.setup_error_title)); -		alertBuilder -			.setMessage(getResources().getString(R.string.setup_error_text)) -			.setCancelable(false) -			.setPositiveButton(getResources().getString(R.string.setup_error_configure_button), new DialogInterface.OnClickListener() { -				@Override -				public void onClick(DialogInterface dialog, int which) { -					startActivityForResult(new Intent(getAppContext(),ConfigurationWizard.class),CONFIGURE_LEAP); -				} -			}) -			.setNegativeButton(getResources().getString(R.string.setup_error_close_button), new DialogInterface.OnClickListener() { -				@Override -				public void onClick(DialogInterface dialog, int which) { -					SharedPreferences.Editor prefsEdit = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE).edit(); -					prefsEdit.remove(Provider.KEY).commit(); -					finish(); -				} -			}) -			.show(); -	} -	 -	/** -	 * Inflates permanent UI elements of the View and contains logic for what -	 * service dependent UI elements to include. -	 */ -	private void buildDashboard() { -		provider = Provider.getInstance(); -		provider.init( this ); - -		setContentView(R.layout.client_dashboard); -	     -		providerNameTV = (TextView) findViewById(R.id.providerName); -		providerNameTV.setText(provider.getDomain()); -		providerNameTV.setTextSize(28); -		 -	    mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); - -		FragmentManager fragMan = getFragmentManager(); -		if ( provider.hasEIP()){ -			EipServiceFragment eipFragment = new EipServiceFragment(); -			fragMan.beginTransaction().replace(R.id.servicesCollection, eipFragment, EipServiceFragment.TAG).commit(); -		} -	} - -	@Override -	public boolean onPrepareOptionsMenu(Menu menu) { -		JSONObject provider_json; -		try { -			provider_json = new JSONObject(getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); -			JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE); -			 -			if(service_description.getBoolean(Provider.ALLOW_REGISTRATION)) { -				if(authed_eip) { -					menu.findItem(R.id.login_button).setVisible(false); -					menu.findItem(R.id.logout_button).setVisible(true); -				} else { -					menu.findItem(R.id.login_button).setVisible(true); -					menu.findItem(R.id.logout_button).setVisible(false); -				} -			} -		} catch (JSONException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		}  -		return true; -	} -	 -	@Override -	public boolean onCreateOptionsMenu(Menu menu) { -		getMenuInflater().inflate(R.menu.client_dashboard, menu); -		return true; -	} -	 -	@Override -	public boolean onOptionsItemSelected(MenuItem item){ -		Intent intent; -		switch (item.getItemId()){ -		case R.id.about_leap: -			intent = new Intent(this, AboutActivity.class); -			startActivity(intent); -			return true; -		case R.id.switch_provider: -			if (Provider.getInstance().hasEIP()){ -				if (getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getBoolean(EIP.AUTHED_EIP, false)){ -					logOut(); -				} -				eipStop(); -			} -			getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().remove(Provider.KEY).commit(); -			startActivityForResult(new Intent(this,ConfigurationWizard.class), SWITCH_PROVIDER); -			return true; -		case R.id.login_button: -			View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); -			logInDialog(view, Bundle.EMPTY); -			return true; -		case R.id.logout_button: -			logOut(); -			return true; -		default: -				return super.onOptionsItemSelected(item); -		} -		 -	} - -	@Override -	public void authenticate(String username, String password) { -	    mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); -		eipStatus = (TextView) findViewById(R.id.eipStatus); -		 -		providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); -		providerAPI_result_receiver.setReceiver(this); -		 -		Intent provider_API_command = new Intent(this, ProviderAPI.class); - -		Bundle parameters = new Bundle(); -		parameters.putString(LogInDialog.USERNAME, username); -		parameters.putString(LogInDialog.PASSWORD, password); - -		JSONObject provider_json; -		try { -			provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); -			parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION)); -		} catch (JSONException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} - -		provider_API_command.setAction(ProviderAPI.SRP_AUTH); -		provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); -		provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); -		 -		mProgressBar.setVisibility(ProgressBar.VISIBLE); -		eipStatus.setText(R.string.authenticating_message); -		//mProgressBar.setMax(4); -		startService(provider_API_command); -	} - -    public void cancelAuthedEipOn() { -	EipServiceFragment eipFragment = (EipServiceFragment) getFragmentManager().findFragmentByTag(EipServiceFragment.TAG); -	eipFragment.checkEipSwitch(false); -    } -	 -	/** -	 * Asks ProviderAPI to log out. -	 */ -	public void logOut() { -		providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); -		providerAPI_result_receiver.setReceiver(this); -		Intent provider_API_command = new Intent(this, ProviderAPI.class); - -		Bundle parameters = new Bundle(); - -		JSONObject provider_json; -		try { -			provider_json = new JSONObject(preferences.getString(Provider.KEY, "")); -			parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION)); -		} catch (JSONException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} - -		provider_API_command.setAction(ProviderAPI.LOG_OUT); -		provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); -		provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); -		 -		if(mProgressBar == null) mProgressBar = (ProgressBar) findViewById(R.id.eipProgress); -		mProgressBar.setVisibility(ProgressBar.VISIBLE); -		if(eipStatus == null) eipStatus = (TextView) findViewById(R.id.eipStatus); -		eipStatus.setText(R.string.logout_message); -	//	eipStatus.setText("Starting to logout"); -		 -		startService(provider_API_command); -		//mProgressBar.setMax(1); - -	} -	 -	/** -	 * Shows the log in dialog. -	 * @param view from which the dialog is created. -	 */ -	public void logInDialog(View view, Bundle resultData) { -		FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction(); -	    Fragment previous_log_in_dialog = getFragmentManager().findFragmentByTag(LogInDialog.TAG); -	    if (previous_log_in_dialog != null) { -	        fragment_transaction.remove(previous_log_in_dialog); -	    } -	    fragment_transaction.addToBackStack(null); - -	    DialogFragment newFragment = LogInDialog.newInstance(); -	    if(resultData != null && !resultData.isEmpty()) { -	    	newFragment.setArguments(resultData); -	    } -	    newFragment.show(fragment_transaction, LogInDialog.TAG); -	} - -	/** -	 * Asks ProviderAPI to download an authenticated OpenVPN certificate. -	 * @param session_id cookie for the server to allow us to download the certificate. -	 */ -	private void downloadAuthedUserCertificate(/*Cookie session_id*/) { -		providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler()); -		providerAPI_result_receiver.setReceiver(this); -		 -		Intent provider_API_command = new Intent(this, ProviderAPI.class); - -		Bundle parameters = new Bundle(); -		parameters.putString(ConfigurationWizard.TYPE_OF_CERTIFICATE, ConfigurationWizard.AUTHED_CERTIFICATE); -		/*parameters.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id.getName()); -		parameters.putString(ConfigHelper.SESSION_ID_KEY, session_id.getValue());*/ - -		provider_API_command.setAction(ProviderAPI.DOWNLOAD_CERTIFICATE); -		provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters); -		provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver); -		 -		startService(provider_API_command); -	} - -	@Override -	public void onReceiveResult(int resultCode, Bundle resultData) { -		if(resultCode == ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL){ -			String session_id_cookie_key = resultData.getString(ProviderAPI.SESSION_ID_COOKIE_KEY); -			String session_id_string = resultData.getString(ProviderAPI.SESSION_ID_KEY); -			setResult(RESULT_OK); - -			authed_eip = true; -			getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); - -			invalidateOptionsMenu(); -        	mProgressBar.setVisibility(ProgressBar.GONE); -    		changeStatusMessage(resultCode); - -        	//Cookie session_id = new BasicClientCookie(session_id_cookie_key, session_id_string); -        	downloadAuthedUserCertificate(/*session_id*/); -		} else if(resultCode == ProviderAPI.SRP_AUTHENTICATION_FAILED) { -        	logInDialog(getCurrentFocus(), resultData); -		} else if(resultCode == ProviderAPI.LOGOUT_SUCCESSFUL) { -			authed_eip = false; -			getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.AUTHED_EIP, authed_eip).commit(); -			mProgressBar.setVisibility(ProgressBar.GONE); -			mProgressBar.setProgress(0); -			invalidateOptionsMenu(); -			setResult(RESULT_OK); -			changeStatusMessage(resultCode); - -		} else if(resultCode == ProviderAPI.LOGOUT_FAILED) { -			setResult(RESULT_CANCELED); -			changeStatusMessage(resultCode); -        	mProgressBar.setVisibility(ProgressBar.GONE); -		} else if(resultCode == ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE) { -        	setResult(RESULT_OK); -    		changeStatusMessage(resultCode); -        	mProgressBar.setVisibility(ProgressBar.GONE); -		if(EipServiceFragment.isEipSwitchChecked()) -		    eipStart(); -		} else if(resultCode == ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE) { -        	setResult(RESULT_CANCELED); -    		changeStatusMessage(resultCode); -        	mProgressBar.setVisibility(ProgressBar.GONE); - 		} -	} - -	private void changeStatusMessage(final int previous_result_code) { -		// TODO Auto-generated method stub -		ResultReceiver eip_status_receiver = new ResultReceiver(new Handler()){ -			protected void onReceiveResult(int resultCode, Bundle resultData){ -				super.onReceiveResult(resultCode, resultData); -				String request = resultData.getString(EIP.REQUEST_TAG); -				if (request.equalsIgnoreCase(EIP.ACTION_IS_EIP_RUNNING)){					 -					if (resultCode == Activity.RESULT_OK){ - -						switch(previous_result_code){ -						case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eipStatus.setText(R.string.succesful_authentication_message); break; -						case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_failed_message); break; -						case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.authed_secured_status); break; -						case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.incorrectly_downloaded_certificate_message); break; -						case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.anonymous_secured_status); break; -						case ProviderAPI.LOGOUT_FAILED: eipStatus.setText(R.string.log_out_failed_message); break; -						 -						}	 -					} -					else if(resultCode == Activity.RESULT_CANCELED){ - -						switch(previous_result_code){ - -						case ProviderAPI.SRP_AUTHENTICATION_SUCCESSFUL: eipStatus.setText(R.string.succesful_authentication_message); break; -						case ProviderAPI.SRP_AUTHENTICATION_FAILED: eipStatus.setText(R.string.authentication_failed_message); break; -						case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.future_authed_secured_status); break; -						case ProviderAPI.INCORRECTLY_DOWNLOADED_CERTIFICATE: eipStatus.setText(R.string.incorrectly_downloaded_certificate_message); break; -						case ProviderAPI.LOGOUT_SUCCESSFUL: eipStatus.setText(R.string.future_anonymous_secured_status); break; -						case ProviderAPI.LOGOUT_FAILED: eipStatus.setText(R.string.log_out_failed_message); break;			 -						} -					} -				} -					 -			} -		}; -		eipIsRunning(eip_status_receiver);		 -	} - -	/** -	 * For retrieving the base application Context in classes that don't extend -	 * Android's Activity class -	 *  -	 * @return Application Context as defined by <code>this</code> for Dashboard instance -	 */ -	public static Context getAppContext() { -		return app; -	} - -	 -	@Override -    public void startActivityForResult(Intent intent, int requestCode) { -        intent.putExtra(Dashboard.REQUEST_CODE, requestCode); -        super.startActivityForResult(intent, requestCode); -    } -	/** -	 * Send a command to EIP -	 *  -	 * @param action	A valid String constant from EIP class representing an Intent -	 * 					filter for the EIP class  -	 */ -	private void eipIsRunning(ResultReceiver eip_receiver){ -		// TODO validate "action"...how do we get the list of intent-filters for a class via Android API? -		Intent eip_intent = new Intent(this, EIP.class); -		eip_intent.setAction(EIP.ACTION_IS_EIP_RUNNING); -		eip_intent.putExtra(EIP.RECEIVER_TAG, eip_receiver); -		startService(eip_intent); -	} -	 -	/** -	 * Send a command to EIP -	 * 	 -	 */ -	private void eipStop(){ -		// TODO validate "action"...how do we get the list of intent-filters for a class via Android API? -		Intent eip_intent = new Intent(this, EIP.class); -		eip_intent.setAction(EIP.ACTION_STOP_EIP); -	//	eip_intent.putExtra(EIP.RECEIVER_TAG, eip_receiver); -		startService(eip_intent); - -	} - -    private void eipStart(){ -	Intent eip_intent = new Intent(this, EIP.class); -	eip_intent.setAction(EIP.ACTION_START_EIP); -	eip_intent.putExtra(EIP.RECEIVER_TAG, EipServiceFragment.getReceiver()); -	startService(eip_intent); - -    } -} diff --git a/src/se/leap/bitmaskclient/DownloadFailedDialog.java b/src/se/leap/bitmaskclient/DownloadFailedDialog.java deleted file mode 100644 index f78002b0..00000000 --- a/src/se/leap/bitmaskclient/DownloadFailedDialog.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package se.leap.bitmaskclient; - -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.NewProviderDialog.NewProviderDialogInterface; -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; - -/** - * Implements a dialog to show why a download failed. - *  - * @author parmegv - * - */ -public class DownloadFailedDialog extends DialogFragment { - -	public static String TAG = "downloaded_failed_dialog"; -	private String reason_to_fail; -	/** -	 * @return a new instance of this DialogFragment. -	 */ -	public static DialogFragment newInstance(String reason_to_fail) { -		DownloadFailedDialog dialog_fragment = new DownloadFailedDialog(); -		dialog_fragment.reason_to_fail = reason_to_fail; -		return dialog_fragment; -	} - -	@Override -	public Dialog onCreateDialog(Bundle savedInstanceState) { -		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - -		builder.setMessage(reason_to_fail) -		.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() { -			public void onClick(DialogInterface dialog, int id) { -				dismiss(); -				interface_with_ConfigurationWizard.retrySetUpProvider(); -			} -		}) -		.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { -			public void onClick(DialogInterface dialog, int id) { -				interface_with_ConfigurationWizard.cancelSettingUpProvider(); -				dialog.dismiss(); -			} -		}); - -		// Create the AlertDialog object and return it -		return builder.create(); -	} - -	public interface DownloadFailedDialogInterface { -		public void retrySetUpProvider(); -		public void cancelSettingUpProvider(); -	} - -	DownloadFailedDialogInterface interface_with_ConfigurationWizard; - -	@Override -	public void onAttach(Activity activity) { -		super.onAttach(activity); -		try { -			interface_with_ConfigurationWizard = (DownloadFailedDialogInterface) activity; -		} catch (ClassCastException e) { -			throw new ClassCastException(activity.toString() -					+ " must implement NoticeDialogListener"); -		} -	} - -	@Override -	public void onCancel(DialogInterface dialog) { -		interface_with_ConfigurationWizard.cancelSettingUpProvider(); -		dialog.dismiss(); -	} - -} diff --git a/src/se/leap/bitmaskclient/EIP.java b/src/se/leap/bitmaskclient/EIP.java deleted file mode 100644 index e773e3b9..00000000 --- a/src/se/leap/bitmaskclient/EIP.java +++ /dev/null @@ -1,623 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - package se.leap.bitmaskclient; - -import java.util.Calendar; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.TreeMap; -import java.util.Vector; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import se.leap.bitmaskclient.R; -import se.leap.openvpn.ConfigParser; -import se.leap.openvpn.ConfigParser.ConfigParseError; -import se.leap.openvpn.LaunchVPN; -import se.leap.openvpn.OpenVpnManagementThread; -import se.leap.openvpn.OpenVpnService; -import se.leap.openvpn.OpenVpnService.LocalBinder; -import se.leap.openvpn.ProfileManager; -import se.leap.openvpn.VpnProfile; -import android.app.Activity; -import android.app.IntentService; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.drm.DrmStore.Action; -import android.os.Bundle; -import android.os.IBinder; -import android.os.ResultReceiver; -import android.util.Log; - -/** - * EIP is the abstract base class for interacting with and managing the Encrypted - * Internet Proxy connection.  Connections are started, stopped, and queried through - * this IntentService. - * Contains logic for parsing eip-service.json from the provider, configuring and selecting - * gateways, and controlling {@link .openvpn.OpenVpnService} connections. - *  - * @author Sean Leonard <meanderingcode@aetherislands.net> - */ -public final class EIP extends IntentService { -	 -	public final static String AUTHED_EIP = "authed eip"; -	public final static String ACTION_START_EIP = "se.leap.bitmaskclient.START_EIP"; -	public final static String ACTION_STOP_EIP = "se.leap.bitmaskclient.STOP_EIP"; -	public final static String ACTION_UPDATE_EIP_SERVICE = "se.leap.bitmaskclient.UPDATE_EIP_SERVICE"; -	public final static String ACTION_IS_EIP_RUNNING = "se.leap.bitmaskclient.IS_RUNNING"; -	public final static String EIP_NOTIFICATION = "EIP_NOTIFICATION"; -	public final static String ALLOWED_ANON = "allow_anonymous"; -	public final static String CERTIFICATE = "cert"; -	public final static String PRIVATE_KEY = "private_key"; -	public final static String KEY = "eip"; -	public final static String PARSED_SERIAL = "eip_parsed_serial"; -	public final static String SERVICE_API_PATH = "config/eip-service.json"; -	public final static String RECEIVER_TAG = "receiverTag"; -	public final static String REQUEST_TAG = "requestTag"; -	public final static String TAG = "se.leap.bitmaskclient.EIP"; -	 -	 -	private static Context context; -	private static ResultReceiver mReceiver; -	private static OpenVpnService mVpnService; -	private static boolean mBound = false; -	// Used to store actions to "resume" onServiceConnection -	private static String mPending = null; -	 -	private static int parsedEipSerial; -	private static JSONObject eipDefinition = null; -	 -	private static OVPNGateway activeGateway = null; - -	public EIP(){ -		super("LEAPEIP"); -	} -	 -	@Override -	public void onCreate() { -		super.onCreate(); -		 -		context = getApplicationContext(); -		 -		updateEIPService(); -		 -		this.retreiveVpnService(); -	} -	 -	@Override -	public void onDestroy() { -		unbindService(mVpnServiceConn); -		mBound = false; - -		super.onDestroy(); -	} -	 -	@Override -	protected void onHandleIntent(Intent intent) { -		String action = intent.getAction(); -		mReceiver = intent.getParcelableExtra(RECEIVER_TAG); -		 -		if ( action == ACTION_IS_EIP_RUNNING ) -			this.isRunning(); -		if ( action == ACTION_UPDATE_EIP_SERVICE ) -			this.updateEIPService(); -		else if ( action == ACTION_START_EIP ) -			this.startEIP(); -		else if ( action == ACTION_STOP_EIP ) -			this.stopEIP(); -	} -	 -	/** -	 * Sends an Intent to bind OpenVpnService. -	 * Used when OpenVpnService isn't bound but might be running. -	 */ -	private boolean retreiveVpnService() { -		Intent bindIntent = new Intent(this,OpenVpnService.class); -		bindIntent.setAction(OpenVpnService.RETRIEVE_SERVICE); -		return bindService(bindIntent, mVpnServiceConn, BIND_AUTO_CREATE); -	} -	 -	private static ServiceConnection mVpnServiceConn = new ServiceConnection() { -		@Override -		public void onServiceConnected(ComponentName name, IBinder service) { -			LocalBinder binder = (LocalBinder) service; -			mVpnService = binder.getService(); -			mBound = true; - -			if (mReceiver != null && mPending != null) { - -				boolean running = mVpnService.isRunning(); -				 -				int resultCode = Activity.RESULT_CANCELED; -				 -				if (mPending.equals(ACTION_IS_EIP_RUNNING)){ -					resultCode = (running) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; - -				} -				else if (mPending.equals(ACTION_START_EIP)){ -					resultCode = (running) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; -				} -				else if (mPending.equals(ACTION_STOP_EIP)){ -					resultCode = (running) ? Activity.RESULT_CANCELED -							: Activity.RESULT_OK; -					} -				Bundle resultData = new Bundle(); -				resultData.putString(REQUEST_TAG, ACTION_IS_EIP_RUNNING); -				mReceiver.send(resultCode, resultData); -				 -				mPending = null; -			} -		} - -		@Override -		public void onServiceDisconnected(ComponentName name) { -			mBound = false; -			 -			if (mReceiver != null){ -				Bundle resultData = new Bundle(); -				resultData.putString(REQUEST_TAG, EIP_NOTIFICATION); -				mReceiver.send(Activity.RESULT_CANCELED, resultData); -			} -		} -		 -	 -	}; -	 -	/** -	 * Attempts to determine if OpenVpnService has an established VPN connection -	 * through the bound ServiceConnection.  If there is no bound service, this -	 * method will attempt to bind a running OpenVpnService and send -	 * <code>Activity.RESULT_CANCELED</code> to the ResultReceiver that made the -	 * request. -	 * Note: If the request to bind OpenVpnService is successful, the ResultReceiver -	 * will be notified in {@link onServiceConnected()} -	 */ -	 -	  private void isRunning() { -          Bundle resultData = new Bundle(); -          resultData.putString(REQUEST_TAG, ACTION_IS_EIP_RUNNING); -          int resultCode = Activity.RESULT_CANCELED; -          if (mBound) { -                  resultCode = (mVpnService.isRunning()) ? Activity.RESULT_OK : Activity.RESULT_CANCELED; -                   -                  if (mReceiver != null){ -                          mReceiver.send(resultCode, resultData); -                  } -          } else { -                  mPending = ACTION_IS_EIP_RUNNING; -                 boolean retrieved_vpn_service = retreiveVpnService(); -                 try { -					Thread.sleep(1000); -				} catch (InterruptedException e) { -					// TODO Auto-generated catch block -					e.printStackTrace(); -				} -                 boolean running = false; -                 try { -                	running = mVpnService.isRunning(); -                 } catch (NullPointerException e){ -                	 e.printStackTrace(); -                 } -                  -                 if (retrieved_vpn_service && running && mReceiver != null){ -                	  mReceiver.send(Activity.RESULT_OK, resultData); -                  } -                  else{ -                	  mReceiver.send(Activity.RESULT_CANCELED, resultData); -                  } -          } -  } -	 -	/** -	 * Initiates an EIP connection by selecting a gateway and preparing and sending an -	 * Intent to {@link se.leap.openvpn.LaunchVPN} -	 */ -	private void startEIP() { -		activeGateway = selectGateway(); -		 -		Intent intent = new Intent(this,LaunchVPN.class); -		intent.setAction(Intent.ACTION_MAIN); -		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); -		intent.putExtra(LaunchVPN.EXTRA_KEY, activeGateway.mVpnProfile.getUUID().toString() ); -		intent.putExtra(LaunchVPN.EXTRA_NAME, activeGateway.mVpnProfile.getName() ); -		intent.putExtra(RECEIVER_TAG, mReceiver); -		startActivity(intent); -		mPending = ACTION_START_EIP; -	} -	 -	/** -	 * Disconnects the EIP connection gracefully through the bound service or forcefully -	 * if there is no bound service.  Sends a message to the requesting ResultReceiver. -	 */ -	private void stopEIP() { -		if (mBound) -			mVpnService.onRevoke(); -		else -			OpenVpnManagementThread.stopOpenVPN(); -			 -		if (mReceiver != null){ -			Bundle resultData = new Bundle(); -			resultData.putString(REQUEST_TAG, ACTION_STOP_EIP); -			mReceiver.send(Activity.RESULT_OK, resultData); -		} -	} - -	/** -	 * Loads eip-service.json from SharedPreferences and calls {@link updateGateways()} -	 * to parse gateway definitions. -	 * TODO Implement API call to refresh eip-service.json from the provider -	 */ -	private void updateEIPService() { -		try { -			eipDefinition = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(KEY, "")); -			parsedEipSerial = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getInt(PARSED_SERIAL, 0); -		} catch (JSONException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} -		if(parsedEipSerial == 0) { -			// Delete all vpn profiles -			ProfileManager vpl = ProfileManager.getInstance(context); -			VpnProfile[] profiles = (VpnProfile[]) vpl.getProfiles().toArray(new VpnProfile[vpl.getProfiles().size()]); -			for (int current_profile = 0; current_profile < profiles.length; current_profile++){ -				vpl.removeProfile(context, profiles[current_profile]); -			} -		} -		if (eipDefinition.optInt("serial") > parsedEipSerial) -			updateGateways(); -	} -	 -	/** -	 * Choose a gateway to connect to based on timezone from system locale data -	 *  -	 * @return The gateway to connect to -	 */ -	private OVPNGateway selectGateway() { -		// TODO Remove String arg constructor in favor of findGatewayByName(String) -		 -		Calendar cal = Calendar.getInstance(); -		int localOffset = cal.get(Calendar.ZONE_OFFSET) / 3600000; -		TreeMap<Integer, Set<String>> offsets = new TreeMap<Integer, Set<String>>(); -		JSONObject locationsObjects = null; -		Iterator<String> locations = null; -		try { -			locationsObjects = eipDefinition.getJSONObject("locations"); -			locations = locationsObjects.keys(); -		} catch (JSONException e1) { -			// TODO Auto-generated catch block -			e1.printStackTrace(); -		} -		 -		while (locations.hasNext()) { -			String locationName = locations.next(); -			JSONObject location = null; -			try { -				location = locationsObjects.getJSONObject(locationName); -				 -				// Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 -				int dist = Math.abs(localOffset - location.optInt("timezone")); -				// Farther than 12 timezones and it's shorter around the "back" -				if (dist > 12) -					dist = 12 - (dist -12);  // Well i'll be.  Absolute values make equations do funny things. -				 -				Set<String> set = offsets.get(dist); -				if (set == null) set = new HashSet<String>(); -				set.add(locationName); -				offsets.put(dist, set); -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -		} -		 -		 -		String closestLocation = offsets.isEmpty() ? "" : offsets.firstEntry().getValue().iterator().next(); -		JSONArray gateways = null; -		String chosenHost = null; -		try { -			gateways = eipDefinition.getJSONArray("gateways"); -			for (int i = 0; i < gateways.length(); i++) { -				JSONObject gw = gateways.getJSONObject(i); -				if ( gw.getString("location").equalsIgnoreCase(closestLocation) || closestLocation.isEmpty()){ -					chosenHost = gw.getString("host"); -					break; -				} -			} -		} catch (JSONException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} - -		return new OVPNGateway(chosenHost); -	} -	 -	/** -	 * Walk the list of gateways defined in eip-service.json and parse them into -	 * OVPNGateway objects. -	 * TODO Store the OVPNGateways (as Serializable) in SharedPreferences -	 */ -	private void updateGateways(){ -		JSONArray gatewaysDefined = null; -		 -		try { -			gatewaysDefined = eipDefinition.getJSONArray("gateways"); -		} catch (JSONException e1) { -			// TODO Auto-generated catch block -			e1.printStackTrace(); -		} -		 -		for ( int i=0 ; i < gatewaysDefined.length(); i++ ){ -			 -			JSONObject gw = null; -			 -			try { -				gw = gatewaysDefined.getJSONObject(i); -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -			 -			try { -				if ( gw.getJSONObject("capabilities").getJSONArray("transport").toString().contains("openvpn") ){ -					new OVPNGateway(gw); -				} -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -		} -		getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(PARSED_SERIAL, eipDefinition.optInt(Provider.API_RETURN_SERIAL)).commit(); -	} - -	/** -	 * OVPNGateway provides objects defining gateways and their options and metadata. -	 * Each instance contains a VpnProfile for OpenVPN specific data and member -	 * variables describing capabilities and location -	 *  -	 * @author Sean Leonard <meanderingcode@aetherislands.net> -	 */ -	private class OVPNGateway { -		 -		private String TAG = "OVPNGateway"; -		 -		private String mName; -		private VpnProfile mVpnProfile; -		private JSONObject mGateway; -		private HashMap<String,Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>(); - -		 -		/** -		 * Attempts to retrieve a VpnProfile by name and build an OVPNGateway around it. -		 * FIXME This needs to become a findGatewayByName() method -		 *  -		 * @param name The hostname of the gateway to inflate -		 */ -		private OVPNGateway(String name){ -			mName = name; -			 -			this.loadVpnProfile(); -		} -		 -		private void loadVpnProfile() { -			ProfileManager vpl = ProfileManager.getInstance(context); -			 -			try { -				if ( mName == null ) -					mVpnProfile = vpl.getProfiles().iterator().next(); -				else -					mVpnProfile = vpl.getProfileByName(mName); -			} catch (NoSuchElementException e) { -				updateEIPService(); -				this.loadVpnProfile();	// FIXME catch infinite loops -			} catch (Exception e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -		} -		 -		/** -		 * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json -		 * and create a VpnProfile belonging to it. -		 *  -		 * @param gateway The JSON OpenVPN gateway definition to parse -		 */ -		protected OVPNGateway(JSONObject gateway){ - -			mGateway = gateway; -			 -			// Currently deletes VpnProfile for host, if there already is one, and builds new -			ProfileManager vpl = ProfileManager.getInstance(context); -			Collection<VpnProfile> profiles = vpl.getProfiles(); -			for (Iterator<VpnProfile> it = profiles.iterator(); it.hasNext(); ){ -				VpnProfile p = it.next(); -				try { -					if ( p.mName.equalsIgnoreCase( gateway.getString("host") ) ){ -						it.remove(); -						vpl.removeProfile(context, p); -					} -				} catch (JSONException e) { -					// TODO Auto-generated catch block -					e.printStackTrace(); -				} -			} -			 -			this.parseOptions(); -			this.createVPNProfile(); -			 -			setUniqueProfileName(vpl); -			vpl.addProfile(mVpnProfile); -			vpl.saveProfile(context, mVpnProfile); -			vpl.saveProfileList(context); -		} -		 -		/** -		 * Attempts to create a unique profile name from the hostname of the gateway -		 *  -		 * @param profileManager -		 */ -		private void setUniqueProfileName(ProfileManager profileManager) { -			int i=0; - -			String newname; -			try { -				newname = mGateway.getString("host"); -				while(profileManager.getProfileByName(newname)!=null) { -					i++; -					if(i==1) -						newname = getString(R.string.converted_profile); -					else -						newname = getString(R.string.converted_profile_i,i); -				} - -				mVpnProfile.mName=newname; -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				Log.v(TAG,"Couldn't read gateway name for profile creation!"); -				e.printStackTrace(); -			} -		} - -		/** -		 * FIXME This method is really the outline of the refactoring needed in se.leap.openvpn.ConfigParser  -		 */ -		private void parseOptions(){ -			 -			// FIXME move these to a common API (& version) definition place, like ProviderAPI or ConfigHelper -			String common_options = "openvpn_configuration"; -			String remote = "ip_address"; -			String ports = "ports"; -			String protos = "protocols"; -			String capabilities = "capabilities"; -			String location_key = "location"; -			String locations = "locations"; -			 -			Vector<String> arg = new Vector<String>(); -			Vector<Vector<String>> args = new Vector<Vector<String>>(); -			 -			try { -				JSONObject def = (JSONObject) eipDefinition.get(common_options); -				Iterator keys = def.keys(); -				Vector<Vector<String>> value = new Vector<Vector<String>>(); -				while ( keys.hasNext() ){ -					String key = keys.next().toString(); -					 -					arg.add(key); -					for ( String word : def.getString(key).split(" ") ) -						arg.add(word); -					value.add( (Vector<String>) arg.clone() ); -					options.put(key, (Vector<Vector<String>>) value.clone()); -					value.clear(); -					arg.clear(); -				} -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -			 -			try { -				arg.add(remote); -				arg.add(mGateway.getString(remote)); -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -			args.add((Vector<String>) arg.clone()); -			options.put("remote", (Vector<Vector<String>>) args.clone() ); -			arg.clear(); -			args.clear(); - - -			 -			try { -				 -				arg.add(location_key); -				String locationText = ""; -				locationText = eipDefinition.getJSONObject(locations).getJSONObject(mGateway.getString(location_key)).getString("name");		 -				arg.add(locationText); - -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -			args.add((Vector<String>) arg.clone()); -			options.put("location", (Vector<Vector<String>>) args.clone() ); - -			arg.clear(); -			args.clear(); -			JSONArray protocolsJSON = null; -			arg.add("proto"); -			try { -				protocolsJSON = mGateway.getJSONObject(capabilities).getJSONArray(protos); -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -			Vector<String> protocols = new Vector<String>(); -			for ( int i=0; i<protocolsJSON.length(); i++ ) -				protocols.add(protocolsJSON.optString(i)); -			if ( protocols.contains("udp")) -				arg.add("udp"); -			else if ( protocols.contains("tcp")) -				arg.add("tcp"); -			args.add((Vector<String>) arg.clone()); -			options.put("proto", (Vector<Vector<String>>) args.clone()); -			arg.clear(); -			args.clear(); -			 -			 -			String port = null; -			arg.add("port"); -			try { -				port = mGateway.getJSONObject(capabilities).getJSONArray(ports).optString(0); -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -			arg.add(port); -			args.add((Vector<String>) arg.clone()); -			options.put("port", (Vector<Vector<String>>) args.clone()); -			args.clear(); -			arg.clear(); -		} -		 -		/** -		 * Create and attach the VpnProfile to our gateway object -		 */ -		protected void createVPNProfile(){ -			try { -				ConfigParser cp = new ConfigParser(); -				cp.setDefinition(options); -				VpnProfile vp = cp.convertProfile(); -				mVpnProfile = vp; -				Log.v(TAG,"Created VPNProfile"); -			} catch (ConfigParseError e) { -				// FIXME We didn't get a VpnProfile!  Error handling! and log level -				Log.v(TAG,"Error createing VPNProfile"); -				e.printStackTrace(); -			} -		} -	} - -} diff --git a/src/se/leap/bitmaskclient/EipServiceFragment.java b/src/se/leap/bitmaskclient/EipServiceFragment.java deleted file mode 100644 index b4cb541a..00000000 --- a/src/se/leap/bitmaskclient/EipServiceFragment.java +++ /dev/null @@ -1,306 +0,0 @@ -package se.leap.bitmaskclient; - -import se.leap.bitmaskclient.R; -import se.leap.openvpn.LogWindow; -import se.leap.openvpn.OpenVPN; -import se.leap.openvpn.OpenVPN.StateListener; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.CompoundButton; -import android.widget.RelativeLayout; -import android.widget.Switch; -import android.widget.TextView; - -public class EipServiceFragment extends Fragment implements StateListener, OnCheckedChangeListener { -	 -	protected static final String IS_EIP_PENDING = "is_eip_pending"; -	 -	private View eipFragment; -	private static Switch eipSwitch; -	private View eipDetail; -	private TextView eipStatus; - -	private boolean eipAutoSwitched = true; -	 -	private boolean mEipStartPending = false; - -    private boolean set_switch_off = false; - -    private static EIPReceiver mEIPReceiver; - -     -    public static String TAG = "se.leap.bitmask.EipServiceFragment"; - -	@Override -	public View onCreateView(LayoutInflater inflater, ViewGroup container, -			Bundle savedInstanceState) { -		 -		eipFragment = inflater.inflate(R.layout.eip_service_fragment, container, false); -		 -		eipDetail = ((RelativeLayout) eipFragment.findViewById(R.id.eipDetail)); -		eipDetail.setVisibility(View.VISIBLE); - -		View eipSettings = eipFragment.findViewById(R.id.eipSettings); -		eipSettings.setVisibility(View.GONE); // FIXME too! - -		if (mEipStartPending) -			eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); -		 -		eipStatus = (TextView) eipFragment.findViewById(R.id.eipStatus); - -		eipSwitch = (Switch) eipFragment.findViewById(R.id.eipSwitch); - -			 -		eipSwitch.setOnTouchListener(new View.OnTouchListener() { -			@Override -			public boolean onTouch(View v, MotionEvent event) { -				eipAutoSwitched = false; -				return false; -			} -		}); -		eipSwitch.setOnCheckedChangeListener(this); -		 -		 -		return eipFragment; -	} - -	@Override -	public void onCreate(Bundle savedInstanceState) { -		super.onCreate(savedInstanceState); -		 -		mEIPReceiver = new EIPReceiver(new Handler()); - -		if (savedInstanceState != null) -			mEipStartPending = savedInstanceState.getBoolean(IS_EIP_PENDING); -	} - -	@Override -	public void onResume() { -		super.onResume(); - -		OpenVPN.addStateListener(this); -		if(set_switch_off) { -		    eipSwitch.setChecked(false); -		    set_switch_off = false; -		} -	} - -    protected void setSwitchOff(boolean value) { -	set_switch_off = value; -    } -     -	@Override -	public void onPause() { -		super.onPause(); - -		OpenVPN.removeStateListener(this); -	} -	 -	@Override -	public void onSaveInstanceState(Bundle outState) { -		super.onSaveInstanceState(outState); -		outState.putBoolean(IS_EIP_PENDING, mEipStartPending); -	} -	 -	@Override -	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { -		if (buttonView.equals(eipSwitch) && !eipAutoSwitched){ -		    boolean allowed_anon = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).getBoolean(EIP.ALLOWED_ANON, false); -		    String certificate = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).getString(EIP.CERTIFICATE, ""); -		    if(allowed_anon || !certificate.isEmpty()) { -			if (isChecked){ -				mEipStartPending = true; -				eipFragment.findViewById(R.id.eipProgress).setVisibility(View.VISIBLE); -				((TextView) eipFragment.findViewById(R.id.eipStatus)).setText(R.string.eip_status_start_pending); -				eipCommand(EIP.ACTION_START_EIP); -			} else { -				if (mEipStartPending){ -					AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity()); -					alertBuilder.setTitle(getResources().getString(R.string.eip_cancel_connect_title)); -					alertBuilder -					.setMessage(getResources().getString(R.string.eip_cancel_connect_text)) -					.setPositiveButton(getResources().getString(R.string.eip_cancel_connect_cancel), new DialogInterface.OnClickListener() { -						@Override -						public void onClick(DialogInterface dialog, int which) { -							eipCommand(EIP.ACTION_STOP_EIP); -							mEipStartPending = false; -						} -					}) -					.setNegativeButton(getResources().getString(R.string.eip_cancel_connect_false), new DialogInterface.OnClickListener() { -						@Override -						public void onClick(DialogInterface dialog, int which) { -							eipAutoSwitched = true; -							eipSwitch.setChecked(true); -							eipAutoSwitched = false; -						} -					}) -					.show(); -				} else { -					eipCommand(EIP.ACTION_STOP_EIP); -				} -			} -		    } -		    else { -			Dashboard dashboard = (Dashboard)getActivity(); -			Bundle waiting_on_login = new Bundle(); -			waiting_on_login.putBoolean(IS_EIP_PENDING, true); -			dashboard.logInDialog(getActivity().getCurrentFocus(), waiting_on_login); -		    } -		} -		else { -		    if(!eipSwitch.isChecked()) -			eipStatus.setText(R.string.state_noprocess); -		} -		eipAutoSwitched = true; -	} -	 - -	 -	/** -	 * Send a command to EIP -	 *  -	 * @param action	A valid String constant from EIP class representing an Intent -	 * 					filter for the EIP class  -	 */ -	private void eipCommand(String action){ -		// TODO validate "action"...how do we get the list of intent-filters for a class via Android API? -		Intent vpnIntent = new Intent(action); -		vpnIntent.putExtra(EIP.RECEIVER_TAG, mEIPReceiver); -		getActivity().startService(vpnIntent); -	} -	 -	@Override -	public void updateState(final String state, final String logmessage, final int localizedResId) { -		// Note: "states" are not organized anywhere...collected state strings: -		//		NOPROCESS,NONETWORK,BYTECOUNT,AUTH_FAILED + some parsing thing ( WAIT(?),AUTH,GET_CONFIG,ASSIGN_IP,CONNECTED,SIGINT ) -		getActivity().runOnUiThread(new Runnable() { - -			@Override -			public void run() { -				if (eipStatus != null) { -					boolean switchState = true; -					String statusMessage = ""; -					String prefix = getString(localizedResId); -					if (state.equals("CONNECTED")){ - -						statusMessage = getString(R.string.eip_state_connected); -						getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); -						mEipStartPending = false; -					} else if (state.equals("BYTECOUNT")) { -					statusMessage = getString(R.string.eip_state_connected); getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); -                                                mEipStartPending = false; -						 -					} else if ( (state.equals("NOPROCESS") && !mEipStartPending ) || state.equals("EXITING") && !mEipStartPending || state.equals("FATAL")) { -						statusMessage = getString(R.string.eip_state_not_connected); -						getActivity().findViewById(R.id.eipProgress).setVisibility(View.GONE); -						mEipStartPending = false; -						switchState = false; -					} else if (state.equals("NOPROCESS")){ -						statusMessage = logmessage; -					} else if (state.equals("ASSIGN_IP")){ //don't show assigning message in eipStatus -						statusMessage = (String) eipStatus.getText(); -					} -					else { -						statusMessage = prefix + " " + logmessage; -					} -					 -					eipAutoSwitched = true; -					eipSwitch.setChecked(switchState); -					eipAutoSwitched = false; -					eipStatus.setText(statusMessage); -				} -			} -		}); -	} - - -	/** -	 * Inner class for handling messages related to EIP status and control requests -	 *  -	 * @author Sean Leonard <meanderingcode@aetherislands.net> -	 */ -	protected class EIPReceiver extends ResultReceiver { -		 -		protected EIPReceiver(Handler handler){ -			super(handler); -		} - -		@Override -		protected void onReceiveResult(int resultCode, Bundle resultData) { -			super.onReceiveResult(resultCode, resultData); -			 -			String request = resultData.getString(EIP.REQUEST_TAG); -			boolean checked = false; -			 -			if (request == EIP.ACTION_IS_EIP_RUNNING) { -				switch (resultCode){ -				case Activity.RESULT_OK: -					checked = true; -					break; -				case Activity.RESULT_CANCELED: -					checked = false; -					break; -				} -			} else if (request == EIP.ACTION_START_EIP) { -				switch (resultCode){ -				case Activity.RESULT_OK: -					checked = true; -					break; -				case Activity.RESULT_CANCELED: -					checked = false; -					eipFragment.findViewById(R.id.eipProgress).setVisibility(View.GONE); -					break; -				} -			} else if (request == EIP.ACTION_STOP_EIP) { -				switch (resultCode){ -				case Activity.RESULT_OK: -					checked = false; -					break; -				case Activity.RESULT_CANCELED: -					checked = true; -					break; -				} -			} else if (request == EIP.EIP_NOTIFICATION) { -				switch  (resultCode){ -				case Activity.RESULT_OK: -					checked = true; -					break; -				case Activity.RESULT_CANCELED: -					checked = false; -					break; -				} -			} -			 -			eipAutoSwitched = true; -			eipSwitch.setChecked(checked); -			eipAutoSwitched = false; -		} -	} -     - -    public static EIPReceiver getReceiver() { -	return mEIPReceiver; -    } - -    public static boolean isEipSwitchChecked() { -	return eipSwitch.isChecked(); -    } - -    public void checkEipSwitch(boolean checked) { -	eipSwitch.setChecked(checked); -	onCheckedChanged(eipSwitch, checked); -    } -} diff --git a/src/se/leap/bitmaskclient/LeapHttpClient.java b/src/se/leap/bitmaskclient/LeapHttpClient.java deleted file mode 100644 index 885b5105..00000000 --- a/src/se/leap/bitmaskclient/LeapHttpClient.java +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - package se.leap.bitmaskclient; - -import java.security.KeyStore; - -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.scheme.PlainSocketFactory; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.SingleClientConnManager; -import android.content.Context; - -/** - * Implements an HTTP client, enabling LEAP Android app to manage its own runtime keystore or bypass default Android security measures. - *  - * @author rafa - * - */ -public class LeapHttpClient extends DefaultHttpClient { - -	private static LeapHttpClient client; - -	/** -	 * If the class scope client is null, it creates one and imports, if existing, the main certificate from Shared Preferences.  -	 * @param context -	 * @return the new client. -	 */ -	public static LeapHttpClient getInstance(String cert_string) { -		if(client == null) { -			if(cert_string != null) { -				ConfigHelper.addTrustedCertificate("provider_ca_certificate", cert_string); -			} -		} -		return client; -	} - -	@Override -	protected ClientConnectionManager createClientConnectionManager() { -		SchemeRegistry registry = new SchemeRegistry(); -		registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); -		registry.register(new Scheme("https", newSslSocketFactory(), 443)); - -		return new SingleClientConnManager(getParams(), registry); -	} - -	/** -	 * Uses keystore from ConfigHelper for the SSLSocketFactory. -	 * @return -	 */ -	private SSLSocketFactory newSslSocketFactory() { -		try { -			KeyStore trusted = ConfigHelper.getKeystore(); -			SSLSocketFactory sf = new SSLSocketFactory(trusted); - -			return sf; -		} catch (Exception e) { -			throw new AssertionError(e); -		} -	} -} diff --git a/src/se/leap/bitmaskclient/LeapSRPSession.java b/src/se/leap/bitmaskclient/LeapSRPSession.java deleted file mode 100644 index a317d95e..00000000 --- a/src/se/leap/bitmaskclient/LeapSRPSession.java +++ /dev/null @@ -1,341 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - package se.leap.bitmaskclient; - -import java.io.UnsupportedEncodingException; -import java.math.BigInteger; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.Arrays; - -import org.jboss.security.srp.SRPParameters; - -/** - * Implements all SRP algorithm logic. - *  - * It's derived from JBoss implementation, with adjustments to make it work with LEAP platform. - *  - * @author parmegv - * - */ -public class LeapSRPSession { -	 -	private static String token = ""; -	 -	final public static String SALT = "salt"; -	final public static String M1 = "M1"; -	final public static String M2 = "M2"; -	final public static String TOKEN = "token"; -	final public static String AUTHORIZATION_HEADER= "Authorization"; -	 -	private SRPParameters params; -	private String username; -	private String password; -	private BigInteger N; -	private byte[] N_bytes; -	private BigInteger g; -	private BigInteger x; -	private BigInteger v; -	private BigInteger a; -	private BigInteger A; -	private byte[] K; -	private SecureRandom pseudoRng; -	/** The M1 = H(H(N) xor H(g) | H(U) | s | A | B | K) hash */ -	private MessageDigest clientHash; -	/** The M2 = H(A | M | K) hash */ -	private MessageDigest serverHash; - -	private static int A_LEN; - -	/** Creates a new SRP server session object from the username, password -	    verifier, -	    @param username, the user ID -	    @param password, the user clear text password -	    @param params, the SRP parameters for the session -	 */ -	public LeapSRPSession(String username, String password, SRPParameters params) -	{ -		this(username, password, params, null); -	} - -	/** Creates a new SRP server session object from the username, password -	    verifier, -	    @param username, the user ID -	    @param password, the user clear text password -	    @param params, the SRP parameters for the session -	    @param abytes, the random exponent used in the A public key -	 */ -	public LeapSRPSession(String username, String password, SRPParameters params, -			byte[] abytes) { -		this.params = params; -		this.g = new BigInteger(1, params.g); -		N_bytes = ConfigHelper.trim(params.N); -		this.N = new BigInteger(1, N_bytes); -		this.username = username; -		this.password = password; -		 -		try { -			pseudoRng = SecureRandom.getInstance("SHA1PRNG"); -		} catch (NoSuchAlgorithmException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} -		 -		if( abytes != null ) { -			A_LEN = 8*abytes.length; -			/* TODO Why did they put this condition? -	         if( 8*abytes.length != A_LEN ) -	            throw new IllegalArgumentException("The abytes param must be " -	               +(A_LEN/8)+" in length, abytes.length="+abytes.length); -			 */ -			this.a = new BigInteger(abytes); -		} -		else -			A_LEN = 64; - -		serverHash = newDigest(); -		clientHash = newDigest(); -	} - -	/** -	 * Calculates the parameter x of the SRP-6a algorithm. -	 * @param username -	 * @param password -	 * @param salt the salt of the user -	 * @return x -	 */ -	public byte[] calculatePasswordHash(String username, String password, byte[] salt) -	{ -		//password = password.replaceAll("\\\\", "\\\\\\\\"); -		// Calculate x = H(s | H(U | ':' | password)) -		MessageDigest x_digest = newDigest(); -		// Try to convert the username to a byte[] using ISO-8859-1 -		byte[] user = null; -		byte[] password_bytes = null; -		byte[] colon = {}; -		String encoding = "ISO-8859-1"; -		try { -			user = ConfigHelper.trim(username.getBytes(encoding)); -			colon = ConfigHelper.trim(":".getBytes(encoding)); -			password_bytes = ConfigHelper.trim(password.getBytes(encoding)); -		} -		catch(UnsupportedEncodingException e) { -			// Use the default platform encoding -			user = ConfigHelper.trim(username.getBytes()); -			colon = ConfigHelper.trim(":".getBytes()); -			password_bytes = ConfigHelper.trim(password.getBytes()); -		} -		 -		// Build the hash -		x_digest.update(user); -		x_digest.update(colon); -		x_digest.update(password_bytes); -		byte[] h = x_digest.digest(); -		 -		x_digest.reset(); -		x_digest.update(salt); -		x_digest.update(h); -		byte[] x_digest_bytes = x_digest.digest(); - -		return x_digest_bytes; -	} - -	/** -	 * Calculates the parameter V of the SRP-6a algorithm. -	 * @param k_string constant k predefined by the SRP server implementation. -	 * @return the value of V -	 */ -	private BigInteger calculateV(String k_string) { -		BigInteger k = new BigInteger(k_string, 16); -		BigInteger v = k.multiply(g.modPow(x, N));  // g^x % N -		return v; -	} - -	/** -	 * Calculates the trimmed xor from two BigInteger numbers -	 * @param b1 the positive source to build first BigInteger -	 * @param b2 the positive source to build second BigInteger -	 * @param length  -	 * @return -	 */ -	public byte[] xor(byte[] b1, byte[] b2) -	{ -		//TODO Check if length matters in the order, when b2 is smaller than b1 or viceversa -		byte[] xor_digest = new BigInteger(1, b1).xor(new BigInteger(1, b2)).toByteArray(); -		return ConfigHelper.trim(xor_digest); -	} - -	/** -	 * @returns The exponential residue (parameter A) to be sent to the server. -	 */ -	public byte[] exponential() { -		byte[] Abytes = null; -		if(A == null) { -			/* If the random component of A has not been specified use a random -	         number */ -			if( a == null ) { -				BigInteger one = BigInteger.ONE; -				do { -					a = new BigInteger(A_LEN, pseudoRng); -				} while(a.compareTo(one) <= 0); -			} -			A = g.modPow(a, N); -			Abytes = ConfigHelper.trim(A.toByteArray()); -		} -		return Abytes; -	} - -	/** -	 * Calculates the parameter M1, to be sent to the SRP server. -	 * It also updates hashes of client and server for further calculations in other methods. -	 * It uses a predefined k. -	 * @param salt_bytes -	 * @param Bbytes the parameter received from the server, in bytes -	 * @return the parameter M1 -	 * @throws NoSuchAlgorithmException -	 */ -	public byte[] response(byte[] salt_bytes, byte[] Bbytes) throws NoSuchAlgorithmException { -		// Calculate x = H(s | H(U | ':' | password)) -		byte[] M1 = null; -		if(new BigInteger(1, Bbytes).mod(new BigInteger(1, N_bytes)) != BigInteger.ZERO) { -			byte[] xb = calculatePasswordHash(username, password, ConfigHelper.trim(salt_bytes)); -			this.x = new BigInteger(1, xb); - -			// Calculate v = kg^x mod N -			String k_string = "bf66c44a428916cad64aa7c679f3fd897ad4c375e9bbb4cbf2f5de241d618ef0"; -			this.v = calculateV(k_string); - -			// H(N) -			byte[] digest_of_n = newDigest().digest(N_bytes); - -			// H(g) -			byte[] digest_of_g = newDigest().digest(params.g); - -			// clientHash = H(N) xor H(g) -			byte[] xor_digest = xor(digest_of_n, digest_of_g); -			clientHash.update(xor_digest); - -			// clientHash = H(N) xor H(g) | H(U) -			byte[] username_digest = newDigest().digest(ConfigHelper.trim(username.getBytes())); -			username_digest = ConfigHelper.trim(username_digest); -			clientHash.update(username_digest); - -			// clientHash = H(N) xor H(g) | H(U) | s -			clientHash.update(ConfigHelper.trim(salt_bytes)); - -			K = null; - -			// clientHash = H(N) xor H(g) | H(U) | A -			byte[] Abytes = ConfigHelper.trim(A.toByteArray()); -			clientHash.update(Abytes); - -			// clientHash = H(N) xor H(g) | H(U) | s | A | B -			Bbytes = ConfigHelper.trim(Bbytes); -			clientHash.update(Bbytes); - -			// Calculate S = (B - kg^x) ^ (a + u * x) % N -			BigInteger S = calculateS(Bbytes); -			byte[] S_bytes = ConfigHelper.trim(S.toByteArray()); - -			// K = SessionHash(S) -			String hash_algorithm = params.hashAlgorithm; -			MessageDigest sessionDigest = MessageDigest.getInstance(hash_algorithm); -			K = ConfigHelper.trim(sessionDigest.digest(S_bytes)); - -			// clientHash = H(N) xor H(g) | H(U) | A | B | K -			clientHash.update(K); - -			M1 = ConfigHelper.trim(clientHash.digest()); - -			// serverHash = Astr + M + K -			serverHash.update(Abytes); -			serverHash.update(M1); -			serverHash.update(K); - -		} -		return M1; -	} - -	/** -	 * It calculates the parameter S used by response() to obtain session hash K. -	 * @param Bbytes the parameter received from the server, in bytes -	 * @return the parameter S -	 */ -	private BigInteger calculateS(byte[] Bbytes) { -		byte[] Abytes = ConfigHelper.trim(A.toByteArray()); -		Bbytes = ConfigHelper.trim(Bbytes); -		byte[] u_bytes = getU(Abytes, Bbytes); -		 -		BigInteger B = new BigInteger(1, Bbytes); -		BigInteger u = new BigInteger(1, u_bytes); -		 -		BigInteger B_minus_v = B.subtract(v); -		BigInteger a_ux = a.add(u.multiply(x)); -		BigInteger S = B_minus_v.modPow(a_ux, N); -		return S; -	} - -	/** -	 * It calculates the parameter u used by calculateS to obtain S. -	 * @param Abytes the exponential residue sent to the server -	 * @param Bbytes the parameter received from the server, in bytes -	 * @return -	 */ -	public byte[] getU(byte[] Abytes, byte[] Bbytes) { -		MessageDigest u_digest = newDigest(); -		u_digest.update(ConfigHelper.trim(Abytes)); -		u_digest.update(ConfigHelper.trim(Bbytes)); -		byte[] u_digest_bytes = u_digest.digest(); -		return ConfigHelper.trim(new BigInteger(1, u_digest_bytes).toByteArray()); -	} - -	/** -	 * @param M2 The server's response to the client's challenge -	 * @returns True if and only if the server's response was correct. -	 */ -	public boolean verify(byte[] M2) -	{ -		// M2 = H(A | M1 | K) -		M2 = ConfigHelper.trim(M2); -		byte[] myM2 = ConfigHelper.trim(serverHash.digest()); -		boolean valid = Arrays.equals(M2, myM2); -		return valid; -	} -	 -	protected static void setToken(String token) { -		LeapSRPSession.token = token; -	} -	 -	protected static String getToken() { -		return token; -	} - -	/** -	 * @return a new SHA-256 digest. -	 */ -	public MessageDigest newDigest() -	{ -		MessageDigest md = null; -		try { -			md = MessageDigest.getInstance("SHA-256"); -		} catch (NoSuchAlgorithmException e) { -			e.printStackTrace(); -		} -		return md; -	} -} diff --git a/src/se/leap/bitmaskclient/LogInDialog.java b/src/se/leap/bitmaskclient/LogInDialog.java deleted file mode 100644 index a28c9049..00000000 --- a/src/se/leap/bitmaskclient/LogInDialog.java +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - package se.leap.bitmaskclient; - -import se.leap.bitmaskclient.R; -import android.R.color; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.content.res.ColorStateList; -import android.os.Bundle; -import android.provider.CalendarContract.Colors; -import android.view.LayoutInflater; -import android.view.View; -import android.view.animation.AlphaAnimation; -import android.view.animation.BounceInterpolator; -import android.widget.EditText; -import android.widget.TextView; - -/** - * Implements the log in dialog, currently without progress dialog. - *  - * It returns to the previous fragment when finished, and sends username and password to the authenticate method. - *  - * It also notifies the user if the password is not valid.  - *  - * @author parmegv - * - */ -public class LogInDialog extends DialogFragment { - -      -	final public static String TAG = "logInDialog"; -	final public static String VERB = "log in"; -	final public static String USERNAME = "username"; -	final public static String PASSWORD = "password"; -	final public static String USERNAME_MISSING = "username missing"; -	final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length"; - -    private static boolean is_eip_pending = false; -     -	public AlertDialog onCreateDialog(Bundle savedInstanceState) { -		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); -		LayoutInflater inflater = getActivity().getLayoutInflater(); -		View log_in_dialog_view = inflater.inflate(R.layout.log_in_dialog, null); - -		final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message); -		if(getArguments() != null && getArguments().containsKey(getResources().getString(R.string.user_message))) { -			user_message.setText(getArguments().getString(getResources().getString(R.string.user_message))); -		} else { -			user_message.setVisibility(View.GONE); -		} -		 -		final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered); -		if(getArguments() != null && getArguments().containsKey(USERNAME)) { -			String username = getArguments().getString(USERNAME); -			username_field.setText(username); -		} -		if (getArguments() != null && getArguments().containsKey(USERNAME_MISSING)) { -			username_field.setError(getResources().getString(R.string.username_ask)); -    	} -		 -		final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered); -		if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) { -			password_field.requestFocus(); -		} -		if (getArguments() != null && getArguments().containsKey(PASSWORD_INVALID_LENGTH)) { -		    password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message)); -		} -		if(getArguments() != null && getArguments().getBoolean(EipServiceFragment.IS_EIP_PENDING, false)) { -			is_eip_pending = true; -		    } - -		 -		builder.setView(log_in_dialog_view) -			.setPositiveButton(R.string.login_button, new DialogInterface.OnClickListener() { -				public void onClick(DialogInterface dialog, int id) { -					String username = username_field.getText().toString(); -					String password = password_field.getText().toString(); -					dialog.dismiss(); -					interface_with_Dashboard.authenticate(username, password); -				} -			}) -			.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { -				public void onClick(DialogInterface dialog, int id) { -					dialog.cancel(); -				} -			}); -		 -		return builder.create(); -	} -	 -	/** -	 * Interface used to communicate LogInDialog with Dashboard. -	 *  -	 * @author parmegv -	 * -	 */ -	public interface LogInDialogInterface { -		/** -		 * Starts authentication process. -		 * @param username -		 * @param password -		 */ -	    public void authenticate(String username, String password); -	    public void cancelAuthedEipOn(); -    } - -	LogInDialogInterface interface_with_Dashboard; - -	/** -	 * @return a new instance of this DialogFragment. -	 */ -	public static DialogFragment newInstance() { -		LogInDialog dialog_fragment = new LogInDialog(); -		return dialog_fragment; -	} -	 -    @Override -    public void onAttach(Activity activity) { -        super.onAttach(activity); -        try { -        	interface_with_Dashboard = (LogInDialogInterface) activity; -        } catch (ClassCastException e) { -            throw new ClassCastException(activity.toString() -                    + " must implement LogInDialogListener"); -        } -    } - -    @Override -    public void onCancel(DialogInterface dialog) { -	if(is_eip_pending) -	    interface_with_Dashboard.cancelAuthedEipOn(); -	super.onCancel(dialog);	     -    } -} diff --git a/src/se/leap/bitmaskclient/NewProviderDialog.java b/src/se/leap/bitmaskclient/NewProviderDialog.java deleted file mode 100644 index cf09c64b..00000000 --- a/src/se/leap/bitmaskclient/NewProviderDialog.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - package se.leap.bitmaskclient; - -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; -import se.leap.bitmaskclient.R; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.Toast; - -/** - * Implements the new custom provider dialog. - *  - * @author parmegv - * - */ -public class NewProviderDialog extends DialogFragment { - -    final public static String TAG = "newProviderDialog"; -         -	public interface NewProviderDialogInterface { -        public void showAndSelectProvider(String url_provider, boolean danger_on); -    } - -	NewProviderDialogInterface interface_with_ConfigurationWizard; - -	/** -	 * @return a new instance of this DialogFragment. -	 */ -	public static DialogFragment newInstance() { -		NewProviderDialog dialog_fragment = new NewProviderDialog(); -		return dialog_fragment; -	} -	 -    @Override -    public void onAttach(Activity activity) { -        super.onAttach(activity); -        try { -        	interface_with_ConfigurationWizard = (NewProviderDialogInterface) activity; -        } catch (ClassCastException e) { -            throw new ClassCastException(activity.toString() -                    + " must implement NoticeDialogListener"); -        } -    } - -    @Override -	public Dialog onCreateDialog(Bundle savedInstanceState) { -		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); -		LayoutInflater inflater = getActivity().getLayoutInflater(); -		View new_provider_dialog_view = inflater.inflate(R.layout.new_provider_dialog, null); -		final EditText url_input_field = (EditText)new_provider_dialog_view.findViewById(R.id.new_provider_url); -		if(getArguments() != null && getArguments().containsKey(Provider.MAIN_URL)) { -			url_input_field.setText(getArguments().getString(Provider.MAIN_URL)); -		} -		final CheckBox danger_checkbox = (CheckBox)new_provider_dialog_view.findViewById(R.id.danger_checkbox); -		if(getArguments() != null && getArguments().containsKey(ProviderItem.DANGER_ON)) { -			danger_checkbox.setActivated(getArguments().getBoolean(ProviderItem.DANGER_ON)); -		} -		 -		builder.setView(new_provider_dialog_view) -			.setMessage(R.string.introduce_new_provider) -			.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() { -				public void onClick(DialogInterface dialog, int id) { -					String entered_url = url_input_field.getText().toString().trim(); -					if(!entered_url.startsWith("https://")) { -						if (entered_url.startsWith("http://")){ -							entered_url = entered_url.substring("http://".length()); -						} -						entered_url = "https://".concat(entered_url); -					} -					boolean danger_on = danger_checkbox.isChecked(); -					if(validURL(entered_url)) { -						interface_with_ConfigurationWizard.showAndSelectProvider(entered_url, danger_on); -						Toast.makeText(getActivity().getApplicationContext(), R.string.valid_url_entered, Toast.LENGTH_LONG).show(); -					} else { -						url_input_field.setText(""); -						danger_checkbox.setChecked(false); -						Toast.makeText(getActivity().getApplicationContext(), R.string.not_valid_url_entered, Toast.LENGTH_LONG).show();; -					} -				} -			}) -			.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { -				public void onClick(DialogInterface dialog, int id) { -					dialog.cancel(); -				} -			}); -		// Create the AlertDialog object and return it -		return builder.create(); -	} - -    /** -     * Checks if the entered url is valid or not. -     * @param entered_url -     * @return true if it's not empty nor contains only the protocol. -     */ -	boolean validURL(String entered_url) { -		//return !entered_url.isEmpty() && entered_url.matches("http[s]?://.+") && !entered_url.replaceFirst("http[s]?://", "").isEmpty(); -		return android.util.Patterns.WEB_URL.matcher(entered_url).matches(); -	} -} diff --git a/src/se/leap/bitmaskclient/PRNGFixes.java b/src/se/leap/bitmaskclient/PRNGFixes.java deleted file mode 100644 index a046f01f..00000000 --- a/src/se/leap/bitmaskclient/PRNGFixes.java +++ /dev/null @@ -1,338 +0,0 @@ -package se.leap.bitmaskclient; - -/* - * This software is provided 'as-is', without any express or implied - * warranty.  In no event will Google be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, as long as the origin is not misrepresented. - * - * Source: http://android-developers.blogspot.de/2013/08/some-securerandom-thoughts.html - */ - -import android.os.Build; -import android.os.Process; -import android.util.Log; - -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.security.NoSuchAlgorithmException; -import java.security.Provider; -import java.security.SecureRandom; -import java.security.SecureRandomSpi; -import java.security.Security; - -/** - * Fixes for the output of the default PRNG having low entropy. - * - * The fixes need to be applied via {@link #apply()} before any use of Java - * Cryptography Architecture primitives. A good place to invoke them is in the - * application's {@code onCreate}. - */ -public final class PRNGFixes { - -    private static final int VERSION_CODE_JELLY_BEAN = 16; -    private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18; -    private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL = -        getBuildFingerprintAndDeviceSerial(); - -    /** Hidden constructor to prevent instantiation. */ -    private PRNGFixes() {} - -    /** -     * Applies all fixes. -     * -     * @throws SecurityException if a fix is needed but could not be applied. -     */ -    public static void apply() { -        applyOpenSSLFix(); -        installLinuxPRNGSecureRandom(); -    } - -    /** -     * Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the -     * fix is not needed. -     * -     * @throws SecurityException if the fix is needed but could not be applied. -     */ -    private static void applyOpenSSLFix() throws SecurityException { -        if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN) -                || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) { -            // No need to apply the fix -            return; -        } - -        try { -            // Mix in the device- and invocation-specific seed. -            Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto") -                    .getMethod("RAND_seed", byte[].class) -                    .invoke(null, generateSeed()); - -            // Mix output of Linux PRNG into OpenSSL's PRNG -            int bytesRead = (Integer) Class.forName( -                    "org.apache.harmony.xnet.provider.jsse.NativeCrypto") -                    .getMethod("RAND_load_file", String.class, long.class) -                    .invoke(null, "/dev/urandom", 1024); -            if (bytesRead != 1024) { -                throw new IOException( -                        "Unexpected number of bytes read from Linux PRNG: " -                                + bytesRead); -            } -        } catch (Exception e) { -            throw new SecurityException("Failed to seed OpenSSL PRNG", e); -        } -    } - -    /** -     * Installs a Linux PRNG-backed {@code SecureRandom} implementation as the -     * default. Does nothing if the implementation is already the default or if -     * there is not need to install the implementation. -     * -     * @throws SecurityException if the fix is needed but could not be applied. -     */ -    private static void installLinuxPRNGSecureRandom() -            throws SecurityException { -        if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) { -            // No need to apply the fix -            return; -        } - -        // Install a Linux PRNG-based SecureRandom implementation as the -        // default, if not yet installed. -        Provider[] secureRandomProviders = -                Security.getProviders("SecureRandom.SHA1PRNG"); -        if ((secureRandomProviders == null) -                || (secureRandomProviders.length < 1) -                || (!LinuxPRNGSecureRandomProvider.class.equals( -                        secureRandomProviders[0].getClass()))) { -            Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1); -        } - -        // Assert that new SecureRandom() and -        // SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed -        // by the Linux PRNG-based SecureRandom implementation. -        SecureRandom rng1 = new SecureRandom(); -        if (!LinuxPRNGSecureRandomProvider.class.equals( -                rng1.getProvider().getClass())) { -            throw new SecurityException( -                    "new SecureRandom() backed by wrong Provider: " -                            + rng1.getProvider().getClass()); -        } - -        SecureRandom rng2; -        try { -            rng2 = SecureRandom.getInstance("SHA1PRNG"); -        } catch (NoSuchAlgorithmException e) { -            throw new SecurityException("SHA1PRNG not available", e); -        } -        if (!LinuxPRNGSecureRandomProvider.class.equals( -                rng2.getProvider().getClass())) { -            throw new SecurityException( -                    "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" -                    + " Provider: " + rng2.getProvider().getClass()); -        } -    } - -    /** -     * {@code Provider} of {@code SecureRandom} engines which pass through -     * all requests to the Linux PRNG. -     */ -    private static class LinuxPRNGSecureRandomProvider extends Provider { - -        public LinuxPRNGSecureRandomProvider() { -            super("LinuxPRNG", -                    1.0, -                    "A Linux-specific random number provider that uses" -                        + " /dev/urandom"); -            // Although /dev/urandom is not a SHA-1 PRNG, some apps -            // explicitly request a SHA1PRNG SecureRandom and we thus need to -            // prevent them from getting the default implementation whose output -            // may have low entropy. -            put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName()); -            put("SecureRandom.SHA1PRNG ImplementedIn", "Software"); -        } -    } - -    /** -     * {@link SecureRandomSpi} which passes all requests to the Linux PRNG -     * ({@code /dev/urandom}). -     */ -    public static class LinuxPRNGSecureRandom extends SecureRandomSpi { - -        /* -         * IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed -         * are passed through to the Linux PRNG (/dev/urandom). Instances of -         * this class seed themselves by mixing in the current time, PID, UID, -         * build fingerprint, and hardware serial number (where available) into -         * Linux PRNG. -         * -         * Concurrency: Read requests to the underlying Linux PRNG are -         * serialized (on sLock) to ensure that multiple threads do not get -         * duplicated PRNG output. -         */ - -        private static final File URANDOM_FILE = new File("/dev/urandom"); - -        private static final Object sLock = new Object(); - -        /** -         * Input stream for reading from Linux PRNG or {@code null} if not yet -         * opened. -         * -         * @GuardedBy("sLock") -         */ -        private static DataInputStream sUrandomIn; - -        /** -         * Output stream for writing to Linux PRNG or {@code null} if not yet -         * opened. -         * -         * @GuardedBy("sLock") -         */ -        private static OutputStream sUrandomOut; - -        /** -         * Whether this engine instance has been seeded. This is needed because -         * each instance needs to seed itself if the client does not explicitly -         * seed it. -         */ -        private boolean mSeeded; - -        @Override -        protected void engineSetSeed(byte[] bytes) { -            try { -                OutputStream out; -                synchronized (sLock) { -                    out = getUrandomOutputStream(); -                } -                out.write(bytes); -                out.flush(); -            } catch (IOException e) { -                // On a small fraction of devices /dev/urandom is not writable. -                // Log and ignore. -                Log.w(PRNGFixes.class.getSimpleName(), -                        "Failed to mix seed into " + URANDOM_FILE); -            } finally { -                mSeeded = true; -            } -        } - -        @Override -        protected void engineNextBytes(byte[] bytes) { -            if (!mSeeded) { -                // Mix in the device- and invocation-specific seed. -                engineSetSeed(generateSeed()); -            } - -            try { -                DataInputStream in; -                synchronized (sLock) { -                    in = getUrandomInputStream(); -                } -                synchronized (in) { -                    in.readFully(bytes); -                } -            } catch (IOException e) { -                throw new SecurityException( -                        "Failed to read from " + URANDOM_FILE, e); -            } -        } - -        @Override -        protected byte[] engineGenerateSeed(int size) { -            byte[] seed = new byte[size]; -            engineNextBytes(seed); -            return seed; -        } - -        private DataInputStream getUrandomInputStream() { -            synchronized (sLock) { -                if (sUrandomIn == null) { -                    // NOTE: Consider inserting a BufferedInputStream between -                    // DataInputStream and FileInputStream if you need higher -                    // PRNG output performance and can live with future PRNG -                    // output being pulled into this process prematurely. -                    try { -                        sUrandomIn = new DataInputStream( -                                new FileInputStream(URANDOM_FILE)); -                    } catch (IOException e) { -                        throw new SecurityException("Failed to open " -                                + URANDOM_FILE + " for reading", e); -                    } -                } -                return sUrandomIn; -            } -        } - -        private OutputStream getUrandomOutputStream() throws IOException { -            synchronized (sLock) { -                if (sUrandomOut == null) { -                    sUrandomOut = new FileOutputStream(URANDOM_FILE); -                } -                return sUrandomOut; -            } -        } -    } - -    /** -     * Generates a device- and invocation-specific seed to be mixed into the -     * Linux PRNG. -     */ -    private static byte[] generateSeed() { -        try { -            ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream(); -            DataOutputStream seedBufferOut = -                    new DataOutputStream(seedBuffer); -            seedBufferOut.writeLong(System.currentTimeMillis()); -            seedBufferOut.writeLong(System.nanoTime()); -            seedBufferOut.writeInt(Process.myPid()); -            seedBufferOut.writeInt(Process.myUid()); -            seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL); -            seedBufferOut.close(); -            return seedBuffer.toByteArray(); -        } catch (IOException e) { -            throw new SecurityException("Failed to generate seed", e); -        } -    } - -    /** -     * Gets the hardware serial number of this device. -     * -     * @return serial number or {@code null} if not available. -     */ -    private static String getDeviceSerialNumber() { -        // We're using the Reflection API because Build.SERIAL is only available -        // since API Level 9 (Gingerbread, Android 2.3). -        try { -            return (String) Build.class.getField("SERIAL").get(null); -        } catch (Exception ignored) { -            return null; -        } -    } - -    private static byte[] getBuildFingerprintAndDeviceSerial() { -        StringBuilder result = new StringBuilder(); -        String fingerprint = Build.FINGERPRINT; -        if (fingerprint != null) { -            result.append(fingerprint); -        } -        String serial = getDeviceSerialNumber(); -        if (serial != null) { -            result.append(serial); -        } -        try { -            return result.toString().getBytes("UTF-8"); -        } catch (UnsupportedEncodingException e) { -            throw new RuntimeException("UTF-8 encoding not supported"); -        } -    } -} diff --git a/src/se/leap/bitmaskclient/Provider.java b/src/se/leap/bitmaskclient/Provider.java deleted file mode 100644 index 216f4261..00000000 --- a/src/se/leap/bitmaskclient/Provider.java +++ /dev/null @@ -1,212 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -package se.leap.bitmaskclient; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Locale; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.Context; -import android.app.Activity; -import android.content.SharedPreferences; - -/** - * @author Sean Leonard <meanderingcode@aetherislands.net> - * - */ -public final class Provider implements Serializable { - -	private static final long serialVersionUID = 6003835972151761353L; -	 -	private static Provider instance = null; -	 -	// We'll access our preferences here -	private static SharedPreferences preferences = null; -	// Represents our Provider's provider.json -	private static JSONObject definition = null; - -    final public static String -    API_URL = "api_uri", -	API_VERSION = "api_version", -	ALLOW_REGISTRATION = "allow_registration", -	API_RETURN_SERIAL = "serial", -	SERVICE = "service", -	KEY = "provider", -	CA_CERT = "ca_cert", -	NAME = "name", -	DESCRIPTION = "description", -	DOMAIN = "domain", -	MAIN_URL = "main_url", -	DOT_JSON_URL = "provider_json_url" -	; - -	// Array of what API versions we understand -	protected static final String[] API_VERSIONS = {"1"};  // I assume we might encounter arbitrary version "numbers" -	// Some API pieces we want to know about -	private static final String API_TERM_SERVICES = "services"; -	private static final String API_TERM_NAME = "name"; -	private static final String API_TERM_DOMAIN = "domain"; -	private static final String API_TERM_DEFAULT_LANGUAGE = "default_language"; -	protected static final String[] API_EIP_TYPES = {"openvpn"}; - -	private static final String PREFS_EIP_NAME = null; - - -	 -	// What, no individual fields?!  We're going to gamble on org.json.JSONObject and JSONArray -	// Supporting multiple API versions will probably break this paradigm, -	// Forcing me to write a real constructor and rewrite getters/setters -	// Also will refactor if i'm instantiating the same local variables all the time -	 -	/** -	 *  -	 */ -	private Provider() {} - -	protected static Provider getInstance(){ -		if(instance==null){ -			instance = new Provider(); -		} -		return instance; -	} - -	protected void init(Activity activity) { -		 -		// Load our preferences from SharedPreferences -		//   If there's nothing there, we will end up returning a rather empty object -		//   to whoever called getInstance() and they can run the First Run Wizard -		//preferences = context.getgetPreferences(0); // 0 == MODE_PRIVATE, but we don't extend Android's classes... -		 -		// Load SharedPreferences -		preferences = activity.getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE); -		// Inflate our provider.json data -		try { -			definition = new JSONObject( preferences.getString(Provider.KEY, "") ); -		} catch (JSONException e) { -			// TODO: handle exception -			 -			// FIXME!!  We want "real" data!! -		} -	} - -	protected String getDomain(){ -		String domain = "Null"; -		try { -			domain = definition.getString(API_TERM_DOMAIN); -		} catch (JSONException e) { -			domain = "Null"; -			e.printStackTrace(); -		} -		return domain; -	} -	 -	protected String getName(){ -		// Should we pass the locale in, or query the system here? -		String lang = Locale.getDefault().getLanguage(); -		String name = "Null"; // Should it actually /be/ null, for error conditions? -		try { -			name = definition.getJSONObject(API_TERM_NAME).getString(lang); -		} catch (JSONException e) { -			// TODO: Nesting try/catch blocks?  Crazy -			//  Maybe you should actually handle exception? -			try { -				name = definition.getJSONObject(API_TERM_NAME).getString( definition.getString(API_TERM_DEFAULT_LANGUAGE) ); -			} catch (JSONException e2) { -				// TODO: Will you handle the exception already? -			} -		} -		 -		return name; -	} -	 -	protected String getDescription(){ -		String lang = Locale.getDefault().getLanguage(); -		String desc = null; -		try { -			desc = definition.getJSONObject("description").getString(lang); -		} catch (JSONException e) { -			// TODO: handle exception!! -			try { -				desc = definition.getJSONObject("description").getString( definition.getString("default_language") ); -			} catch (JSONException e2) { -				// TODO: i can't believe you're doing it again! -			} -		} -		 -		return desc; -	} - -	protected boolean hasEIP() { -		JSONArray services = null; -		try { -			services = definition.getJSONArray(API_TERM_SERVICES); // returns ["openvpn"] -		} catch (Exception e) { -			// TODO: handle exception -		} -		for (int i=0;i<API_EIP_TYPES.length+1;i++){ -			try { -				// Walk the EIP types array looking for matches in provider's service definitions -				if ( Arrays.asList(API_EIP_TYPES).contains( services.getString(i) ) ) -					return true; -			} catch (NullPointerException e){ -				e.printStackTrace(); -				return false; -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -				return false; -			} -		} -		return false; -	} -	 -	protected String getEIPType() { -		// FIXME!!!!!  We won't always be providing /only/ OpenVPN, will we? -		// This will have to hook into some saved choice of EIP transport -		if ( instance.hasEIP() ) -			return "OpenVPN"; -		else -			return null; -	} -	 -	protected JSONObject getEIP() { -		// FIXME!!!!!  We won't always be providing /only/ OpenVPN, will we? -		// This will have to hook into some saved choice of EIP transport, cluster, gateway -		//   with possible "choose at random" preference -		if ( instance.hasEIP() ){ -			// TODO Might need an EIP class, but we've only got OpenVPN type right now, -			// and only one gateway for our only provider... -			// TODO We'll try to load from preferences, have to call ProviderAPI if we've got nothin... -			JSONObject eipObject = null; -			try { -				eipObject = new JSONObject( preferences.getString(PREFS_EIP_NAME, "") ); -			} catch (JSONException e) { -				// TODO ConfigHelper.rescueJSON() -				// Still nothing? -				// TODO ProviderAPI.getEIP() -				e.printStackTrace(); -			} -			 -			return eipObject; -		} else -			return null; -	} -} diff --git a/src/se/leap/bitmaskclient/ProviderAPI.java b/src/se/leap/bitmaskclient/ProviderAPI.java deleted file mode 100644 index 75ef511d..00000000 --- a/src/se/leap/bitmaskclient/ProviderAPI.java +++ /dev/null @@ -1,875 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - *  - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - package se.leap.bitmaskclient; - -import java.io.DataOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.math.BigInteger; -import java.net.CookieHandler; -import java.net.CookieManager; -import java.net.CookiePolicy; -import java.net.MalformedURLException; -import java.net.SocketTimeoutException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.net.UnknownHostException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Scanner; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -import org.apache.http.client.ClientProtocolException; -import org.jboss.security.srp.SRPParameters; -import org.json.JSONException; -import org.json.JSONObject; - -import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.ProviderListContent.ProviderItem; -import android.app.IntentService; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.ResultReceiver; -import android.util.Base64; -import android.util.Log; - - -/** - * Implements HTTP api methods used to manage communications with the provider server. - *  - * It's an IntentService because it downloads data from the Internet, so it operates in the background. - *   - * @author parmegv - * @author MeanderingCode - * - */ -public class ProviderAPI extends IntentService { -	 -	private Handler mHandler; - -    final public static String -    SET_UP_PROVIDER = "setUpProvider", -    DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON", -    SRP_REGISTER = "srpRegister", -    SRP_AUTH = "srpAuth", -    LOG_OUT = "logOut", -    DOWNLOAD_CERTIFICATE = "downloadUserAuthedCertificate", -    PARAMETERS = "parameters", -    RESULT_KEY = "result", -    RECEIVER_KEY = "receiver", -    SESSION_ID_COOKIE_KEY = "session_id_cookie_key", -    SESSION_ID_KEY = "session_id", -    ERRORS = "errors", -    UPDATE_PROGRESSBAR = "update_progressbar", -    CURRENT_PROGRESS = "current_progress", -    TAG = "provider_api_tag" -    ; - -    final public static int -    CUSTOM_PROVIDER_ADDED = 0, -    SRP_AUTHENTICATION_SUCCESSFUL = 3, -    SRP_AUTHENTICATION_FAILED = 4, -    SRP_REGISTRATION_SUCCESSFUL = 5, -    SRP_REGISTRATION_FAILED = 6, -    LOGOUT_SUCCESSFUL = 7, -    LOGOUT_FAILED = 8, -    CORRECTLY_DOWNLOADED_CERTIFICATE = 9, -    INCORRECTLY_DOWNLOADED_CERTIFICATE = 10, -    PROVIDER_OK = 11, -    PROVIDER_NOK = 12, -    CORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 13, -    INCORRECTLY_DOWNLOADED_ANON_CERTIFICATE = 14 -    ; - -    private static boolean  -    CA_CERT_DOWNLOADED = false, -    PROVIDER_JSON_DOWNLOADED = false, -    EIP_SERVICE_JSON_DOWNLOADED = false -    ; -     -    private static String last_provider_main_url; -    private static boolean last_danger_on = false; -    private static boolean setting_up_provider = true; -     -    public static void stop() { -    	setting_up_provider = false; -    } - -	public ProviderAPI() { -		super("ProviderAPI"); -		Log.v("ClassName", "Provider API"); -	} -	 -	@Override -	public void onCreate() { -		super.onCreate(); -		mHandler = new Handler(); -		CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER) ); -	} -	 -	public static String lastProviderMainUrl() { -		return last_provider_main_url; -	} -	 -    public static boolean lastDangerOn() { -    	return last_danger_on; -    } -     -	private String formatErrorMessage(final int toast_string_id) { -		return "{ \"" + ERRORS + "\" : \""+getResources().getString(toast_string_id)+"\" }"; -	} - -	@Override -	protected void onHandleIntent(Intent command) { -		final ResultReceiver receiver = command.getParcelableExtra(RECEIVER_KEY); -		String action = command.getAction(); -		Bundle parameters = command.getBundleExtra(PARAMETERS); -		setting_up_provider = true; -		 -		if(action.equalsIgnoreCase(SET_UP_PROVIDER)) { -			Bundle result = setUpProvider(parameters); -			if(setting_up_provider) { -				if(result.getBoolean(RESULT_KEY)) { -					receiver.send(PROVIDER_OK, result); -				} else {  -					receiver.send(PROVIDER_NOK, result); -				} -			} -		} else if (action.equalsIgnoreCase(SRP_AUTH)) { -			Bundle session_id_bundle = authenticateBySRP(parameters); -				if(session_id_bundle.getBoolean(RESULT_KEY)) { -					receiver.send(SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); -				} else { -					receiver.send(SRP_AUTHENTICATION_FAILED, session_id_bundle); -				} -		} else if (action.equalsIgnoreCase(LOG_OUT)) { -				if(logOut(parameters)) { -					receiver.send(LOGOUT_SUCCESSFUL, Bundle.EMPTY); -				} else { -					receiver.send(LOGOUT_FAILED, Bundle.EMPTY); -				} -		} else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) { -				if(getNewCert(parameters)) { -					receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); -				} else { -					receiver.send(INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); -				} -		} -	} -	 -	/** -	 * Starts the authentication process using SRP protocol. -	 *  -	 * @param task containing: username, password and api url.  -	 * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if authentication was successful.  -	 */ -	private Bundle authenticateBySRP(Bundle task) { -		Bundle session_id_bundle = new Bundle(); -		int progress = 0; -		 -		String username = (String) task.get(LogInDialog.USERNAME); -		String password = (String) task.get(LogInDialog.PASSWORD); -		if(validUserLoginData(username, password)) { -		 -			String authentication_server = (String) task.get(Provider.API_URL); - -			SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); -			LeapSRPSession client = new LeapSRPSession(username, password, params); -			byte[] A = client.exponential(); -			broadcast_progress(progress++); -			try { -				JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); -				if(saltAndB.length() > 0) { -					String salt = saltAndB.getString(LeapSRPSession.SALT); -					broadcast_progress(progress++); -					byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); -					byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); -					if(M1 != null) { -					broadcast_progress(progress++); -					JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); -					  if(session_idAndM2.has(LeapSRPSession.M2) && client.verify((byte[])session_idAndM2.get(LeapSRPSession.M2))) { -						  session_id_bundle.putBoolean(RESULT_KEY, true); -						  broadcast_progress(progress++); -					  } else { -						  session_id_bundle.putBoolean(RESULT_KEY, false); -						  session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); -						  session_id_bundle.putString(LogInDialog.USERNAME, username); -					  } -					} else { -						session_id_bundle.putBoolean(RESULT_KEY, false); -						session_id_bundle.putString(LogInDialog.USERNAME, username); -						session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_srp_math_error_user_message)); -					} -					broadcast_progress(progress++); -				} else { -					session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); -					session_id_bundle.putString(LogInDialog.USERNAME, username); -					session_id_bundle.putBoolean(RESULT_KEY, false); -				} -			} catch (ClientProtocolException e) { -				session_id_bundle.putBoolean(RESULT_KEY, false); -				session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_client_http_user_message)); -				session_id_bundle.putString(LogInDialog.USERNAME, username); -			} catch (IOException e) { -				session_id_bundle.putBoolean(RESULT_KEY, false); -				session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_io_exception_user_message)); -				session_id_bundle.putString(LogInDialog.USERNAME, username); -			} catch (JSONException e) { -				session_id_bundle.putBoolean(RESULT_KEY, false); -				session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_json_exception_user_message)); -				session_id_bundle.putString(LogInDialog.USERNAME, username); -			} catch (NoSuchAlgorithmException e) { -				session_id_bundle.putBoolean(RESULT_KEY, false); -				session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_no_such_algorithm_exception_user_message)); -				session_id_bundle.putString(LogInDialog.USERNAME, username); -			} catch (KeyManagementException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} catch (KeyStoreException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} catch (CertificateException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -		} else { -			if(!wellFormedPassword(password)) { -				session_id_bundle.putBoolean(RESULT_KEY, false); -				session_id_bundle.putString(LogInDialog.USERNAME, username); -				session_id_bundle.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true); -			} -			if(username.isEmpty()) { -				session_id_bundle.putBoolean(RESULT_KEY, false); -				session_id_bundle.putBoolean(LogInDialog.USERNAME_MISSING, true); -			} -		} -		 -		return session_id_bundle; -	} -	 -	/** -	 * Sets up an intent with the progress value passed as a parameter -	 * and sends it as a broadcast. -	 * @param progress -	 */ -	private void broadcast_progress(int progress) { -		Intent intentUpdate = new Intent(); -		intentUpdate.setAction(UPDATE_PROGRESSBAR); -		intentUpdate.addCategory(Intent.CATEGORY_DEFAULT); -		intentUpdate.putExtra(CURRENT_PROGRESS, progress); -		sendBroadcast(intentUpdate); -	} - -	/** -	 * Validates parameters entered by the user to log in -	 * @param entered_username -	 * @param entered_password -	 * @return true if both parameters are present and the entered password length is greater or equal to eight (8). -	 */ -	private boolean validUserLoginData(String entered_username, String entered_password) { -		return !(entered_username.isEmpty()) && wellFormedPassword(entered_password); -	} - -	/** -	 * Validates a password -	 * @param entered_password -	 * @return true if the entered password length is greater or equal to eight (8). -	 */ -	private boolean wellFormedPassword(String entered_password) { -		return entered_password.length() >= 8; -	} - -	/** -	 * Sends an HTTP POST request to the authentication server with the SRP Parameter A. -	 * @param server_url -	 * @param username -	 * @param clientA First SRP parameter sent  -	 * @return response from authentication server -	 * @throws ClientProtocolException -	 * @throws IOException -	 * @throws JSONException -	 * @throws CertificateException  -	 * @throws NoSuchAlgorithmException  -	 * @throws KeyStoreException  -	 * @throws KeyManagementException  -	 */ -	private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException { -		Map<String, String> parameters = new HashMap<String, String>(); -		parameters.put("login", username); -		parameters.put("A", clientA); -		return sendToServer(server_url + "/sessions.json", "POST", parameters); -		 -		/*HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + "login=" + username + "&&" + "A=" + clientA); -		return sendToServer(post);*/ -	} - -	/** -	 * Sends an HTTP PUT request to the authentication server with the SRP Parameter M1 (or simply M). -	 * @param server_url -	 * @param username -	 * @param m1 Second SRP parameter sent  -	 * @return response from authentication server -	 * @throws ClientProtocolException -	 * @throws IOException -	 * @throws JSONException -	 * @throws CertificateException  -	 * @throws NoSuchAlgorithmException  -	 * @throws KeyStoreException  -	 * @throws KeyManagementException  -	 */ -	private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException { -		Map<String, String> parameters = new HashMap<String, String>(); -		parameters.put("client_auth", new BigInteger(1, ConfigHelper.trim(m1)).toString(16)); -		 -		//HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + "client_auth" + "=" + new BigInteger(1, ConfigHelper.trim(m1)).toString(16)); -		JSONObject json_response = sendToServer(server_url + "/sessions/" + username +".json", "PUT", parameters); - -		JSONObject session_idAndM2 = new JSONObject(); -		if(json_response.length() > 0) { -			byte[] M2_not_trimmed = new BigInteger(json_response.getString(LeapSRPSession.M2), 16).toByteArray(); -			/*Cookie session_id_cookie = LeapHttpClient.getInstance(getApplicationContext()).getCookieStore().getCookies().get(0); -			session_idAndM2.put(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id_cookie.getName()); -			session_idAndM2.put(ConfigHelper.SESSION_ID_KEY, session_id_cookie.getValue());*/ -			session_idAndM2.put(LeapSRPSession.M2, ConfigHelper.trim(M2_not_trimmed)); -			CookieHandler.setDefault(null); // we don't need cookies anymore -			String token = json_response.getString(LeapSRPSession.TOKEN); -			LeapSRPSession.setToken(token); -		} -		return session_idAndM2; -	} -	 -	/** -	 * Executes an HTTP request expecting a JSON response. -	 * @param url -	 * @param request_method -	 * @param parameters -	 * @return response from authentication server -	 * @throws IOException -	 * @throws JSONException -	 * @throws MalformedURLException  -	 * @throws CertificateException  -	 * @throws NoSuchAlgorithmException  -	 * @throws KeyStoreException  -	 * @throws KeyManagementException  -	 */ -	private JSONObject sendToServer(String url, String request_method, Map<String, String> parameters) throws JSONException, MalformedURLException, IOException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException { -		JSONObject json_response; -		InputStream is = null; -		HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(url).openConnection(); -		urlConnection.setRequestMethod(request_method); -		urlConnection.setChunkedStreamingMode(0); -		urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); -		try { -			 -			DataOutputStream writer = new DataOutputStream(urlConnection.getOutputStream()); -			writer.writeBytes(formatHttpParameters(parameters)); -			writer.close(); - -			is = urlConnection.getInputStream(); -			String plain_response = new Scanner(is).useDelimiter("\\A").next(); -			json_response = new JSONObject(plain_response); -		} finally { -			InputStream error_stream = urlConnection.getErrorStream(); -			if(error_stream != null) { -				String error_response = new Scanner(error_stream).useDelimiter("\\A").next(); -				urlConnection.disconnect(); -				Log.d("Error", error_response); -				json_response = new JSONObject(error_response); -				if(!json_response.isNull(ERRORS) || json_response.has(ERRORS)) { -					return new JSONObject(); -				} -			} -		} - -		return json_response; -	} -	 -	private String formatHttpParameters(Map<String, String> parameters) throws UnsupportedEncodingException	{ -	    StringBuilder result = new StringBuilder(); -	    boolean first = true; - -		Iterator<String> parameter_iterator = parameters.keySet().iterator(); -		while(parameter_iterator.hasNext()) { -			if(first) -				first = false; -			else -				result.append("&&"); -			 -			String key = parameter_iterator.next(); -			String value = parameters.get(key); - -	        result.append(URLEncoder.encode(key, "UTF-8")); -	        result.append("="); -	        result.append(URLEncoder.encode(value, "UTF-8")); -		} - -	    return result.toString(); -	} -	 -	 -	 -	 -	/** -	 * Downloads a provider.json from a given URL, adding a new provider using the given name.   -	 * @param task containing a boolean meaning if the provider is custom or not, another boolean meaning if the user completely trusts this provider, the provider name and its provider.json url. -	 * @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if the update was successful.  -	 */ -	private Bundle setUpProvider(Bundle task) { -		int progress = 0; -		Bundle current_download = new Bundle(); -		 -		if(task != null && task.containsKey(ProviderItem.DANGER_ON) && task.containsKey(Provider.MAIN_URL)) { -			last_danger_on = task.getBoolean(ProviderItem.DANGER_ON); -			last_provider_main_url = task.getString(Provider.MAIN_URL); -			CA_CERT_DOWNLOADED = PROVIDER_JSON_DOWNLOADED = EIP_SERVICE_JSON_DOWNLOADED = false; -		} - -		if(!CA_CERT_DOWNLOADED) -			current_download = downloadCACert(last_provider_main_url, last_danger_on); -		if(CA_CERT_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { -			broadcast_progress(progress++); -			CA_CERT_DOWNLOADED = true; -			if(!PROVIDER_JSON_DOWNLOADED) -				current_download = getAndSetProviderJson(last_provider_main_url);  -			if(PROVIDER_JSON_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) { -				broadcast_progress(progress++); -				PROVIDER_JSON_DOWNLOADED = true; -				current_download = getAndSetEipServiceJson();  -				if(current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY)) { -					broadcast_progress(progress++); -					EIP_SERVICE_JSON_DOWNLOADED = true; -				} -			} -		} -		 -		return current_download; -	} -	 -	private Bundle downloadCACert(String provider_main_url, boolean danger_on) { -		Bundle result = new Bundle(); -		String cert_string = downloadWithCommercialCA(provider_main_url + "/ca.crt", danger_on); - -	    if(validCertificate(cert_string) && setting_up_provider) { -	    	getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit(); -			result.putBoolean(RESULT_KEY, true); -		} else { -			String reason_to_fail = pickErrorMessage(cert_string); -			result.putString(ERRORS, reason_to_fail); -			result.putBoolean(RESULT_KEY, false); -		} -		 -		return result; -	} -	 - -	public static boolean caCertDownloaded() { -		return CA_CERT_DOWNLOADED; -	} - -	private boolean validCertificate(String cert_string) { -		boolean result = false; -		if(!ConfigHelper.checkErroneousDownload(cert_string)) { -			X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string); -			try { -				Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); -				result = true; -			} catch (CertificateEncodingException e) { -				Log.d(TAG, e.getLocalizedMessage()); -			} -		} -		 -		return result; -	} -	 -	private Bundle getAndSetProviderJson(String provider_main_url) { -		Bundle result = new Bundle(); - -		if(setting_up_provider) { -			String provider_dot_json_string = downloadWithProviderCA(provider_main_url + "/provider.json", true); - -			try { -				JSONObject provider_json = new JSONObject(provider_dot_json_string); -				String name = provider_json.getString(Provider.NAME); -				//TODO setProviderName(name); - -				getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.KEY, provider_json.toString()).commit(); -				getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)).commit(); - -				result.putBoolean(RESULT_KEY, true); -			} catch (JSONException e) { -				//TODO Error message should be contained in that provider_dot_json_string -				String reason_to_fail = pickErrorMessage(provider_dot_json_string); -				result.putString(ERRORS, reason_to_fail); -				result.putBoolean(RESULT_KEY, false); -			} -		} -		return result; -	} - - -	 -	public static boolean providerJsonDownloaded() { -		return PROVIDER_JSON_DOWNLOADED; -	} - -	private Bundle getAndSetEipServiceJson() { -		Bundle result = new Bundle(); -		String eip_service_json_string = ""; -		if(setting_up_provider) { -			try { -				JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); -				String eip_service_url = provider_json.getString(Provider.API_URL) +  "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH; -				eip_service_json_string = downloadWithProviderCA(eip_service_url, true); -				JSONObject eip_service_json = new JSONObject(eip_service_json_string); -				eip_service_json.getInt(Provider.API_RETURN_SERIAL); - -				getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.KEY, eip_service_json.toString()).commit(); - -				result.putBoolean(RESULT_KEY, true); -			} catch (JSONException e) { -				String reason_to_fail = pickErrorMessage(eip_service_json_string); -				result.putString(ERRORS, reason_to_fail); -				result.putBoolean(RESULT_KEY, false); -			} -		} -		return result; -	} - -	public static boolean eipServiceDownloaded() { -		return EIP_SERVICE_JSON_DOWNLOADED; -	} -	 -	/** -	 * Interprets the error message as a JSON object and extract the "errors" keyword pair. -	 * If the error message is not a JSON object, then it is returned untouched. -	 * @param string_json_error_message -	 * @return final error message -	 */ -	private String pickErrorMessage(String string_json_error_message) { -		String error_message = ""; -		try { -			JSONObject json_error_message = new JSONObject(string_json_error_message); -			error_message = json_error_message.getString(ERRORS); -		} catch (JSONException e) { -			// TODO Auto-generated catch block -			error_message = string_json_error_message; -		} -		 -		return error_message; -	} -	 -	/** -	 * Tries to download the contents of the provided url using commercially validated CA certificate from chosen provider. -	 *  -	 * If danger_on flag is true, SSL exceptions will be managed by futher methods that will try to use some bypass methods. -	 * @param string_url -	 * @param danger_on if the user completely trusts this provider -	 * @return -	 */ -	private String downloadWithCommercialCA(String string_url, boolean danger_on) { -		 -		String json_file_content = ""; -		 -		URL provider_url = null; -		int seconds_of_timeout = 1; -		try { -			provider_url = new URL(string_url); -			URLConnection url_connection = provider_url.openConnection(); -			url_connection.setConnectTimeout(seconds_of_timeout*1000); -			if(!LeapSRPSession.getToken().isEmpty()) -				url_connection.addRequestProperty(LeapSRPSession.AUTHORIZATION_HEADER, "Token token = " + LeapSRPSession.getToken()); -			json_file_content = new Scanner(url_connection.getInputStream()).useDelimiter("\\A").next(); -		} catch (MalformedURLException e) { -			json_file_content = formatErrorMessage(R.string.malformed_url); -		} catch(SocketTimeoutException e) { -			json_file_content = formatErrorMessage(R.string.server_unreachable_message); -		} catch (IOException e) { -			if(provider_url != null) { -				json_file_content = downloadWithProviderCA(string_url, danger_on); -			} else { -				json_file_content = formatErrorMessage(R.string.certificate_error); -			} -		} catch (Exception e) { -			if(provider_url != null && danger_on) { -				json_file_content = downloadWithProviderCA(string_url, danger_on); -			} -		} - -		return json_file_content; -	} - -	/** -	 * Tries to download the contents of the provided url using not commercially validated CA certificate from chosen provider.  -	 * @param url as a string -	 * @param danger_on true to download CA certificate in case it has not been downloaded. -	 * @return an empty string if it fails, the url content if not.  -	 */ -	private String downloadWithProviderCA(String url_string, boolean danger_on) { -		String json_file_content = ""; - -		try { -			URL url = new URL(url_string); -			// Tell the URLConnection to use a SocketFactory from our SSLContext -			HttpsURLConnection urlConnection = -					(HttpsURLConnection)url.openConnection(); -			urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); -			if(!LeapSRPSession.getToken().isEmpty()) -				urlConnection.addRequestProperty(LeapSRPSession.AUTHORIZATION_HEADER, "Token token=" + LeapSRPSession.getToken()); -			json_file_content = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); -		} catch (CertificateException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (UnknownHostException e) { -			json_file_content = formatErrorMessage(R.string.server_unreachable_message); -		} catch (IOException e) { -			// The downloaded certificate doesn't validate our https connection. -			if(danger_on) { -				json_file_content = downloadWithoutCA(url_string); -			} else { -				json_file_content = formatErrorMessage(R.string.certificate_error); -			} -		} catch (KeyStoreException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (NoSuchAlgorithmException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (KeyManagementException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} -		return json_file_content; -	} -	 -	private javax.net.ssl.SSLSocketFactory getProviderSSLSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException { -		String provider_cert_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.CA_CERT,""); - -		java.security.cert.Certificate provider_certificate = ConfigHelper.parseX509CertificateFromString(provider_cert_string); - -		// Create a KeyStore containing our trusted CAs -		String keyStoreType = KeyStore.getDefaultType(); -		KeyStore keyStore = KeyStore.getInstance(keyStoreType); -		keyStore.load(null, null); -		keyStore.setCertificateEntry("provider_ca_certificate", provider_certificate); - -		// Create a TrustManager that trusts the CAs in our KeyStore -		String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); -		TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); -		tmf.init(keyStore); - -		// Create an SSLContext that uses our TrustManager -		SSLContext context = SSLContext.getInstance("TLS"); -		context.init(null, tmf.getTrustManagers(), null); - -		return context.getSocketFactory(); -	} -	 -	/** -	 * Downloads the string that's in the url with any certificate. -	 */ -	private String downloadWithoutCA(String url_string) { -		String string = ""; -		try { - -			HostnameVerifier hostnameVerifier = new HostnameVerifier() { -				@Override -				public boolean verify(String hostname, SSLSession session) { -					return true; -				} -			}; -			 -			class DefaultTrustManager implements X509TrustManager { - -				@Override -					public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} - -				@Override -					public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} - -				@Override -					public X509Certificate[] getAcceptedIssuers() { -						return null; -					} -			} - -			SSLContext context = SSLContext.getInstance("TLS"); -			context.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); - -			URL url = new URL(url_string); -			HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); -			urlConnection.setSSLSocketFactory(context.getSocketFactory()); -			urlConnection.setHostnameVerifier(hostnameVerifier); -			string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); -			System.out.println("String ignoring certificate = " + string); -		} catch (FileNotFoundException e) { -			e.printStackTrace(); -			string = formatErrorMessage(R.string.server_unreachable_message); -		} catch (IOException e) { -			// The downloaded certificate doesn't validate our https connection. -			e.printStackTrace(); -			string = formatErrorMessage(R.string.certificate_error); -		} catch (NoSuchAlgorithmException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (KeyManagementException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} -		return string; -	} -	 -	/** -	 * Logs out from the api url retrieved from the task. -	 * @param task containing api url from which the user will log out -	 * @return true if there were no exceptions -	 */ -	private boolean logOut(Bundle task) { -		try { -			String delete_url = task.getString(Provider.API_URL) + "/logout"; -			int progress = 0; - -			HttpsURLConnection urlConnection = (HttpsURLConnection)new URL(delete_url).openConnection(); -			urlConnection.setRequestMethod("DELETE"); -			urlConnection.setSSLSocketFactory(getProviderSSLSocketFactory()); - -			int responseCode = urlConnection.getResponseCode(); -			broadcast_progress(progress++); -			LeapSRPSession.setToken(""); -			Log.d(TAG, Integer.toString(responseCode)); -		} catch (ClientProtocolException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return false; -		} catch (IndexOutOfBoundsException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return false; -		} catch (IOException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return false; -		} catch (KeyManagementException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (KeyStoreException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (NoSuchAlgorithmException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} catch (CertificateException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		} -		return true; -	} - -	/** -	 * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate. -	 *  -	 * @param task containing the type of the certificate to be downloaded -	 * @return true if certificate was downloaded correctly, false if provider.json or danger_on flag are not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error.  -	 */ -	private boolean getNewCert(Bundle task) { - -		try { -			String type_of_certificate = task.getString(ConfigurationWizard.TYPE_OF_CERTIFICATE); -			JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, "")); -			 -			String provider_main_url = provider_json.getString(Provider.API_URL); -			URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE); - -			boolean danger_on = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getBoolean(ProviderItem.DANGER_ON, false); - -			String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), danger_on); - -			if(!cert_string.isEmpty()) { -				if(ConfigHelper.checkErroneousDownload(cert_string)) { -					String reason_to_fail = provider_json.getString(ERRORS); -					//result.putString(ConfigHelper.ERRORS_KEY, reason_to_fail); -					//result.putBoolean(ConfigHelper.RESULT_KEY, false); -					return false; -				} else { -					 -					// API returns concatenated cert & key.  Split them for OpenVPN options -					String certificateString = null, keyString = null; -					String[] certAndKey = cert_string.split("(?<=-\n)"); -					for (int i=0; i < certAndKey.length-1; i++){ -						if ( certAndKey[i].contains("KEY") ) { -							keyString = certAndKey[i++] + certAndKey[i]; -						} -						else if ( certAndKey[i].contains("CERTIFICATE") ) { -							certificateString = certAndKey[i++] + certAndKey[i]; -						} -					} -					try { -						RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString); -						keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT ); -						getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----").commit(); - -						X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString); -						certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); -						getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit(); -						 -						return true; -					} catch (CertificateException e) { -						// TODO Auto-generated catch block -						e.printStackTrace(); -						return false; -					} -				} -			} else { -				return false; -			} -		} catch (IOException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return false; -		} catch (JSONException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return false; -		} /*catch (URISyntaxException e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -			return false; -		}*/ -	} -} diff --git a/src/se/leap/bitmaskclient/ProviderAPIResultReceiver.java b/src/se/leap/bitmaskclient/ProviderAPIResultReceiver.java deleted file mode 100644 index 7b256124..00000000 --- a/src/se/leap/bitmaskclient/ProviderAPIResultReceiver.java +++ /dev/null @@ -1,56 +0,0 @@ -/**
 - * Copyright (c) 2013 LEAP Encryption Access Project and contributers
 - * 
 - * This program is free software: you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation, either version 3 of the License, or
 - * (at your option) any later version.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
 - */
 - package se.leap.bitmaskclient;
 -
 -import android.os.Bundle;
 -import android.os.Handler;
 -import android.os.ResultReceiver;
 -
 -/**
 - * Implements the ResultReceiver needed by Activities using ProviderAPI to receive the results of its operations. 
 - * @author parmegv
 - *
 - */
 -public class ProviderAPIResultReceiver extends ResultReceiver {
 -	private Receiver mReceiver;
 -	
 -	public ProviderAPIResultReceiver(Handler handler) {
 -		super(handler);
 -		// TODO Auto-generated constructor stub
 -	}
 -	
 -	public void setReceiver(Receiver receiver) {
 -        mReceiver = receiver;
 -    }
 -
 -	/**
 -	 * Interface to enable ProviderAPIResultReceiver to receive results from the ProviderAPI IntentService. 
 -	 * @author parmegv
 -	 *
 -	 */
 -    public interface Receiver {
 -        public void onReceiveResult(int resultCode, Bundle resultData);
 -    }
 -
 -    @Override
 -    protected void onReceiveResult(int resultCode, Bundle resultData) {
 -        if (mReceiver != null) {
 -            mReceiver.onReceiveResult(resultCode, resultData);
 -        }
 -    }
 -    
 -}
 diff --git a/src/se/leap/bitmaskclient/ProviderDetailFragment.java b/src/se/leap/bitmaskclient/ProviderDetailFragment.java deleted file mode 100644 index c067ce2b..00000000 --- a/src/se/leap/bitmaskclient/ProviderDetailFragment.java +++ /dev/null @@ -1,115 +0,0 @@ -package se.leap.bitmaskclient;
 -
 -import org.json.JSONException;
 -import org.json.JSONObject;
 -
 -import se.leap.bitmaskclient.R;
 -import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
 -
 -import android.app.Activity;
 -import android.app.AlertDialog;
 -import android.app.Dialog;
 -import android.app.DialogFragment;
 -import android.content.DialogInterface;
 -import android.content.SharedPreferences;
 -import android.os.Bundle;
 -import android.view.LayoutInflater;
 -import android.view.View;
 -import android.widget.TextView;
 -
 -public class ProviderDetailFragment extends DialogFragment {
 -
 -    final public static String TAG = "providerDetailFragment";
 -    
 -	@Override
 -	public Dialog onCreateDialog(Bundle savedInstanceState) {
 -		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
 -		try {
 -
 -			LayoutInflater inflater = getActivity().getLayoutInflater();
 -			View provider_detail_view = inflater.inflate(R.layout.provider_detail_fragment, null);
 -			
 -			JSONObject provider_json = new JSONObject(getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, getActivity().MODE_PRIVATE).getString(Provider.KEY, ""));
 -			
 -			final TextView domain = (TextView)provider_detail_view.findViewById(R.id.provider_detail_domain);
 -			domain.setText(provider_json.getString(Provider.DOMAIN));
 -			final TextView name = (TextView)provider_detail_view.findViewById(R.id.provider_detail_name);
 -			name.setText(provider_json.getJSONObject(Provider.NAME).getString("en"));
 -			final TextView description = (TextView)provider_detail_view.findViewById(R.id.provider_detail_description);
 -			description.setText(provider_json.getJSONObject(Provider.DESCRIPTION).getString("en"));
 -			
 -			builder.setView(provider_detail_view);
 -			builder.setTitle(R.string.provider_details_fragment_title);
 -			
 -			if(anon_allowed(provider_json)) {
 -				builder.setPositiveButton(R.string.use_anonymously_button, new DialogInterface.OnClickListener() {
 -					public void onClick(DialogInterface dialog, int id) {
 -						interface_with_configuration_wizard.use_anonymously();
 -					}
 -				});
 -			}
 -
 -			if(registration_allowed(provider_json)) {
 -				builder.setNegativeButton(R.string.login_button, new DialogInterface.OnClickListener() {
 -					public void onClick(DialogInterface dialog, int id) {
 -						interface_with_configuration_wizard.login();
 -					}
 -				});
 -			}
 -
 -			return builder.create();
 -		} catch (JSONException e) {
 -			return null;
 -		}
 -	}
 -	
 -	private boolean anon_allowed(JSONObject provider_json) {
 -		try {
 -			JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE);
 -			return service_description.has(EIP.ALLOWED_ANON) && service_description.getBoolean(EIP.ALLOWED_ANON);
 -		} catch (JSONException e) {
 -			return false;
 -		}
 -	}
 -	
 -	private boolean registration_allowed(JSONObject provider_json) {
 -		try {
 -			JSONObject service_description = provider_json.getJSONObject(Provider.SERVICE);
 -			return service_description.has(Provider.ALLOW_REGISTRATION) && service_description.getBoolean(Provider.ALLOW_REGISTRATION);
 -		} catch (JSONException e) {
 -			return false;
 -		}
 -	}
 -	
 -	@Override
 -	public void onCancel(DialogInterface dialog) {
 -		super.onCancel(dialog);
 -		SharedPreferences.Editor editor = getActivity().getSharedPreferences(Dashboard.SHARED_PREFERENCES, Activity.MODE_PRIVATE).edit();
 -		editor.remove(Provider.KEY).remove(ProviderItem.DANGER_ON).remove(EIP.ALLOWED_ANON).remove(EIP.KEY).commit(); -		interface_with_configuration_wizard.showAllProviders(); -	}
 -
 -	public static DialogFragment newInstance() {
 -		ProviderDetailFragment provider_detail_fragment = new ProviderDetailFragment();
 -		return provider_detail_fragment;
 -	}
 -	
 -    @Override
 -    public void onAttach(Activity activity) {
 -        super.onAttach(activity);
 -        try {
 -        	interface_with_configuration_wizard = (ProviderDetailFragmentInterface) activity;
 -        } catch (ClassCastException e) {
 -            throw new ClassCastException(activity.toString()
 -                    + " must implement LogInDialogListener");
 -        }
 -    }
 -	
 -	public interface ProviderDetailFragmentInterface {
 -		public void login();
 -		public void use_anonymously();
 -		public void showAllProviders();
 -	}
 -	
 -	ProviderDetailFragmentInterface interface_with_configuration_wizard;
 -}
 diff --git a/src/se/leap/bitmaskclient/ProviderListAdapter.java b/src/se/leap/bitmaskclient/ProviderListAdapter.java deleted file mode 100644 index 43bba085..00000000 --- a/src/se/leap/bitmaskclient/ProviderListAdapter.java +++ /dev/null @@ -1,114 +0,0 @@ -package se.leap.bitmaskclient; - -import java.util.List; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TwoLineListItem; - -public class ProviderListAdapter<T> extends ArrayAdapter<T> { -	private static boolean[] hidden = null; -	 -	public void hide(int position) { -		hidden[getRealPosition(position)] = true; -		notifyDataSetChanged(); -		notifyDataSetInvalidated(); -	} -	 -	public void unHide(int position) { -		hidden[getRealPosition(position)] = false; -		notifyDataSetChanged(); -		notifyDataSetInvalidated(); -	} -     -    public void unHideAll() { -    	for (int provider_index = 0; provider_index < hidden.length; provider_index++) -    		hidden[provider_index] = false; -    } -	 -	private int getRealPosition(int position) { -		int hElements = getHiddenCountUpTo(position); -		int diff = 0; -		for(int i=0;i<hElements;i++) { -			diff++; -			if(hidden[position+diff]) -				i--; -		} -		return (position + diff); -	} -	private int getHiddenCount() { -		int count = 0; -		for(int i=0;i<hidden.length;i++) -			if(hidden[i]) -				count++; -		return count; -	} -	private int getHiddenCountUpTo(int location) { -		int count = 0; -		for(int i=0;i<=location;i++) { -			if(hidden[i]) -				count++; -		} -		return count; -	} - -	@Override -	public int getCount() { -		return (hidden.length - getHiddenCount()); -	} - -	public ProviderListAdapter(Context mContext, int layout, List<T> objects) { -		super(mContext, layout, objects); -		if(hidden == null) { -			hidden = new boolean[objects.size()]; -			for (int i = 0; i < objects.size(); i++) -				hidden[i] = false; -		} -	} - -	public ProviderListAdapter(Context mContext, int layout, List<T> objects, boolean show_all_providers) { -		super(mContext, layout, objects); -		if(show_all_providers) { -			hidden = new boolean[objects.size()]; -			for (int i = 0; i < objects.size(); i++) -				hidden[i] = false; -		} -	} -	 -	@Override -	public void add(T item) { -		super.add(item); -		boolean[] new_hidden = new boolean[hidden.length+1]; -		System.arraycopy(hidden, 0, new_hidden, 0, hidden.length); -		new_hidden[hidden.length] = false; -		hidden = new_hidden; -	} -	 -	@Override -	public void remove(T item) { -		super.remove(item); -		boolean[] new_hidden = new boolean[hidden.length-1]; -		System.arraycopy(hidden, 0, new_hidden, 0, hidden.length-1); -		hidden = new_hidden; -	} - -	@Override -	public View getView(int index, View convertView, ViewGroup parent) { -		TwoLineListItem row; -		int position = getRealPosition(index); -		if (convertView == null) { -			LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); -			row = (TwoLineListItem)inflater.inflate(R.layout.provider_list_item, null);                     -		} else { -			row = (TwoLineListItem)convertView; -		} -		ProviderListContent.ProviderItem data = ProviderListContent.ITEMS.get(position); -		row.getText1().setText(data.domain()); -		row.getText2().setText(data.name()); - -		return row; -	} -} diff --git a/src/se/leap/bitmaskclient/ProviderListContent.java b/src/se/leap/bitmaskclient/ProviderListContent.java deleted file mode 100644 index e1ca4f9a..00000000 --- a/src/se/leap/bitmaskclient/ProviderListContent.java +++ /dev/null @@ -1,112 +0,0 @@ -/**
 - * Copyright (c) 2013 LEAP Encryption Access Project and contributers
 - * 
 - * This program is free software: you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation, either version 3 of the License, or
 - * (at your option) any later version.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
 - */
 - package se.leap.bitmaskclient;
 -
 -import java.io.IOException;
 -import java.io.InputStream;
 -import java.util.ArrayList;
 -import java.util.HashMap;
 -import java.util.List;
 -import java.util.Map;
 -import java.net.URL;
 -import java.net.MalformedURLException;
 -
 -import org.json.JSONException;
 -import org.json.JSONObject;
 -
 -/**
 - * Models the provider list shown in the ConfigurationWizard.
 - * 
 - * @author parmegv
 - *
 - */
 -public class ProviderListContent {
 -
 -	public static List<ProviderItem> ITEMS = new ArrayList<ProviderItem>();
 -
 -	public static Map<String, ProviderItem> ITEM_MAP = new HashMap<String, ProviderItem>();
 -
 -	/**
 -	 * Adds a new provider item to the end of the items map, and to the items list.
 -	 * @param item
 -	 */
 -	public static void addItem(ProviderItem item) {
 -		ITEMS.add(item);
 -		ITEM_MAP.put(String.valueOf(ITEMS.size()), item);
 -	}
 -	public static void removeItem(ProviderItem item) {
 -		ITEMS.remove(item);
 -		ITEM_MAP.remove(item);
 -	}
 -
 -	/**
 -	 * A provider item.
 -	 */ -	public static class ProviderItem {
 -		final public static String CUSTOM = "custom";
 -		final public static String DANGER_ON = "danger_on";
 -		private String provider_main_url;
 -		private String name; -
 -		/**
 -		 * @param name of the provider
 -		 * @param urls_file_input_stream file input stream linking with the assets url file
 -		 * @param custom if it's a new provider entered by the user or not
 -		 * @param danger_on if the user trusts completely the new provider
 -		 */
 -		public ProviderItem(String name, InputStream urls_file_input_stream) {
 -
 -			try {
 -				byte[] urls_file_bytes = new byte[urls_file_input_stream.available()];
 -				urls_file_input_stream.read(urls_file_bytes);
 -				String urls_file_content = new String(urls_file_bytes);
 -				JSONObject file_contents = new JSONObject(urls_file_content); -				provider_main_url = file_contents.getString(Provider.MAIN_URL);
 -				this.name = name;
 -			} catch (JSONException e) {
 -				// TODO Auto-generated catch block
 -				e.printStackTrace();
 -			} catch (IOException e) {
 -				// TODO Auto-generated catch block
 -				e.printStackTrace();
 -			}
 -		}
 -
 -		/**
 -		 * @param name of the provider
 -		 * @param provider_main_url used to download provider.json file of the provider
 -		 * @param provider_json already downloaded
 -		 * @param custom if it's a new provider entered by the user or not
 -		 */ -		public ProviderItem(String name, String provider_main_url) {
 -			this.name = name;
 -			this.provider_main_url = provider_main_url; -		}
 -		
 -		public String name() { return name; }
 -		
 -		public String providerMainUrl() { return provider_main_url; }
 -		
 -		public String domain() {
 -			try {
 -				return new URL(provider_main_url).getHost();
 -			} catch (MalformedURLException e) {
 -				return provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("/.*", "");
 -			}
 -		}
 -	}
 -}
 diff --git a/src/se/leap/bitmaskclient/ProviderListFragment.java b/src/se/leap/bitmaskclient/ProviderListFragment.java deleted file mode 100644 index db414d87..00000000 --- a/src/se/leap/bitmaskclient/ProviderListFragment.java +++ /dev/null @@ -1,234 +0,0 @@ -/**
 - * Copyright (c) 2013 LEAP Encryption Access Project and contributers
 - * 
 - * This program is free software: you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation, either version 3 of the License, or
 - * (at your option) any later version.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
 - */
 - package se.leap.bitmaskclient;
 -
 -import se.leap.bitmaskclient.R;
 -import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
 -import android.app.Activity;
 -import android.app.ListFragment;
 -import android.os.Bundle;
 -import android.view.LayoutInflater;
 -import android.view.View;
 -import android.view.ViewGroup;
 -import android.widget.ListView;
 -
 -/**
 - * A list fragment representing a list of Providers. This fragment
 - * also supports tablet devices by allowing list items to be given an
 - * 'activated' state upon selection. This helps indicate which item is
 - * currently being viewed in a {@link DashboardFragment}.
 - * <p>
 - * Activities containing this fragment MUST implement the {@link Callbacks}
 - * interface.
 - */
 -public class ProviderListFragment extends ListFragment {
 -
 -	public static String TAG = "provider_list_fragment";
 -	public static String SHOW_ALL_PROVIDERS = "show_all_providers";
 -	public static String TOP_PADDING = "top padding from providerlistfragment";
 -	private ProviderListAdapter<ProviderItem> content_adapter;
 -	
 -    /**
 -     * The serialization (saved instance state) Bundle key representing the
 -     * activated item position. Only used on tablets.
 -     */
 -    private static final String STATE_ACTIVATED_POSITION = "activated_position";
 -
 -    /**
 -     * The fragment's current callback object, which is notified of list item
 -     * clicks.
 -     */
 -    private Callbacks mCallbacks = sDummyCallbacks;
 -
 -    /**
 -     * The current activated item position. Only used on tablets.
 -     */
 -    private int mActivatedPosition = ListView.INVALID_POSITION;
 -
 -    /**
 -     * A callback interface that all activities containing this fragment must
 -     * implement. This mechanism allows activities to be notified of item
 -     * selections.
 -     */
 -    public interface Callbacks {
 -        /**
 -         * Callback for when an item has been selected.
 -         */
 -        public void onItemSelected(String id);
 -    }
 -
 -    /**
 -     * A dummy implementation of the {@link Callbacks} interface that does
 -     * nothing. Used only when this fragment is not attached to an activity.
 -     */
 -    private static Callbacks sDummyCallbacks = new Callbacks() {
 -        @Override
 -        public void onItemSelected(String id) {
 -        }
 -    };
 -
 -    /**
 -     * Mandatory empty constructor for the fragment manager to instantiate the
 -     * fragment (e.g. upon screen orientation changes).
 -     */
 -    public ProviderListFragment() {
 -    }
 -    
 -    @Override
 -    public void onCreate(Bundle savedInstanceState) {
 -    	super.onCreate(savedInstanceState);
 -    	if(getArguments().containsKey(SHOW_ALL_PROVIDERS))
 -    		content_adapter = new ProviderListAdapter<ProviderListContent.ProviderItem>(
 -    				getActivity(),
 -    				R.layout.provider_list_item,
 -    				ProviderListContent.ITEMS, getArguments().getBoolean(SHOW_ALL_PROVIDERS));
 -    	else
 -    		content_adapter = new ProviderListAdapter<ProviderListContent.ProviderItem>(
 -    				getActivity(),
 -    				R.layout.provider_list_item,
 -    				ProviderListContent.ITEMS);
 -    		
 -			
 -        setListAdapter(content_adapter);
 -    }
 -
 -    @Override
 -    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
 -    	return inflater.inflate(R.layout.provider_list_fragment, container, false);
 -    }
 -    
 -    @Override
 -    public void onViewCreated(View view, Bundle savedInstanceState) {
 -        super.onViewCreated(view, savedInstanceState);
 -
 -        // Restore the previously serialized activated item position.
 -        if (savedInstanceState != null
 -                && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
 -            setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
 -        }
 -    	if(getArguments() != null && getArguments().containsKey(TOP_PADDING)) {
 -    		int topPadding = getArguments().getInt(TOP_PADDING);
 -    		View current_view = getView();
 -    		getView().setPadding(current_view.getPaddingLeft(), topPadding, current_view.getPaddingRight(), current_view.getPaddingBottom());
 -    	}
 -    }
 -
 -    @Override
 -    public void onAttach(Activity activity) {
 -        super.onAttach(activity);
 -
 -        // Activities containing this fragment must implement its callbacks.
 -        if (!(activity instanceof Callbacks)) {
 -            throw new IllegalStateException("Activity must implement fragment's callbacks.");
 -        }
 -
 -        mCallbacks = (Callbacks) activity;
 -    }
 -
 -    @Override
 -    public void onDetach() {
 -        super.onDetach();
 -
 -        // Reset the active callbacks interface to the dummy implementation.
 -        mCallbacks = sDummyCallbacks;
 -    }
 -
 -    @Override
 -    public void onListItemClick(ListView listView, View view, int position, long id) {
 -        super.onListItemClick(listView, view, position, id);
 -
 -        // Notify the active callbacks interface (the activity, if the
 -        // fragment is attached to one) that an item has been selected.
 -        mCallbacks.onItemSelected(ProviderListContent.ITEMS.get(position).name());
 -
 -        for(int item_position = 0; item_position < listView.getCount(); item_position++) {
 -        	if(item_position != position)
 -        		content_adapter.hide(item_position);
 -        }
 -    }
 -
 -    @Override
 -    public void onSaveInstanceState(Bundle outState) {
 -        super.onSaveInstanceState(outState);
 -        if (mActivatedPosition != ListView.INVALID_POSITION) {
 -            // Serialize and persist the activated item position.
 -            outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
 -        }
 -    }
 -
 -    public void notifyAdapter() {
 -    	content_adapter.notifyDataSetChanged();
 -    }
 -    /**
 -     * Turns on activate-on-click mode. When this mode is on, list items will be
 -     * given the 'activated' state when touched.
 -     */
 -    public void setActivateOnItemClick(boolean activateOnItemClick) {
 -        // When setting CHOICE_MODE_SINGLE, ListView will automatically
 -        // give items the 'activated' state when touched.
 -        getListView().setChoiceMode(activateOnItemClick
 -                ? ListView.CHOICE_MODE_SINGLE
 -                : ListView.CHOICE_MODE_NONE);
 -    }
 -
 -    private void setActivatedPosition(int position) {
 -        if (position == ListView.INVALID_POSITION) {
 -            getListView().setItemChecked(mActivatedPosition, false);
 -        } else {
 -            getListView().setItemChecked(position, true);
 -        }
 -
 -        mActivatedPosition = position;
 -    }
 -    
 -    public void removeLastItem() {
 -    	unhideAll();
 -    	content_adapter.remove(content_adapter.getItem(content_adapter.getCount()-1));
 -    	content_adapter.notifyDataSetChanged();
 -    }
 -    
 -    public void addItem(ProviderItem provider) {
 -    	content_adapter.add(provider);
 -    	content_adapter.notifyDataSetChanged();
 -    }
 -    
 -    public void hideAllBut(int position) {
 -    	int real_count = content_adapter.getCount();
 -    	for(int i = 0; i < real_count;)
 -    		if(i != position) {
 -    			content_adapter.hide(i);
 -    			position--;
 -    			real_count--;
 -    		} else {
 -    			i++;
 -    		} -    }
 -    
 -    public void unhideAll() {
 -    	if(content_adapter != null) {
 -    		content_adapter.unHideAll();
 -    		content_adapter.notifyDataSetChanged();
 -    	}
 -    }
 -
 -	/**
 -	 * @return a new instance of this ListFragment.
 -	 */
 -	public static ProviderListFragment newInstance() {
 -		return new ProviderListFragment();
 -	}
 -}
 diff --git a/src/se/leap/openvpn/CIDRIP.java b/src/se/leap/openvpn/CIDRIP.java deleted file mode 100644 index 8c4b6709..00000000 --- a/src/se/leap/openvpn/CIDRIP.java +++ /dev/null @@ -1,58 +0,0 @@ -package se.leap.openvpn; - -class CIDRIP{ -	String mIp; -	int len; -	public CIDRIP(String ip, String mask){ -		mIp=ip; -		long netmask=getInt(mask); - -		// Add 33. bit to ensure the loop terminates -		netmask += 1l << 32; - -		int lenZeros = 0; -		while((netmask & 0x1) == 0) { -			lenZeros++; -			netmask = netmask >> 1; -		} -		// Check if rest of netmask is only 1s -		if(netmask != (0x1ffffffffl >> lenZeros)) { -			// Asume no CIDR, set /32 -			len=32; -		} else { -			len =32 -lenZeros;  -		} - -	} -	@Override -	public String toString() { -		return String.format("%s/%d",mIp,len); -	} - -	public boolean normalise(){ -		long ip=getInt(mIp); - -		long newip = ip & (0xffffffffl << (32 -len)); -		if (newip != ip){ -			mIp = String.format("%d.%d.%d.%d", (newip & 0xff000000) >> 24,(newip & 0xff0000) >> 16, (newip & 0xff00) >> 8 ,newip & 0xff); -			return true; -		} else { -			return false; -		} -	} -	static long getInt(String ipaddr) { -		String[] ipt = ipaddr.split("\\."); -		long ip=0; - -		ip += Long.parseLong(ipt[0])<< 24; -		ip += Integer.parseInt(ipt[1])<< 16; -		ip += Integer.parseInt(ipt[2])<< 8; -		ip += Integer.parseInt(ipt[3]); - -		return ip; -	} -	public long getInt() { -		return getInt(mIp); -	} -	 -}
\ No newline at end of file diff --git a/src/se/leap/openvpn/ConfigParser.java b/src/se/leap/openvpn/ConfigParser.java deleted file mode 100644 index df4eae1b..00000000 --- a/src/se/leap/openvpn/ConfigParser.java +++ /dev/null @@ -1,569 +0,0 @@ -package se.leap.openvpn; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.util.HashMap; -import java.util.Locale; -import java.util.Vector; - -//! Openvpn Config FIle Parser, probably not 100% accurate but close enough - -// And rember, this is valid :) -// --<foo> -// bar -// </foo> -public class ConfigParser { - - -	private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>(); -	public void parseConfig(Reader reader) throws IOException, ConfigParseError { - - -		BufferedReader br =new BufferedReader(reader); - -		@SuppressWarnings("unused") -		int lineno=0; - -		while (true){ -			String line = br.readLine(); -			if(line==null) -				break; -			lineno++; -			Vector<String> args = parseline(line); -			if(args.size() ==0) -				continue; - - -			if(args.get(0).startsWith("--")) -				args.set(0, args.get(0).substring(2)); - -			checkinlinefile(args,br); - -			String optionname = args.get(0); -			if(!options.containsKey(optionname)) { -				options.put(optionname, new Vector<Vector<String>>()); -			} -			options.get(optionname).add(args); -		} -	} -	public void setDefinition(HashMap<String,Vector<Vector<String>>> args) { -		options = args; -	} - -	private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError { -		String arg0 = args.get(0); -		// CHeck for <foo> -		if(arg0.startsWith("<") && arg0.endsWith(">")) { -			String argname = arg0.substring(1, arg0.length()-1); -			String inlinefile = VpnProfile.INLINE_TAG; - -			String endtag = String.format("</%s>",argname); -			do { -				String line = br.readLine(); -				if(line==null){ -					throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found",argname,argname)); -				} -				if(line.equals(endtag)) -					break; -				else { -					inlinefile+=line; -					inlinefile+= "\n";					 -				} -			} while(true); - -			args.clear(); -			args.add(argname); -			args.add(inlinefile); -		} - -	} - -	enum linestate { -		initial, -		readin_single_quote -		, reading_quoted, reading_unquoted, done} - -	private boolean space(char c) { -		// I really hope nobody is using zero bytes inside his/her config file -		// to sperate parameter but here we go: -		return Character.isWhitespace(c) || c == '\0'; - -	} - -	public class ConfigParseError extends Exception { -		private static final long serialVersionUID = -60L; - -		public ConfigParseError(String msg) { -			super(msg); -		} -	} - - -	// adapted openvpn's parse function to java -	private Vector<String> parseline(String line) throws ConfigParseError { -		Vector<String> parameters = new Vector<String>();  - -		if (line.length()==0) -			return parameters; - - -		linestate state = linestate.initial; -		boolean backslash = false; -		char out=0; - -		int pos=0; -		String currentarg=""; - -		do {  -			// Emulate the c parsing ... -			char in; -			if(pos < line.length()) -				in = line.charAt(pos); -			else  -				in = '\0'; - -			if (!backslash && in == '\\' && state != linestate.readin_single_quote) -			{ -				backslash = true; -			} -			else -			{ -				if (state == linestate.initial) -				{ -					if (!space (in)) -					{ -						if (in == ';' || in == '#') /* comment */ -							break; -						if (!backslash && in == '\"') -							state = linestate.reading_quoted; -						else if (!backslash && in == '\'') -							state = linestate.readin_single_quote; -						else -						{ -							out = in; -							state = linestate.reading_unquoted; -						} -					} -				} -				else if (state == linestate.reading_unquoted) -				{ -					if (!backslash && space (in)) -						state = linestate.done; -					else -						out = in; -				} -				else if (state == linestate.reading_quoted) -				{ -					if (!backslash && in == '\"') -						state = linestate.done; -					else -						out = in; -				} -				else if (state == linestate.readin_single_quote) -				{ -					if (in == '\'') -						state = linestate.done; -					else -						out = in; -				} - -				if (state == linestate.done) -				{ -					/* ASSERT (parm_len > 0); */ -					state = linestate.initial; -					parameters.add(currentarg); -					currentarg = ""; -					out =0; -				} - -				if (backslash && out!=0) -				{ -					if (!(out == '\\' || out == '\"' || space (out))) -					{ -						throw new ConfigParseError("Options warning: Bad backslash ('\\') usage"); -					} -				} -				backslash = false; -			} - -			/* store parameter character */ -			if (out!=0) -			{ -				currentarg+=out; -			} -		} while (pos++ < line.length()); - -		return parameters; -	} - - -	final String[] unsupportedOptions = { "config",  -			"connection",  -			"proto-force",  -			"remote-random", -			"tls-server" - -	}; - -	// Ignore all scripts -	// in most cases these won't work and user who wish to execute scripts will -	// figure out themselves -	final String[] ignoreOptions = { "tls-client", -			"askpass", -			"auth-nocache", -			"up", -			"down", -			"route-up", -			"ipchange", -			"route-up", -			"route-pre-down", -			"auth-user-pass-verify", -			"dhcp-release", -			"dhcp-renew", -			"dh", -			"management-hold", -			"management", -			"management-query-passwords", -			"pause-exit", -			"persist-key", -			"register-dns", -			"route-delay", -			"route-gateway", -			"route-metric", -			"route-method", -			"status", -			"script-security", -			"show-net-up", -			"suppress-timestamps", -			"tmp-dir", -			"tun-ipv6", -			"topology", -			"win-sys", -	}; -	 -	 -	// This method is far too long -	public VpnProfile convertProfile() throws ConfigParseError{ -		boolean noauthtypeset=true; -		VpnProfile np = new VpnProfile("converted Profile"); -		// Pull, client, tls-client -		np.clearDefaults(); - -		// XXX we are always client -		if(/*options.containsKey("client") || options.containsKey("pull")*/ true) { -			np.mUsePull=true; -			options.remove("pull"); -			options.remove("client"); -		} -		 -		Vector<String> secret = getOption("secret", 1, 2); -		if(secret!=null)  -		{ -			np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; -			noauthtypeset=false; -			np.mUseTLSAuth=true; -			np.mTLSAuthFilename=secret.get(1); -			if(secret.size()==3) -				np.mTLSAuthDirection=secret.get(2); -			 -		} -		 -		Vector<Vector<String>> routes = getAllOption("route", 1, 4); -		if(routes!=null) { -			String routeopt = ""; -			for(Vector<String> route:routes){ -				String netmask = "255.255.255.255"; -				if(route.size() >= 3) -					netmask = route.get(2); -				String net = route.get(1);	 -				try { -					CIDRIP cidr = new CIDRIP(net, netmask); -					routeopt+=cidr.toString() + " "; -				} catch (ArrayIndexOutOfBoundsException aioob) { -					throw new ConfigParseError("Could not parse netmask of route " + netmask); -				} catch (NumberFormatException ne) { -					throw new ConfigParseError("Could not parse netmask of route " + netmask); -				} -			 -			} -			np.mCustomRoutes=routeopt; -		} - -		// Also recognize tls-auth [inline] direction ...  -		Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2); -		if(tlsauthoptions!=null) { -			for(Vector<String> tlsauth:tlsauthoptions) { -				if(tlsauth!=null)  -				{ -					if(!tlsauth.get(1).equals("[inline]")) { -						np.mTLSAuthFilename=tlsauth.get(1); -						np.mUseTLSAuth=true; -					} -					if(tlsauth.size()==3) -						np.mTLSAuthDirection=tlsauth.get(2); -				} -			} -		} -		 -		Vector<String> direction = getOption("key-direction", 1, 1); -		if(direction!=null) -			np.mTLSAuthDirection=direction.get(1); - - -		if(getAllOption("redirect-gateway", 0, 5) != null) -			np.mUseDefaultRoute=true; - -		Vector<String> dev =getOption("dev",1,1); -		Vector<String> devtype =getOption("dev-type",1,1); - -		if( (devtype !=null && devtype.get(1).equals("tun")) ||   -				(dev!=null && dev.get(1).startsWith("tun")) ||  -				(devtype ==null && dev == null) ) { -			//everything okay  -		} else { -			throw new ConfigParseError("Sorry. Only tun mode is supported. See the FAQ for more detail"); -		} - - - -		Vector<String> mode =getOption("mode",1,1); -		if (mode != null){ -			if(!mode.get(1).equals("p2p")) -				throw new ConfigParseError("Invalid mode for --mode specified, need p2p"); -		} -		 -		Vector<String> port = getOption("port", 1,1); -		if(port!=null){ -			np.mServerPort = port.get(1); -		} -		 -		Vector<String> proto = getOption("proto", 1,1); -		if(proto!=null){ -			np.mUseUdp=isUdpProto(proto.get(1));; -		} - -		// Parse remote config -		Vector<String> remote = getOption("remote",1,3); -		if(remote != null){ -			switch (remote.size()) { -			case 4: -				np.mUseUdp=isUdpProto(remote.get(3)); -			case 3: -				np.mServerPort = remote.get(2); -			case 2: -				np.mServerName = remote.get(1); -			} -		} -		 -		// Parse remote config -		Vector<String> location = getOption("location",0,2); -		if(location != null && location.size() == 2){ -			np.mLocation = location.get(1).replace("__", ", "); -		} - -		Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2); -		if(dhcpoptions!=null) { -			for(Vector<String> dhcpoption:dhcpoptions) { -				String type=dhcpoption.get(1); -				String arg = dhcpoption.get(2); -				if(type.equals("DOMAIN")) { -					np.mSearchDomain=dhcpoption.get(2); -				} else if(type.equals("DNS")) { -					np.mOverrideDNS=true; -					if(np.mDNS1.equals(VpnProfile.DEFAULT_DNS1)) -						np.mDNS1=arg; -					else -						np.mDNS2=arg; -				} -			} -		} - -		Vector<String> ifconfig = getOption("ifconfig", 2, 2); -		if(ifconfig!=null) { -			CIDRIP cidr = new CIDRIP(ifconfig.get(1), ifconfig.get(2)); -			np.mIPv4Address=cidr.toString(); -		} -		 -		if(getOption("remote-random-hostname", 0, 0)!=null) -			np.mUseRandomHostname=true; - -		if(getOption("float", 0, 0)!=null) -			np.mUseFloat=true; - -		if(getOption("comp-lzo", 0, 1)!=null) -			np.mUseLzo=true; - -		Vector<String> cipher = getOption("cipher", 1, 1); -		if(cipher!=null) -			np.mCipher= cipher.get(1); - -		Vector<String> ca = getOption("ca",1,1); -		if(ca!=null){ -			np.mCaFilename = ca.get(1); -		} - -		Vector<String> cert = getOption("cert",1,1); -		if(cert!=null){ -			np.mClientCertFilename = cert.get(1); -			np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES; -			noauthtypeset=false; -		} -		Vector<String> key= getOption("key",1,1); -		if(key!=null) -			np.mClientKeyFilename=key.get(1); - -		Vector<String> pkcs12 = getOption("pkcs12",1,1); -		if(pkcs12!=null) { -			np.mPKCS12Filename = pkcs12.get(1); -			np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; -			noauthtypeset=false; -		} - -		Vector<String> tlsremote = getOption("tls-remote",1,1); -		if(tlsremote!=null){ -			np.mRemoteCN = tlsremote.get(1); -			np.mCheckRemoteCN=true; -		}  - -		Vector<String> verb = getOption("verb",1,1); -		if(verb!=null){ -			np.mVerb=verb.get(1); -		} - -		 -		if(getOption("nobind", 0, 0) != null) -			np.mNobind=true; -		 -		if(getOption("persist-tun", 0,0) != null) -			np.mPersistTun=true; -		 -		Vector<String> connectretry = getOption("connect-retry", 1, 1); -		if(connectretry!=null) -			np.mConnectRetry =connectretry.get(1); -		 -		Vector<String> connectretrymax = getOption("connect-retry-max", 1, 1); -		if(connectretrymax!=null) -			np.mConnectRetryMax =connectretrymax.get(1); -		 -		Vector<Vector<String>> remotetls = getAllOption("remote-cert-tls", 1, 1); -		if(remotetls!=null) -			if(remotetls.get(0).get(1).equals("server")) -				np.mExpectTLSCert=true; -			else -				options.put("remotetls",remotetls); -		 -		Vector<String> authuser = getOption("auth-user-pass",0,1); -		if(authuser !=null){ -			if(noauthtypeset) { -				np.mAuthenticationType=VpnProfile.TYPE_USERPASS; -			} else if(np.mAuthenticationType==VpnProfile.TYPE_CERTIFICATES) { -				np.mAuthenticationType=VpnProfile.TYPE_USERPASS_CERTIFICATES; -			} else if(np.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) { -				np.mAuthenticationType=VpnProfile.TYPE_USERPASS_KEYSTORE; -			} -			if(authuser.size()>1) { -				// Set option value to password get to get canche to embed later. -				np.mUsername=null; -				np.mPassword=authuser.get(1); -				useEmbbedUserAuth(np,authuser.get(1)); -			} -			 -		} - -		 -		// Check the other options - -		checkIgnoreAndInvalidOptions(np); -		fixup(np); - -		return np; -	} - -	private boolean isUdpProto(String proto) throws ConfigParseError { -		boolean isudp; -		if(proto.equals("udp") || proto.equals("udp6")) -			isudp=true; -		else if (proto.equals("tcp-client") || -				proto.equals("tcp")  ||  -				proto.equals("tcp6") || -				proto.endsWith("tcp6-client")) -			isudp =false; -		else  -			throw new ConfigParseError("Unsupported option to --proto " + proto); -		return isudp; -	} -	 -	static public void useEmbbedUserAuth(VpnProfile np,String inlinedata) -	{ -		String data = inlinedata.replace(VpnProfile.INLINE_TAG, ""); -		String[] parts = data.split("\n"); -		if(parts.length >= 2) { -			np.mUsername=parts[0]; -			np.mPassword=parts[1]; -		} -	} - -	private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError { -		for(String option:unsupportedOptions) -			if(options.containsKey(option)) -				throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting",option)); - -		for(String option:ignoreOptions) -			// removing an item which is not in the map is no error -			options.remove(option); - -		if(options.size()> 0) { -			String custom = "# These Options were found in the config file do not map to config settings:\n"; - -			for(Vector<Vector<String>> option:options.values()) { -				for(Vector<String> optionsline: option) { -					for (String arg : optionsline) -						custom+= VpnProfile.openVpnEscape(arg) + " "; -				} -				custom+="\n"; - -			} -			np.mCustomConfigOptions = custom; -			np.mUseCustomConfig=true; - -		} -	} - - -	private void fixup(VpnProfile np) { -		if(np.mRemoteCN.equals(np.mServerName)) { -			np.mRemoteCN=""; -		} -	} - -	private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError { -		Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg); -		if(alloptions==null) -			return null; -		else -			return alloptions.lastElement(); -	} - - -	private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError { -		Vector<Vector<String>> args = options.get(option); -		if(args==null) -			return null; - -		for(Vector<String> optionline:args) - -			if(optionline.size()< (minarg+1) || optionline.size() > maxarg+1) { -				String err = String.format(Locale.getDefault(),"Option %s has %d parameters, expected between %d and %d", -						option,optionline.size()-1,minarg,maxarg ); -				throw new ConfigParseError(err); -			} -		options.remove(option); -		return args; -	} - -} - - - - diff --git a/src/se/leap/openvpn/LICENSE.txt b/src/se/leap/openvpn/LICENSE.txt deleted file mode 100644 index d897edea..00000000 --- a/src/se/leap/openvpn/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -License for OpenVPN for Android. Please note that the thirdparty libraries/executables may have other license (OpenVPN, lzo, OpenSSL, Google Breakpad) - -Copyright (c) 2012-2013, Arne Schwabe - All rights reserved. - -If you need a non GPLv2 license of the source please contact me. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -In addition, as a special exception, the copyright holders give -permission to link the code of portions of this program with the -OpenSSL library. diff --git a/src/se/leap/openvpn/LaunchVPN.java b/src/se/leap/openvpn/LaunchVPN.java deleted file mode 100644 index 89f2d372..00000000 --- a/src/se/leap/openvpn/LaunchVPN.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - *      http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package se.leap.openvpn; - -import java.io.IOException; -import java.util.Collection; -import java.util.Vector; - -import se.leap.bitmaskclient.ConfigHelper; -import se.leap.bitmaskclient.EIP; -import se.leap.bitmaskclient.R; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.ListActivity; -import android.content.ActivityNotFoundException; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.VpnService; -import android.os.Bundle; -import android.os.Parcelable; -import android.os.ResultReceiver; -import android.preference.PreferenceManager; -import android.text.InputType; -import android.text.method.PasswordTransformationMethod; -import android.view.View; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; - -/** - * This Activity actually handles two stages of a launcher shortcut's life cycle. - *  - * 1. Your application offers to provide shortcuts to the launcher.  When - *    the user installs a shortcut, an activity within your application - *    generates the actual shortcut and returns it to the launcher, where it - *    is shown to the user as an icon. - * - * 2. Any time the user clicks on an installed shortcut, an intent is sent. - *    Typically this would then be handled as necessary by an activity within - *    your application. - *     - * We handle stage 1 (creating a shortcut) by simply sending back the information (in the form - * of an {@link android.content.Intent} that the launcher will use to create the shortcut. - *  - * You can also implement this in an interactive way, by having your activity actually present - * UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL, - * media item, or action. - *  - * We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents - * of the incoming {@link android.content.Intent}. - *  - * In a real application, you would probably use the shortcut intent to display specific content - * or start a particular operation. - */ -public class LaunchVPN extends ListActivity implements OnItemClickListener { - -	public static final String EXTRA_KEY = "se.leap.openvpn.shortcutProfileUUID"; -	public static final String EXTRA_NAME = "se.leap.openvpn.shortcutProfileName"; -	public static final String EXTRA_HIDELOG =  "se.leap.openvpn.showNoLogWindow";; - -	public static final int START_VPN_PROFILE= 70; -	 -	// Dashboard, maybe more, want to know! -	private ResultReceiver mReceiver; - -	private ProfileManager mPM; -	private VpnProfile mSelectedProfile; -	private boolean mhideLog=false; - -	private boolean mCmfixed=false; - -	@Override -	public void onCreate(Bundle icicle) { -		super.onCreate(icicle); - -		mPM =ProfileManager.getInstance(this); -	 -	}	 - -	@Override -	protected void onStart() { -		super.onStart(); -		// Resolve the intent - -		final Intent intent = getIntent(); -		final String action = intent.getAction(); -		 -		// If something wants feedback, they sent us a Receiver -		mReceiver = intent.getParcelableExtra(EIP.RECEIVER_TAG); -		 -		// If the intent is a request to create a shortcut, we'll do that and exit - -		 -		if(Intent.ACTION_MAIN.equals(action)) { -			// we got called to be the starting point, most likely a shortcut -			String shortcutUUID = intent.getStringExtra( EXTRA_KEY); -			String shortcutName = intent.getStringExtra( EXTRA_NAME); -			mhideLog = intent.getBooleanExtra(EXTRA_HIDELOG, false); - -			VpnProfile profileToConnect = ProfileManager.get(shortcutUUID); -			if(shortcutName != null && profileToConnect ==null) -				profileToConnect = ProfileManager.getInstance(this).getProfileByName(shortcutName); - -			if(profileToConnect ==null) { -				OpenVPN.logError(R.string.shortcut_profile_notfound); -				// show Log window to display error -				showLogWindow(); -				finish(); -				return; -			} - -			mSelectedProfile = profileToConnect; -			launchVPN(); - -		} else if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) { -			createListView(); -		} -	} - -	private void createListView() { -		ListView lv = getListView(); -		//lv.setTextFilterEnabled(true); - -		Collection<VpnProfile> vpnlist = mPM.getProfiles(); - -		Vector<String> vpnnames=new Vector<String>(); -		for (VpnProfile vpnProfile : vpnlist) { -			vpnnames.add(vpnProfile.mName); -		} - - - -		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,vpnnames); -		lv.setAdapter(adapter); - -		lv.setOnItemClickListener(this); -	} - -	/** -	 * This function creates a shortcut and returns it to the caller.  There are actually two  -	 * intents that you will send back. -	 *  -	 * The first intent serves as a container for the shortcut and is returned to the launcher by  -	 * setResult().  This intent must contain three fields: -	 *  -	 * <ul> -	 * <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li> -	 * <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with -	 * the shortcut.</li> -	 * <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a -	 * bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as -	 * a drawable resource.</li> -	 * </ul> -	 *  -	 * If you use a simple drawable resource, note that you must wrapper it using -	 * {@link android.content.Intent.ShortcutIconResource}, as shown below.  This is required so -	 * that the launcher can access resources that are stored in your application's .apk file.  If  -	 * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras  -	 * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}. -	 *  -	 * The shortcut intent can be any intent that you wish the launcher to send, when the user  -	 * clicks on the shortcut.  Typically this will be {@link android.content.Intent#ACTION_VIEW}  -	 * with an appropriate Uri for your content, but any Intent will work here as long as it  -	 * triggers the desired action within your Activity. -	 * @param profile  -	 */ -	private void setupShortcut(VpnProfile profile) { -		// First, set up the shortcut intent.  For this example, we simply create an intent that -		// will bring us directly back to this activity.  A more typical implementation would use a  -		// data Uri in order to display a more specific result, or a custom action in order to  -		// launch a specific operation. - -		Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); -		shortcutIntent.setClass(this, LaunchVPN.class); -		shortcutIntent.putExtra(EXTRA_KEY,profile.getUUID().toString()); - -		// Then, set up the container intent (the response to the caller) - -		Intent intent = new Intent(); -		intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); -		intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, profile.getName()); -		Parcelable iconResource = Intent.ShortcutIconResource.fromContext( -				this,  R.drawable.icon); -		intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); - -		// Now, return the result to the launcher - -		setResult(RESULT_OK, intent); -	} - - -	@Override -	public void onItemClick(AdapterView<?> parent, View view, int position, -			long id) { -		String profilename = ((TextView) view).getText().toString(); - -		VpnProfile profile = mPM.getProfileByName(profilename); - -		// if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {	 -		setupShortcut(profile); -		finish(); -		return; -		//    } - -	} - -	 - -	private void askForPW(final int type) { - -		final EditText entry = new EditText(this); -		entry.setSingleLine(); -		entry.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); -		entry.setTransformationMethod(new PasswordTransformationMethod()); - -		AlertDialog.Builder dialog = new AlertDialog.Builder(this); -		dialog.setTitle("Need " + getString(type)); -		dialog.setMessage("Enter the password for profile " + mSelectedProfile.mName); -		dialog.setView(entry); - -		dialog.setPositiveButton(android.R.string.ok, -				new DialogInterface.OnClickListener() { -			@Override -			public void onClick(DialogInterface dialog, int which) { -				String pw = entry.getText().toString(); -				if(type == R.string.password) { -					mSelectedProfile.mTransientPW = pw; -				} else { -					mSelectedProfile.mTransientPCKS12PW = pw; -				} -				onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null); - -			} - -		}); -		dialog.setNegativeButton(android.R.string.cancel, -				new DialogInterface.OnClickListener() { -			@Override -			public void onClick(DialogInterface dialog, int which) { -				finish(); -			} -		}); - -		dialog.create().show(); - -	} -	@Override -	protected void onActivityResult(int requestCode, int resultCode, Intent data) { -		super.onActivityResult(requestCode, resultCode, data); - -		if(requestCode==START_VPN_PROFILE) { -			if(resultCode == Activity.RESULT_OK) { -				int needpw = mSelectedProfile.needUserPWInput(); -				if(needpw !=0) { -					askForPW(needpw); -				} else { -					SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);         -					boolean showlogwindow = prefs.getBoolean("showlogwindow", false); -					 -					if(!mhideLog && showlogwindow) -						showLogWindow(); -					new startOpenVpnThread().start(); -				} -			} else if (resultCode == Activity.RESULT_CANCELED) { -				// User does not want us to start, so we just vanish (well, now we tell our receiver, then vanish) -				Bundle resultData = new Bundle(); -				// For now, nothing else is calling, so this "request" string is good enough -				resultData.putString(EIP.REQUEST_TAG, EIP.ACTION_START_EIP); -				mReceiver.send(RESULT_CANCELED, resultData); -				finish(); -			} -		} -	} -	void showLogWindow() { - -		Intent startLW = new Intent(getBaseContext(),LogWindow.class); -		startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); -		startActivity(startLW); - -	} - -	void showConfigErrorDialog(int vpnok) { -		AlertDialog.Builder d = new AlertDialog.Builder(this); -		d.setTitle(R.string.config_error_found); -		d.setMessage(vpnok); -		d.setPositiveButton(android.R.string.ok, new OnClickListener() { - -			@Override -			public void onClick(DialogInterface dialog, int which) { -				finish(); - -			} -		}); -		d.show(); -	} - -	void launchVPN () { -		int vpnok = mSelectedProfile.checkProfile(this); -		if(vpnok!= R.string.no_error_found) { -			showConfigErrorDialog(vpnok); -			return; -		} - -		Intent intent = VpnService.prepare(this); -		// Check if we want to fix /dev/tun -		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);         -		boolean usecm9fix = prefs.getBoolean("useCM9Fix", false); -		boolean loadTunModule = prefs.getBoolean("loadTunModule", false); - -		if(loadTunModule) -			execeuteSUcmd("insmod /system/lib/modules/tun.ko"); - -		if(usecm9fix && !mCmfixed ) { -			execeuteSUcmd("chown system /dev/tun"); -		} - - -		if (intent != null) { -			// Start the query -			try { -				startActivityForResult(intent, START_VPN_PROFILE); -			} catch (ActivityNotFoundException ane) { -				// Shame on you Sony! At least one user reported that  -				// an official Sony Xperia Arc S image triggers this exception -				OpenVPN.logError(R.string.no_vpn_support_image); -				showLogWindow(); -			} -		} else { -			onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null); -		} - -	} - -	private void execeuteSUcmd(String command) { -		ProcessBuilder pb = new ProcessBuilder(new String[] {"su","-c",command}); -		try { -			Process p = pb.start(); -			int ret = p.waitFor(); -			if(ret ==0) -				mCmfixed=true; -		} catch (InterruptedException e) { -			e.printStackTrace(); -		} catch (IOException e) { -			e.printStackTrace(); -		} -	} - -	private class startOpenVpnThread extends Thread { - -		@Override -		public void run() { -			VPNLaunchHelper.startOpenVpn(mSelectedProfile, getBaseContext()); -			// Tell whom-it-may-concern that we started VPN -			Bundle resultData = new Bundle(); -			// For now, nothing else is calling, so this "request" string is good enough -			resultData.putString(EIP.REQUEST_TAG, EIP.ACTION_START_EIP); -			mReceiver.send(RESULT_OK, resultData); -			finish(); - -		} - -	} - - -} diff --git a/src/se/leap/openvpn/LogWindow.java b/src/se/leap/openvpn/LogWindow.java deleted file mode 100644 index b87c4999..00000000 --- a/src/se/leap/openvpn/LogWindow.java +++ /dev/null @@ -1,340 +0,0 @@ -package se.leap.openvpn; - -import java.util.Vector; - -import se.leap.bitmaskclient.R; - -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.app.ListActivity; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.database.DataSetObserver; -import android.os.Bundle; -import android.os.Handler; -import android.os.Handler.Callback; -import android.os.Message; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; -import se.leap.openvpn.OpenVPN.LogItem; -import se.leap.openvpn.OpenVPN.LogListener; -import se.leap.openvpn.OpenVPN.StateListener; - -public class LogWindow extends ListActivity implements StateListener  { -	private static final int START_VPN_CONFIG = 0; -	private String[] mBconfig=null; - - -	class LogWindowListAdapter implements ListAdapter, LogListener, Callback { - -		private static final int MESSAGE_NEWLOG = 0; - -		private static final int MESSAGE_CLEARLOG = 1; - -		private Vector<String> myEntries=new Vector<String>(); - -		private Handler mHandler; - -		private Vector<DataSetObserver> observers=new Vector<DataSetObserver>(); - - -		public LogWindowListAdapter() { -			initLogBuffer(); - -			if (mHandler == null) { -				mHandler = new Handler(this); -			} - -			OpenVPN.addLogListener(this); -		} - - - -		private void initLogBuffer() { -			myEntries.clear(); -			for (LogItem litem : OpenVPN.getlogbuffer()) { -				myEntries.add(litem.getString(getContext()));				 -			} -		} - -		String getLogStr() { -			String str = ""; -			for(String entry:myEntries) { -				str+=entry + '\n'; -			} -			return str; -		} - - -		private void shareLog() { -			Intent shareIntent = new Intent(Intent.ACTION_SEND); -			shareIntent.putExtra(Intent.EXTRA_TEXT, getLogStr()); -			shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.bitmask_openvpn_log_file)); -			shareIntent.setType("text/plain"); -			startActivity(Intent.createChooser(shareIntent, "Send Logfile")); -		} - -		@Override -		public void registerDataSetObserver(DataSetObserver observer) { -			observers.add(observer); - -		} - -		@Override -		public void unregisterDataSetObserver(DataSetObserver observer) { -			observers.remove(observer); -		} - -		@Override -		public int getCount() { -			return myEntries.size(); -		} - -		@Override -		public Object getItem(int position) { -			return myEntries.get(position); -		} - -		@Override -		public long getItemId(int position) { -			return position; -		} - -		@Override -		public boolean hasStableIds() { -			return true; -		} - -		@Override -		public View getView(int position, View convertView, ViewGroup parent) { -			TextView v; -			if(convertView==null) -				v = new TextView(getBaseContext()); -			else -				v = (TextView) convertView; -			v.setText(myEntries.get(position)); -			return v; -		} - -		@Override -		public int getItemViewType(int position) { -			return 0; -		} - -		@Override -		public int getViewTypeCount() { -			return 1; -		} - -		@Override -		public boolean isEmpty() { -			return myEntries.isEmpty(); - -		} - -		@Override -		public boolean areAllItemsEnabled() { -			return true; -		} - -		@Override -		public boolean isEnabled(int position) { -			return true; -		} - -		@Override -		public void newLog(LogItem logmessage) { -			Message msg = Message.obtain(); -			msg.what=MESSAGE_NEWLOG; -			Bundle mbundle=new Bundle(); -			mbundle.putString("logmessage", logmessage.getString(getBaseContext())); -			msg.setData(mbundle); -			mHandler.sendMessage(msg); -		} - -		@Override -		public boolean handleMessage(Message msg) { -			// We have been called -			if(msg.what==MESSAGE_NEWLOG) { - -				String logmessage = msg.getData().getString("logmessage"); -				myEntries.add(logmessage); - -				for (DataSetObserver observer : observers) { -					observer.onChanged(); -				} -			} else if (msg.what == MESSAGE_CLEARLOG) { -				initLogBuffer(); -				for (DataSetObserver observer : observers) { -					observer.onInvalidated(); -				} -			}  - -			return true; -		} - -		void clearLog() { -			// Actually is probably called from GUI Thread as result of the user  -			// pressing a button. But better safe than sorry -			OpenVPN.clearLog(); -			OpenVPN.logMessage(0,"","Log cleared."); -			mHandler.sendEmptyMessage(MESSAGE_CLEARLOG); -		} -	} - - - -	private LogWindowListAdapter ladapter; -	private TextView mSpeedView; - -	@Override -	public boolean onOptionsItemSelected(MenuItem item) { -		if(item.getItemId()==R.id.clearlog) { -			ladapter.clearLog(); -			return true; -		} else if(item.getItemId()==R.id.cancel){ -			Builder builder = new AlertDialog.Builder(this); -			builder.setTitle(R.string.title_cancel); -			builder.setMessage(R.string.cancel_connection_query); -			builder.setNegativeButton(android.R.string.no, null); -			builder.setPositiveButton(android.R.string.yes, new OnClickListener() { - -				@Override -				public void onClick(DialogInterface dialog, int which) { -					ProfileManager.setConntectedVpnProfileDisconnected(getApplicationContext()); -					OpenVpnManagementThread.stopOpenVPN();		 -				} -			}); - -			builder.show(); -			return true; -		} else if(item.getItemId()==R.id.info) { -			if(mBconfig==null) -				OpenVPN.triggerLogBuilderConfig(); - -		} else if(item.getItemId()==R.id.send) { -			ladapter.shareLog(); -		} - -		return super.onOptionsItemSelected(item); - -	} - -	protected Context getContext() { -		return this; -	} - -	@Override -	public boolean onCreateOptionsMenu(Menu menu) { -		MenuInflater inflater = getMenuInflater(); -		inflater.inflate(R.menu.logmenu, menu); -		return true; -	} - - -	@Override -	protected void onResume() { -		super.onResume(); -		OpenVPN.addStateListener(this); -	} - -	@Override -	protected void onActivityResult(int requestCode, int resultCode, Intent data) { -		if (requestCode == START_VPN_CONFIG && resultCode==RESULT_OK) { -			String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); - -			final VpnProfile profile = ProfileManager.get(configuredVPN); -			ProfileManager.getInstance(this).saveProfile(this, profile); -			// Name could be modified, reset List adapter - -			AlertDialog.Builder dialog = new AlertDialog.Builder(this); -			dialog.setTitle(R.string.configuration_changed); -			dialog.setMessage(R.string.restart_vpn_after_change); - - -			dialog.setPositiveButton(R.string.restart, -					new DialogInterface.OnClickListener() { -				@Override -				public void onClick(DialogInterface dialog, int which) { -					Intent intent = new Intent(getBaseContext(), LaunchVPN.class); -					intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUIDString()); -					intent.setAction(Intent.ACTION_MAIN); -					startActivity(intent); -				} - - -			}); -			dialog.setNegativeButton(R.string.ignore, null); -			dialog.create().show(); -		} -		super.onActivityResult(requestCode, resultCode, data); -	} - -	@Override -	protected void onStop() { -		super.onStop(); -		OpenVPN.removeStateListener(this); -	} - -	@Override -	public void onCreate(Bundle savedInstanceState) { -		super.onCreate(savedInstanceState); - -		setContentView(R.layout.logwindow); -		ListView lv = getListView(); - -		lv.setOnItemLongClickListener(new OnItemLongClickListener() { - -			@Override -			public boolean onItemLongClick(AdapterView<?> parent, View view, -					int position, long id) { -				ClipboardManager clipboard = (ClipboardManager) -						getSystemService(Context.CLIPBOARD_SERVICE); -				ClipData clip = ClipData.newPlainText("Log Entry",((TextView) view).getText()); -				clipboard.setPrimaryClip(clip); -				Toast.makeText(getBaseContext(), R.string.copied_entry, Toast.LENGTH_SHORT).show(); -				return true; -			} -		}); - -		ladapter = new LogWindowListAdapter(); -		lv.setAdapter(ladapter); - -		mSpeedView = (TextView) findViewById(R.id.speed); -	} - -	@Override -	public void updateState(final String status,final String logmessage, final int resid) { -		runOnUiThread(new Runnable() { - -			@Override -			public void run() { -				String prefix=getString(resid) + ":"; -				if (status.equals("BYTECOUNT") || status.equals("NOPROCESS") ) -					prefix=""; -				mSpeedView.setText(prefix + logmessage); -			} -		}); - -	} - -	@Override -	protected void onDestroy() { -		super.onDestroy(); -		OpenVPN.removeLogListener(ladapter); -	} - -} diff --git a/src/se/leap/openvpn/NetworkSateReceiver.java b/src/se/leap/openvpn/NetworkSateReceiver.java deleted file mode 100644 index 777402b4..00000000 --- a/src/se/leap/openvpn/NetworkSateReceiver.java +++ /dev/null @@ -1,86 +0,0 @@ -package se.leap.openvpn;
 -
 -import android.content.BroadcastReceiver;
 -import android.content.Context;
 -import android.content.Intent;
 -import android.content.SharedPreferences;
 -import android.net.ConnectivityManager;
 -import android.net.NetworkInfo;
 -import android.net.NetworkInfo.State;
 -import android.preference.PreferenceManager;
 -import se.leap.bitmaskclient.R;
 -
 -public class NetworkSateReceiver extends BroadcastReceiver {
 -	private int lastNetwork=-1;
 -	private OpenVpnManagementThread mManangement;
 -
 -	private String lastStateMsg=null;
 -	
 -	public NetworkSateReceiver(OpenVpnManagementThread managementThread) {
 -		super();
 -		mManangement = managementThread;
 -	}
 -
 -	@Override
 -	public void onReceive(Context context, Intent intent) {
 -		NetworkInfo networkInfo = getCurrentNetworkInfo(context);
 -		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);        
 -		boolean sendusr1 = prefs.getBoolean("netchangereconnect", true);
 -
 -		String netstatestring;
 -		if(networkInfo==null)
 -			netstatestring = "not connected";
 -		else  {
 -			String subtype = networkInfo.getSubtypeName();
 -			if(subtype==null) 
 -				subtype = "";
 -			String extrainfo = networkInfo.getExtraInfo();
 -			if(extrainfo==null)
 -				extrainfo="";
 -			
 -			/*
 -			if(networkInfo.getType()==android.net.ConnectivityManager.TYPE_WIFI) {
 -				WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);			
 -				WifiInfo wifiinfo = wifiMgr.getConnectionInfo();
 -				extrainfo+=wifiinfo.getBSSID();
 -				
 -				subtype += wifiinfo.getNetworkId();
 -			}*/
 -			
 -			
 -			
 -			netstatestring = String.format("%2$s %4$s to %1$s %3$s",networkInfo.getTypeName(),
 -					networkInfo.getDetailedState(),extrainfo,subtype );
 -		}
 -		
 -		
 -		
 -		if(networkInfo!=null && networkInfo.getState() == State.CONNECTED) {
 -				int newnet = networkInfo.getType();
 -			
 -				if(sendusr1 && lastNetwork!=newnet)
 -					mManangement.reconnect();
 -							
 -				lastNetwork = newnet;
 -		} else if (networkInfo==null) {
 -			// Not connected, stop openvpn, set last connected network to no network
 -			lastNetwork=-1;
 -			if(sendusr1)
 -				mManangement.signalusr1();
 -		}
 -		
 -		if(!netstatestring.equals(lastStateMsg))
 -			OpenVPN.logInfo(R.string.netstatus, netstatestring);
 -		lastStateMsg=netstatestring;
 -
 -	}
 -
 -	private NetworkInfo getCurrentNetworkInfo(Context context) {
 -		ConnectivityManager conn =  (ConnectivityManager)
 -				context.getSystemService(Context.CONNECTIVITY_SERVICE);
 -		
 -		NetworkInfo networkInfo = conn.getActiveNetworkInfo();
 -		return networkInfo;
 -	}
 -
 -}
 diff --git a/src/se/leap/openvpn/OpenVPN.java b/src/se/leap/openvpn/OpenVPN.java deleted file mode 100644 index 8acdc423..00000000 --- a/src/se/leap/openvpn/OpenVPN.java +++ /dev/null @@ -1,250 +0,0 @@ -package se.leap.openvpn; - -import java.util.LinkedList; -import java.util.Locale; -import java.util.Vector; - -import se.leap.bitmaskclient.R; - - -import android.content.Context; -import android.os.Build; -import android.util.Log; - -public class OpenVPN { - - -	public static LinkedList<LogItem> logbuffer; - -	private static Vector<LogListener> logListener; -	private static Vector<StateListener> stateListener; -	private static String[] mBconfig; - -	private static String mLaststatemsg; - -	private static String mLaststate; - -	private static int mLastStateresid=R.string.state_noprocess; -	public static String TAG="se.leap.openvpn.OpenVPN"; - -	static { -		logbuffer  = new LinkedList<LogItem>(); -		logListener = new Vector<OpenVPN.LogListener>(); -		stateListener = new Vector<OpenVPN.StateListener>(); -		logInformation(); -	} - -	public static class LogItem { -		public static final int ERROR = 1; -		public static final int INFO = 2; -		public static final int VERBOSE = 3; - -		private Object [] mArgs = null; -		private String mMessage = null; -		private int mRessourceId; -		// Default log priority -		int mLevel = INFO; - -		public LogItem(int ressourceId, Object[] args) { -			mRessourceId = ressourceId; -			mArgs = args; -		} - - -		public LogItem(int loglevel,int ressourceId, Object[] args) { -			mRessourceId = ressourceId; -			mArgs = args; -			mLevel = loglevel; -		} - - -		public LogItem(String message) { -			 -			mMessage = message; -		} - -		public LogItem(int loglevel, String msg) { -			mLevel = loglevel; -			mMessage = msg; -		} - - -		public LogItem(int loglevel, int ressourceId) { -			mRessourceId =ressourceId; -			mLevel = loglevel; -		} - - -		public String getString(Context c) { -			if(mMessage !=null) { -				return mMessage; -			} else { -				if(c!=null) { -					if(mArgs == null) -						return c.getString(mRessourceId); -					else -						return c.getString(mRessourceId,mArgs); -				} else { -					String str = String.format(Locale.ENGLISH,"Log (no context) resid %d", mRessourceId); -					if(mArgs !=null) -						for(Object o:mArgs) -							str += "|" +  o.toString(); -					return str; -				} -			} -		} -	} - -	private static final int MAXLOGENTRIES = 500; - - -	public static final String MANAGMENT_PREFIX = "M:"; - - - - - - -	public interface LogListener { -		void newLog(LogItem logItem); -	} - -	public interface StateListener { -		void updateState(String state, String logmessage, int localizedResId); -	} - -	synchronized static void logMessage(int level,String prefix, String message) -	{ -		newlogItem(new LogItem(prefix +  message)); -		Log.d("OpenVPN log item", message); -	} - -	synchronized static void clearLog() { -		logbuffer.clear(); -		logInformation(); -	} - -	private static void logInformation() { - -		logInfo(R.string.mobile_info,Build.MODEL, Build.BOARD,Build.BRAND,Build.VERSION.SDK_INT); -	} - -	public synchronized static void addLogListener(LogListener ll){ -		logListener.add(ll); -	} - -	public synchronized static void removeLogListener(LogListener ll) { -		logListener.remove(ll); -	} - - -	public synchronized static void addStateListener(StateListener sl){ -		stateListener.add(sl); -		if(mLaststate!=null) -			sl.updateState(mLaststate, mLaststatemsg, mLastStateresid); -	}	 - -	private static int getLocalizedState(String state){ -		if (state.equals("CONNECTING"))  -			return R.string.state_connecting; -		else if (state.equals("WAIT")) -			return R.string.state_wait; -		else if (state.equals("AUTH")) -			return R.string.state_auth; -		else if (state.equals("GET_CONFIG")) -			return R.string.state_get_config; -		else if (state.equals("ASSIGN_IP")) -			return R.string.state_assign_ip; -		else if (state.equals("ADD_ROUTES")) -			return R.string.state_add_routes; -		else if (state.equals("CONNECTED")) -			return R.string.state_connected; -		else if (state.equals("RECONNECTING")) -			return R.string.state_reconnecting; -		else if (state.equals("EXITING")) -			return R.string.state_exiting; -		else if (state.equals("RESOLVE")) -			return R.string.state_resolve; -		else if (state.equals("TCP_CONNECT")) -			return R.string.state_tcp_connect; -		else if (state.equals("FATAL")) -			return R.string.eip_state_not_connected; -		else -			return R.string.unknown_state; - -	} - -	public synchronized static void removeStateListener(StateListener sl) { -		stateListener.remove(sl); -	} - - -	synchronized public static LogItem[] getlogbuffer() { - -		// The stoned way of java to return an array from a vector -		// brought to you by eclipse auto complete -		return (LogItem[]) logbuffer.toArray(new LogItem[logbuffer.size()]); - -	} -	public static void logBuilderConfig(String[] bconfig) { -		mBconfig = bconfig; -	} -	public static void triggerLogBuilderConfig() { -		if(mBconfig==null) { -			logMessage(0, "", "No active interface"); -		} else { -			for (String item : mBconfig) { -				logMessage(0, "", item); -			}	 -		} - -	} - -	public static void updateStateString (String state, String msg) {	 -		int rid = getLocalizedState(state); -		updateStateString(state, msg,rid); -	} - -	public synchronized static void updateStateString(String state, String msg, int resid) { -		if (! "BYTECOUNT".equals(state)) { -			mLaststate= state; -			mLaststatemsg = msg; -			mLastStateresid = resid; - -			for (StateListener sl : stateListener) { -				sl.updateState(state,msg,resid); -			} -		} -	} - -	public static void logInfo(String message) { -		newlogItem(new LogItem(LogItem.INFO, message)); -	} - -	public static void logInfo(int ressourceId, Object... args) { -		newlogItem(new LogItem(LogItem.INFO, ressourceId, args)); -	} - -	private static void newlogItem(LogItem logItem) { -		logbuffer.addLast(logItem); -		if(logbuffer.size()>MAXLOGENTRIES) -			logbuffer.removeFirst(); - -		for (LogListener ll : logListener) { -			ll.newLog(logItem); -		} -	} - -	public static void logError(String msg) { -		newlogItem(new LogItem(LogItem.ERROR, msg)); - -	} - -	public static void logError(int ressourceId) { -		newlogItem(new LogItem(LogItem.ERROR, ressourceId)); -	} -	public static void logError(int ressourceId, Object... args) { -		newlogItem(new LogItem(LogItem.ERROR, ressourceId,args)); -	} - -} diff --git a/src/se/leap/openvpn/OpenVPNThread.java b/src/se/leap/openvpn/OpenVPNThread.java deleted file mode 100644 index ffd21732..00000000 --- a/src/se/leap/openvpn/OpenVPNThread.java +++ /dev/null @@ -1,130 +0,0 @@ -package se.leap.openvpn;
 -
 -import java.io.BufferedReader;
 -import java.io.BufferedWriter;
 -import java.io.FileWriter;
 -import java.io.IOException;
 -import java.io.InputStream;
 -import java.io.InputStreamReader;
 -import java.util.LinkedList;
 -
 -import se.leap.bitmaskclient.R;
 -
 -import android.util.Log;
 -import se.leap.openvpn.OpenVPN.LogItem;
 -
 -public class OpenVPNThread implements Runnable {
 -	private static final String DUMP_PATH_STRING = "Dump path: ";
 -	private static final String TAG = "OpenVPN";
 -	private String[] mArgv;
 -	private Process mProcess;
 -	private String mNativeDir;
 -	private OpenVpnService mService;
 -	private String mDumpPath;
 -
 -	public OpenVPNThread(OpenVpnService service,String[] argv, String nativelibdir)
 -	{
 -		mArgv = argv;
 -		mNativeDir = nativelibdir;
 -		mService = service;
 -	}
 -	
 -	public void stopProcess() {
 -		mProcess.destroy();
 -	}
 -
 -	
 -	
 -	@Override
 -	public void run() {
 -		try {
 -			Log.i(TAG, "Starting openvpn");			
 -			startOpenVPNThreadArgs(mArgv);
 -			Log.i(TAG, "Giving up");
 -		} catch (Exception e) {
 -			e.printStackTrace();
 -			Log.e(TAG, "OpenVPNThread Got " + e.toString());
 -		} finally {
 -			int exitvalue = 0;
 -			try {
 -				 exitvalue = mProcess.waitFor();
 -			} catch ( IllegalThreadStateException ite) {
 -				OpenVPN.logError("Illegal Thread state: " + ite.getLocalizedMessage());
 -			} catch (InterruptedException ie) {
 -				OpenVPN.logError("InterruptedException: " + ie.getLocalizedMessage());
 -			}
 -			if( exitvalue != 0)
 -				OpenVPN.logError("Process exited with exit value " + exitvalue);
 -			
 -//			OpenVPN.updateStateString("NOPROCESS","No process running.", R.string.state_noprocess); fixes bug #4565
 -			if(mDumpPath!=null) {
 -				try {
 -					BufferedWriter logout = new BufferedWriter(new FileWriter(mDumpPath + ".log"));
 -					for(LogItem li :OpenVPN.getlogbuffer()){
 -						logout.write(li.getString(null) + "\n");
 -					}
 -					logout.close();
 -					OpenVPN.logError(R.string.minidump_generated);
 -				} catch (IOException e) {
 -					OpenVPN.logError("Writing minidump log: " +e.getLocalizedMessage());
 -				}
 -			}
 -
 -			mService.processDied();
 -			Log.i(TAG, "Exiting");
 -		}
 -	}
 -	
 -	private void startOpenVPNThreadArgs(String[] argv) {
 -		LinkedList<String> argvlist = new LinkedList<String>();
 -		
 -		for(String arg:argv)
 -			argvlist.add(arg);
 -	
 -		ProcessBuilder pb = new ProcessBuilder(argvlist);
 -		// Hack O rama
 -		
 -		// Hack until I find a good way to get the real library path
 -		String applibpath = argv[0].replace("/cache/" + VpnProfile.MINIVPN , "/lib");
 -		
 -		String lbpath = pb.environment().get("LD_LIBRARY_PATH");
 -		if(lbpath==null) 
 -			lbpath = applibpath;
 -		else
 -			lbpath = lbpath + ":" + applibpath;
 -		
 -		if (!applibpath.equals(mNativeDir)) {
 -			lbpath = lbpath + ":" + mNativeDir;
 -		}
 -		
 -		pb.environment().put("LD_LIBRARY_PATH", lbpath);
 -		pb.redirectErrorStream(true);
 -		try {
 -			mProcess = pb.start();
 -			// Close the output, since we don't need it
 -			mProcess.getOutputStream().close();
 -			InputStream in = mProcess.getInputStream();
 -			BufferedReader br = new BufferedReader(new InputStreamReader(in));
 -				
 -			while(true) {
 -				String logline = br.readLine();
 -				if(logline==null) 
 -					return;
 -
 -				if (logline.startsWith(DUMP_PATH_STRING))
 -					mDumpPath = logline.substring(DUMP_PATH_STRING.length());
 -					
 -
 -				OpenVPN.logMessage(0, "P:", logline);
 -			}
 -			
 -		
 -		} catch (IOException e) {
 -			OpenVPN.logMessage(0, "", "Error reading from output of OpenVPN process"+ e.getLocalizedMessage());
 -			e.printStackTrace();
 -			stopProcess();
 -		}
 -		
 -		
 -	}
 -}
 diff --git a/src/se/leap/openvpn/OpenVpnManagementThread.java b/src/se/leap/openvpn/OpenVpnManagementThread.java deleted file mode 100644 index 27a3db65..00000000 --- a/src/se/leap/openvpn/OpenVpnManagementThread.java +++ /dev/null @@ -1,592 +0,0 @@ -package se.leap.openvpn;
 -
 -import java.io.FileDescriptor;
 -import java.io.IOException;
 -import java.io.InputStream;
 -import java.lang.reflect.InvocationTargetException;
 -import java.lang.reflect.Method;
 -import java.net.InetSocketAddress;
 -import java.net.SocketAddress;
 -import java.security.InvalidKeyException;
 -import java.security.NoSuchAlgorithmException;
 -import java.security.PrivateKey;
 -import java.util.LinkedList;
 -import java.util.Vector;
 -
 -import javax.crypto.BadPaddingException;
 -import javax.crypto.Cipher;
 -import javax.crypto.IllegalBlockSizeException;
 -import javax.crypto.NoSuchPaddingException;
 -
 -import se.leap.bitmaskclient.R;
 -import android.content.SharedPreferences;
 -import android.net.LocalServerSocket;
 -import android.net.LocalSocket;
 -import android.os.Build;
 -import android.os.ParcelFileDescriptor;
 -import android.preference.PreferenceManager;
 -import android.util.Base64;
 -import android.util.Log;
 -
 -public class OpenVpnManagementThread implements Runnable {
 -
 -	private static final String TAG = "openvpn";
 -	private LocalSocket mSocket;
 -	private VpnProfile mProfile;
 -	private OpenVpnService mOpenVPNService;
 -	private LinkedList<FileDescriptor> mFDList=new LinkedList<FileDescriptor>();
 -	private int mBytecountinterval=2;
 -	private long mLastIn=0; 
 -	private long mLastOut=0;
 -	private LocalServerSocket mServerSocket;
 -	private boolean mReleaseHold=true;
 -	private boolean mWaitingForRelease=false;
 -	private long mLastHoldRelease=0; 
 -
 -	private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
 -
 -	static private native void jniclose(int fdint);
 -	static private native byte[] rsasign(byte[] input,int pkey) throws InvalidKeyException;
 -
 -	public OpenVpnManagementThread(VpnProfile profile, LocalServerSocket mgmtsocket, OpenVpnService openVpnService) {
 -		mProfile = profile;
 -		mServerSocket = mgmtsocket;
 -		mOpenVPNService = openVpnService;
 -		
 -
 -		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(openVpnService);
 -		boolean managemeNetworkState = prefs.getBoolean("netchangereconnect", true);
 -		if(managemeNetworkState)
 -			mReleaseHold=false;
 -
 -	}
 -
 -	static {
 -		System.loadLibrary("opvpnutil");
 -	}
 -
 -	public void managmentCommand(String cmd) {
 -		if(mSocket!=null) {
 -			try {
 -				mSocket.getOutputStream().write(cmd.getBytes());
 -				mSocket.getOutputStream().flush();
 -			} catch (IOException e) {
 -				// Ignore socket stack traces
 -			}
 -		}
 -	}
 -
 -
 -	@Override
 -	public void run() {
 -		Log.i(TAG, "Managment Socket Thread started");
 -		byte [] buffer  =new byte[2048];
 -		//	mSocket.setSoTimeout(5); // Setting a timeout cannot be that bad
 -
 -		String pendingInput="";
 -		active.add(this);
 -
 -		try {
 -			// Wait for a client to connect
 -			mSocket= mServerSocket.accept();
 -			InputStream instream = mSocket.getInputStream();
 -
 -			while(true) {
 -				int numbytesread = instream.read(buffer);
 -				if(numbytesread==-1)
 -					return;
 -
 -				FileDescriptor[] fds = null;
 -				try {
 -					fds = mSocket.getAncillaryFileDescriptors();
 -				} catch (IOException e) {
 -					OpenVPN.logMessage(0, "", "Error reading fds from socket" + e.getLocalizedMessage());
 -					e.printStackTrace();
 -				}
 -				if(fds!=null){
 -
 -					for (FileDescriptor fd : fds) {
 -
 -						mFDList.add(fd);
 -					}
 -				}
 -
 -				String input = new String(buffer,0,numbytesread,"UTF-8");
 -
 -				pendingInput += input;
 -
 -				pendingInput=processInput(pendingInput);
 -
 -
 -
 -			}
 -		} catch (IOException e) {
 -			e.printStackTrace();
 -		}
 -		active.remove(this);
 -	}
 -
 -	//! Hack O Rama 2000!
 -	private void protectFileDescriptor(FileDescriptor fd) {
 -		Exception exp=null;
 -		try {
 -			Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
 -			int fdint = (Integer) getInt.invoke(fd);
 -
 -			// You can even get more evil by parsing toString() and extract the int from that :)
 -
 -			mOpenVPNService.protect(fdint);
 -
 -			//ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
 -			//pfd.close();
 -			jniclose(fdint);
 -			return;
 -		} catch (NoSuchMethodException e) {
 -			exp =e;
 -		} catch (IllegalArgumentException e) {
 -			exp =e;
 -		} catch (IllegalAccessException e) {
 -			exp =e;
 -		} catch (InvocationTargetException e) {
 -			exp =e;
 -		} catch (NullPointerException e) {
 -			exp =e;
 -		}
 -		if(exp!=null) {
 -			exp.printStackTrace();
 -			Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd);
 -			OpenVPN.logMessage(0, "",  "Failed to retrieve fd from socket: " + exp.getLocalizedMessage());
 -		}
 -	}
 -
 -	private String processInput(String pendingInput) {
 -
 -
 -		while(pendingInput.contains("\n")) {
 -			String[] tokens = pendingInput.split("\\r?\\n", 2);
 -			processCommand(tokens[0]);
 -			if(tokens.length == 1)
 -				// No second part, newline was at the end
 -				pendingInput="";
 -			else
 -				pendingInput=tokens[1];
 -		}
 -		return pendingInput;
 -	}
 -
 -
 -	private void processCommand(String command) {
 -		Log.d(TAG, "processCommand: " + command);
 -
 -		if (command.startsWith(">") && command.contains(":")) {
 -			String[] parts = command.split(":",2);
 -			String cmd = parts[0].substring(1);
 -			String argument = parts[1];
 -			if(cmd.equals("INFO")) {
 -				// Ignore greeting from mgmt
 -				//logStatusMessage(command);
 -			}else if (cmd.equals("PASSWORD")) {
 -				processPWCommand(argument);
 -			} else if (cmd.equals("HOLD")) {
 -				handleHold();
 -			} else if (cmd.equals("NEED-OK")) {
 -				processNeedCommand(argument);
 -			} else if (cmd.equals("BYTECOUNT")){
 -				processByteCount(argument);
 -			} else if (cmd.equals("STATE")) {
 -				processState(argument);
 -			} else if (cmd.equals("FATAL")){
 -				processState(","+cmd+","); 	//handles FATAL as state
 -			} else if (cmd.equals("PROXY")) {
 -				processProxyCMD(argument);
 -			} else if (cmd.equals("LOG")) {
 -				String[] args = argument.split(",",3);
 -				// 0 unix time stamp
 -				// 1 log level N,I,E etc.
 -				// 2 log message
 -				OpenVPN.logMessage(0, "",  args[2]);
 -			} else if (cmd.equals("RSA_SIGN")) {
 -				processSignCommand(argument);
 -			} else {
 -				OpenVPN.logMessage(0, "MGMT:", "Got unrecognized command" + command);
 -				Log.i(TAG, "Got unrecognized command" + command);
 -			}
 -		} else if (command.startsWith("SUCCESS:")) { //Fixes bug LEAP #4565
 -				if (command.equals("SUCCESS: signal SIGINT thrown")){
 -					Log.d(TAG, "SUCCESS: signal SIGINT thrown");
 -					processState(",EXITING,SIGINT,,");
 -				}
 -		} else {
 -			Log.i(TAG, "Got unrecognized line from managment" + command);
 -			OpenVPN.logMessage(0, "MGMT:", "Got unrecognized line from management:" + command);
 -		}
 -	}
 -	private void handleHold() {
 -		if(mReleaseHold) {
 -			releaseHoldCmd();
 -		} else { 
 -			mWaitingForRelease=true;
 -			OpenVPN.updateStateString("NONETWORK", "",R.string.state_nonetwork);
 -		}
 -	}
 -	private void releaseHoldCmd() {
 -		if ((System.currentTimeMillis()- mLastHoldRelease) < 5000) {
 -			try {
 -				Thread.sleep(3000);
 -			} catch (InterruptedException e) {}
 -			
 -		}
 -		mWaitingForRelease=false;
 -		mLastHoldRelease  = System.currentTimeMillis();
 -		managmentCommand("hold release\n");
 -		managmentCommand("bytecount " + mBytecountinterval + "\n");
 -		managmentCommand("state on\n");
 -	}
 -	
 -	public void releaseHold() {
 -		mReleaseHold=true;
 -		if(mWaitingForRelease)
 -			releaseHoldCmd();
 -			
 -	}
 -
 -	private void processProxyCMD(String argument) {
 -		String[] args = argument.split(",",3);
 -		SocketAddress proxyaddr = ProxyDetection.detectProxy(mProfile);
 -
 -		
 -		if(args.length >= 2) {
 -			String proto = args[1];
 -			if(proto.equals("UDP")) {
 -				proxyaddr=null;
 -			}
 -		}
 -
 -		if(proxyaddr instanceof InetSocketAddress ){
 -			InetSocketAddress isa = (InetSocketAddress) proxyaddr;
 -			
 -			OpenVPN.logInfo(R.string.using_proxy, isa.getHostName(),isa.getPort());
 -			
 -			String proxycmd = String.format("proxy HTTP %s %d\n", isa.getHostName(),isa.getPort());
 -			managmentCommand(proxycmd);
 -		} else {
 -			managmentCommand("proxy NONE\n");
 -		}
 -
 -	}
 -	private void processState(String argument) {
 -		String[] args = argument.split(",",3);
 -		String currentstate = args[1];
 -		if(args[2].equals(",,")){
 -			OpenVPN.updateStateString(currentstate,"");
 -		}
 -		else if (args[2].endsWith(",,")){ //fixes LEAP Bug #4546
 -			args[2] = (String) args[2].subSequence(0, args[2].length()-2);
 -			Log.d(TAG, "processState() STATE: "+ currentstate + "   msg: " + args[2]);
 -			OpenVPN.updateStateString(currentstate,args[2]);
 -		}
 -		else{
 -			OpenVPN.updateStateString(currentstate,args[2]);
 -		}
 -	}
 -
 -	private static int repeated_byte_counts = 0;
 -	private void processByteCount(String argument) {
 -		//   >BYTECOUNT:{BYTES_IN},{BYTES_OUT}
 -		int comma = argument.indexOf(',');
 -		long in = Long.parseLong(argument.substring(0, comma));
 -		long out = Long.parseLong(argument.substring(comma+1));
 -
 -		long diffin = in - mLastIn; 
 -		long diffout = out - mLastOut;
 -		if(diffin == 0 && diffout == 0)
 -			repeated_byte_counts++;
 -		if(repeated_byte_counts > 3)
 -			Log.d("OpenVPN log", "Repeated byte count = " + repeated_byte_counts);
 -		mLastIn=in;
 -		mLastOut=out;
 -
 -		String netstat = String.format("In: %8s, %8s/s  Out %8s, %8s/s",
 -				humanReadableByteCount(in, false),
 -				humanReadableByteCount(diffin, false),
 -				humanReadableByteCount(out, false),
 -				humanReadableByteCount(diffout, false));
 -		OpenVPN.updateStateString("BYTECOUNT",netstat);
 -
 -
 -	}
 -
 -	// From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
 -	public static String humanReadableByteCount(long bytes, boolean si) {
 -		int unit = si ? 1000 : 1024;
 -		if (bytes < unit) return bytes + " B";
 -		int exp = (int) (Math.log(bytes) / Math.log(unit));
 -		String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
 -		return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
 -	}
 -
 -	private void processNeedCommand(String argument) {
 -		int p1 =argument.indexOf('\'');
 -		int p2 = argument.indexOf('\'',p1+1);
 -
 -		String needed = argument.substring(p1+1, p2);
 -		String extra = argument.split(":",2)[1];
 -
 -		String status = "ok";
 -
 -
 -		if (needed.equals("PROTECTFD")) {
 -			FileDescriptor fdtoprotect = mFDList.pollFirst();
 -			protectFileDescriptor(fdtoprotect);
 -		} else if (needed.equals("DNSSERVER")) {
 -			mOpenVPNService.addDNS(extra);
 -		}else if (needed.equals("DNSDOMAIN")){
 -			mOpenVPNService.setDomain(extra);
 -		} else if (needed.equals("ROUTE")) {
 -			String[] routeparts = extra.split(" ");
 -			mOpenVPNService.addRoute(routeparts[0], routeparts[1]);
 -		} else if (needed.equals("ROUTE6")) {
 -			mOpenVPNService.addRoutev6(extra);
 -		} else if (needed.equals("IFCONFIG")) {
 -			String[] ifconfigparts = extra.split(" ");
 -			int mtu = Integer.parseInt(ifconfigparts[2]);
 -			mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1],mtu,ifconfigparts[3]);
 -		} else if (needed.equals("IFCONFIG6")) {
 -			mOpenVPNService.setLocalIPv6(extra);
 -
 -		} else if (needed.equals("OPENTUN")) {
 -			if(sendTunFD(needed,extra))
 -				return;
 -			else
 -				status="cancel";
 -			// This not nice or anything but setFileDescriptors accepts only FilDescriptor class :(
 -
 -		} else {
 -			Log.e(TAG,"Unkown needok command " + argument);
 -			return;
 -		}
 -
 -		String cmd = String.format("needok '%s' %s\n", needed, status);
 -		managmentCommand(cmd);
 -	}
 -
 -	private boolean sendTunFD (String needed, String extra) {
 -		Exception exp = null;
 -		if(!extra.equals("tun")) {
 -			// We only support tun
 -			String errmsg = String.format("Devicetype %s requested, but only tun is possible with the Android API, sorry!",extra);
 -			OpenVPN.logMessage(0, "", errmsg );
 -
 -			return false;
 -		}
 -		ParcelFileDescriptor pfd = mOpenVPNService.openTun(); 
 -		if(pfd==null)
 -			return false;
 -
 -		Method setInt;
 -		int fdint = pfd.getFd();
 -		try {
 -			setInt = FileDescriptor.class.getDeclaredMethod("setInt$",int.class);
 -			FileDescriptor fdtosend = new FileDescriptor();
 -
 -			setInt.invoke(fdtosend,fdint);
 -
 -			FileDescriptor[] fds = {fdtosend};
 -			mSocket.setFileDescriptorsForSend(fds);
 -
 -			Log.d("Openvpn", "Sending FD tosocket: " + fdtosend + " " + fdint + "  " + pfd);
 -			// Trigger a send so we can close the fd on our side of the channel
 -			// The API documentation fails to mention that it will not reset the file descriptor to
 -			// be send and will happily send the file descriptor on every write ...
 -			String cmd = String.format("needok '%s' %s\n", needed, "ok");
 -			managmentCommand(cmd);
 -
 -			// Set the FileDescriptor to null to stop this mad behavior 
 -			mSocket.setFileDescriptorsForSend(null);
 -
 -			pfd.close();			
 -
 -			return true;
 -		} catch (NoSuchMethodException e) {
 -			exp =e;
 -		} catch (IllegalArgumentException e) {
 -			exp =e;
 -		} catch (IllegalAccessException e) {
 -			exp =e;
 -		} catch (InvocationTargetException e) {
 -			exp =e;
 -		} catch (IOException e) {
 -			exp =e;
 -		}
 -		if(exp!=null) {
 -			OpenVPN.logMessage(0,"", "Could not send fd over socket:" + exp.getLocalizedMessage());
 -			exp.printStackTrace();
 -		}
 -		return false;
 -	}
 -
 -	private void processPWCommand(String argument) {
 -		//argument has the form 	Need 'Private Key' password
 -		// or  ">PASSWORD:Verification Failed: '%s' ['%s']"
 -		String needed;
 -		
 -		
 -		
 -		try{
 -
 -			int p1 = argument.indexOf('\'');
 -			int p2 = argument.indexOf('\'',p1+1);
 -			needed = argument.substring(p1+1, p2);
 -			if (argument.startsWith("Verification Failed")) {
 -				proccessPWFailed(needed, argument.substring(p2+1));
 -				return;
 -			}
 -		} catch (StringIndexOutOfBoundsException sioob) {
 -			OpenVPN.logMessage(0, "", "Could not parse management Password command: "  + argument);
 -			return;
 -		}
 -
 -		String pw=null;
 -
 -		if(needed.equals("Private Key")) {
 -			pw = mProfile.getPasswordPrivateKey();
 -		} else if (needed.equals("Auth")) {
 -			String usercmd = String.format("username '%s' %s\n", 
 -					needed, VpnProfile.openVpnEscape(mProfile.mUsername));
 -			managmentCommand(usercmd);
 -			pw = mProfile.getPasswordAuth();
 -		} 
 -		if(pw!=null) {
 -			String cmd = String.format("password '%s' %s\n", needed, VpnProfile.openVpnEscape(pw));
 -			managmentCommand(cmd);
 -		} else {
 -			OpenVPN.logMessage(0, OpenVPN.MANAGMENT_PREFIX, String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed));
 -		}
 -
 -	}
 -
 -
 -
 -
 -	private void proccessPWFailed(String needed, String args) {
 -		OpenVPN.updateStateString("AUTH_FAILED", needed + args,R.string.state_auth_failed);
 -	}
 -	private void logStatusMessage(String command) {
 -		OpenVPN.logMessage(0,"MGMT:", command);
 -	}
 -
 -
 -	public static boolean stopOpenVPN() {
 -		boolean sendCMD=false;
 -		for (OpenVpnManagementThread mt: active){
 -			mt.managmentCommand("signal SIGINT\n");
 -			sendCMD=true;
 -			try {
 -				if(mt.mSocket !=null)
 -					mt.mSocket.close();
 -			} catch (IOException e) {
 -				// Ignore close error on already closed socket
 -			}
 -		}
 -		return sendCMD;		
 -	}
 -
 -	public void signalusr1() {
 -		mReleaseHold=false;
 -		if(!mWaitingForRelease)
 -			managmentCommand("signal SIGUSR1\n");
 -	}
 -
 -	public void reconnect() {
 -		signalusr1();
 -		releaseHold();
 -	}
 -
 -	private void processSignCommand(String b64data) {
 -
 -		PrivateKey privkey = mProfile.getKeystoreKey();
 -		Exception err =null;
 -
 -		byte[] data = Base64.decode(b64data, Base64.DEFAULT);
 -
 -		// The Jelly Bean *evil* Hack
 -		// 4.2 implements the RSA/ECB/PKCS1PADDING in the OpenSSLprovider
 -		if(Build.VERSION.SDK_INT==16){
 -			processSignJellyBeans(privkey,data);
 -			return;
 -		}
 -
 -
 -		try{
 -
 -
 -			Cipher rsasinger = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
 -
 -			rsasinger.init(Cipher.ENCRYPT_MODE, privkey);
 -
 -			byte[] signed_bytes = rsasinger.doFinal(data);
 -			String signed_string = Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
 -			managmentCommand("rsa-sig\n");
 -			managmentCommand(signed_string);
 -			managmentCommand("\nEND\n");
 -		} catch (NoSuchAlgorithmException e){
 -			err =e;
 -		} catch (InvalidKeyException e) {
 -			err =e;
 -		} catch (NoSuchPaddingException e) {
 -			err =e;
 -		} catch (IllegalBlockSizeException e) {
 -			err =e;
 -		} catch (BadPaddingException e) {
 -			err =e;
 -		}
 -		if(err !=null) {
 -			OpenVPN.logError(R.string.error_rsa_sign,err.getClass().toString(),err.getLocalizedMessage());
 -		}
 -
 -	}
 -
 -
 -	private void processSignJellyBeans(PrivateKey privkey, byte[] data) {
 -		Exception err =null;
 -		try {
 -			Method[] allm = privkey.getClass().getSuperclass().getDeclaredMethods();
 -			System.out.println(allm);
 -			Method getKey = privkey.getClass().getSuperclass().getDeclaredMethod("getOpenSSLKey");
 -			getKey.setAccessible(true);
 -
 -			// Real object type is OpenSSLKey
 -			Object opensslkey = getKey.invoke(privkey);
 -
 -			getKey.setAccessible(false);
 -
 -			Method getPkeyContext = opensslkey.getClass().getDeclaredMethod("getPkeyContext");
 -
 -			// integer pointer to EVP_pkey
 -			getPkeyContext.setAccessible(true);
 -			int pkey = (Integer) getPkeyContext.invoke(opensslkey);
 -			getPkeyContext.setAccessible(false);
 -
 -			byte[] signed_bytes = rsasign(data, pkey); 
 -			String signed_string = Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
 -			managmentCommand("rsa-sig\n");
 -			managmentCommand(signed_string);
 -			managmentCommand("\nEND\n");
 -
 -		} catch (NoSuchMethodException e) {
 -			err=e;
 -		} catch (IllegalArgumentException e) {
 -			err=e;
 -		} catch (IllegalAccessException e) {
 -			err=e;
 -		} catch (InvocationTargetException e) {
 -			err=e;
 -		} catch (InvalidKeyException e) {
 -			err=e;
 -		}
 -		if(err !=null) {
 -			OpenVPN.logError(R.string.error_rsa_sign,err.getClass().toString(),err.getLocalizedMessage());
 -		}
 -
 -	}
 -}
 diff --git a/src/se/leap/openvpn/OpenVpnService.java b/src/se/leap/openvpn/OpenVpnService.java deleted file mode 100644 index b5c9c798..00000000 --- a/src/se/leap/openvpn/OpenVpnService.java +++ /dev/null @@ -1,504 +0,0 @@ -package se.leap.openvpn; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Vector; - -import se.leap.bitmaskclient.Dashboard; -import se.leap.bitmaskclient.R; -import android.annotation.TargetApi; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.LocalServerSocket; -import android.net.LocalSocket; -import android.net.LocalSocketAddress; -import android.net.VpnService; -import android.os.Binder; -import android.os.Handler.Callback; -import android.os.Build; -import android.os.IBinder; -import android.os.Message; -import android.os.ParcelFileDescriptor; -import se.leap.openvpn.OpenVPN.StateListener; - -public class OpenVpnService extends VpnService implements StateListener, Callback { -	public static final String START_SERVICE = "se.leap.openvpn.START_SERVICE"; -	public static final String RETRIEVE_SERVICE = "se.leap.openvpn.RETRIEVE_SERVICE"; - -	private Thread mProcessThread=null; - -	private Vector<String> mDnslist=new Vector<String>(); - -	private VpnProfile mProfile; - -	private String mDomain=null; - -	private Vector<CIDRIP> mRoutes=new Vector<CIDRIP>(); -	private Vector<String> mRoutesv6=new Vector<String>(); - -	private CIDRIP mLocalIP=null; - -	private OpenVpnManagementThread mSocketManager; - -	private Thread mSocketManagerThread; -	private int mMtu; -	private String mLocalIPv6=null; -	private NetworkSateReceiver mNetworkStateReceiver; -	private NotificationManager mNotificationManager; - -	private boolean mDisplayBytecount=false; - -	private boolean mStarting=false; - -	private long mConnecttime; - - -	private static final int OPENVPN_STATUS = 1; - -	public static final int PROTECT_FD = 0; - -	private final IBinder mBinder = new LocalBinder(); -	 -	public class LocalBinder extends Binder { -		public OpenVpnService getService() { -            // Return this instance of LocalService so clients can call public methods -            return OpenVpnService.this; -        } -    } -	 -	@Override -	public IBinder onBind(Intent intent) { -		String action = intent.getAction(); -		if( action !=null && (action.equals(START_SERVICE) || action.equals(RETRIEVE_SERVICE)) ) -			return mBinder; -		else -			return super.onBind(intent); -	} -	 -	@Override -	public void onRevoke() { -		OpenVpnManagementThread.stopOpenVPN(); -		endVpnService(); -	} - -	// Similar to revoke but do not try to stop process -	public void processDied() { -		endVpnService(); -	} - -	private void endVpnService() { -		mProcessThread=null; -		OpenVPN.logBuilderConfig(null); -		ProfileManager.setConntectedVpnProfileDisconnected(this); -		if(!mStarting) { -			stopSelf(); -			stopForeground(true); -		} -	} - -	private void showNotification(String state, String msg, String tickerText, boolean lowpriority, long when, boolean persistant) { -		String ns = Context.NOTIFICATION_SERVICE; -		mNotificationManager = (NotificationManager) getSystemService(ns); -		int icon; -		if (state.equals("NOPROCESS") || state.equals("AUTH_FAILED") || state.equals("NONETWORK") || state.equals("EXITING")){ -			icon = R.drawable.ic_vpn_disconnected; -		}else{	 -			icon = R.drawable.ic_stat_vpn; -		} -		 -		android.app.Notification.Builder nbuilder = new Notification.Builder(this); - -		nbuilder.setContentTitle(getString(R.string.notifcation_title,mProfile.mLocation)); -		nbuilder.setContentText(msg); -		nbuilder.setOnlyAlertOnce(true); -		nbuilder.setOngoing(persistant); -		nbuilder.setContentIntent(getLogPendingIntent()); -		nbuilder.setSmallIcon(icon); -		if(when !=0) -			nbuilder.setWhen(when); - - -		// Try to set the priority available since API 16 (Jellybean) -		jbNotificationExtras(lowpriority, nbuilder); -		if(tickerText!=null) -			nbuilder.setTicker(tickerText); - -		@SuppressWarnings("deprecation") -		Notification notification = nbuilder.getNotification(); - - -		mNotificationManager.notify(OPENVPN_STATUS, notification); -	} - -	@TargetApi(Build.VERSION_CODES.JELLY_BEAN) -	private void jbNotificationExtras(boolean lowpriority, -			android.app.Notification.Builder nbuilder) { -		try { -			if(lowpriority) { -				Method setpriority = nbuilder.getClass().getMethod("setPriority", int.class); -				// PRIORITY_MIN == -2 -				setpriority.invoke(nbuilder, -2 ); - -				nbuilder.setUsesChronometer(true); -				/*				PendingIntent cancelconnet=null; - -				nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel,  -						getString(R.string.cancel_connection),cancelconnet); */ -			} - -			//ignore exception -		} catch (NoSuchMethodException nsm) { -		} catch (IllegalArgumentException e) { -		} catch (IllegalAccessException e) { -		} catch (InvocationTargetException e) { -		} - -	} - -	PendingIntent getLogPendingIntent() { -		// Let the configure Button show the Dashboard -		Intent intent = new Intent(Dashboard.getAppContext(),Dashboard.class); -		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); -		PendingIntent startLW = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); -		intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); -		return startLW; - -	} - - -	private LocalServerSocket openManagmentInterface(int tries) { -		// Could take a while to open connection -		String socketname = (getCacheDir().getAbsolutePath() + "/" +  "mgmtsocket"); -		LocalSocket sock = new LocalSocket(); - -		while(tries > 0 && !sock.isConnected()) { -			try { -				sock.bind(new LocalSocketAddress(socketname, -						LocalSocketAddress.Namespace.FILESYSTEM)); -			} catch (IOException e) { -				// wait 300 ms before retrying -				try { Thread.sleep(300); -				} catch (InterruptedException e1) {} - -			}  -			tries--; -		} - -		try { -			LocalServerSocket lss = new LocalServerSocket(sock.getFileDescriptor()); -			return lss; -		} catch (IOException e) { -			e.printStackTrace(); -		} -		return null; - - -	} - -	void registerNetworkStateReceiver() { -		// Registers BroadcastReceiver to track network connection changes. -		IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); -		mNetworkStateReceiver = new NetworkSateReceiver(mSocketManager); -		this.registerReceiver(mNetworkStateReceiver, filter); -	} - - -	@Override -	public int onStartCommand(Intent intent, int flags, int startId) {		 -		 -		if( intent != null && intent.getAction() !=null && -				(intent.getAction().equals(START_SERVICE) || intent.getAction().equals(RETRIEVE_SERVICE)) ) -			return START_NOT_STICKY; -			 - -		// Extract information from the intent. -		String prefix = getPackageName(); -		String[] argv = intent.getStringArrayExtra(prefix + ".ARGV"); -		String nativelibdir = intent.getStringExtra(prefix + ".nativelib"); -		String profileUUID = intent.getStringExtra(prefix + ".profileUUID"); - -		mProfile = ProfileManager.get(profileUUID); - -		//showNotification("Starting VPN " + mProfile.mName,"Starting VPN " + mProfile.mName, false,0); - - -		OpenVPN.addStateListener(this); - -		// Set a flag that we are starting a new VPN -		mStarting=true; -		// Stop the previous session by interrupting the thread. -		if(OpenVpnManagementThread.stopOpenVPN()){ -			// an old was asked to exit, wait 2s -			try { -				Thread.sleep(1000); -			} catch (InterruptedException e) { -			} -		} - -		if (mProcessThread!=null) { -			mProcessThread.interrupt(); -			try { -				Thread.sleep(1000); -			} catch (InterruptedException e) { -			} -		} -		// An old running VPN should now be exited -		mStarting=false; - - -		// Open the Management Interface -		LocalServerSocket mgmtsocket = openManagmentInterface(8); - -		if(mgmtsocket!=null) { -			// start a Thread that handles incoming messages of the managment socket -			mSocketManager = new OpenVpnManagementThread(mProfile,mgmtsocket,this); -			mSocketManagerThread = new Thread(mSocketManager,"OpenVPNMgmtThread"); -			mSocketManagerThread.start(); -			OpenVPN.logInfo("started Socket Thread"); -			registerNetworkStateReceiver(); -		} - - -		// Start a new session by creating a new thread. -		OpenVPNThread processThread = new OpenVPNThread(this, argv,nativelibdir); - -		mProcessThread = new Thread(processThread, "OpenVPNProcessThread"); -		mProcessThread.start(); - -		ProfileManager.setConnectedVpnProfile(this, mProfile); - -		return START_NOT_STICKY; -	} - -	@Override -	public void onDestroy() { -		if (mProcessThread != null) { -			mSocketManager.managmentCommand("signal SIGINT\n"); - -			mProcessThread.interrupt(); -		} -		if (mNetworkStateReceiver!= null) { -			this.unregisterReceiver(mNetworkStateReceiver); -		} - -	} - - - -	public ParcelFileDescriptor openTun() { -		Builder builder = new Builder(); - -		if(mLocalIP==null && mLocalIPv6==null) { -			OpenVPN.logMessage(0, "", getString(R.string.opentun_no_ipaddr)); -			return null; -		} - -		if(mLocalIP!=null) { -			builder.addAddress(mLocalIP.mIp, mLocalIP.len); -		} - -		if(mLocalIPv6!=null) { -			String[] ipv6parts = mLocalIPv6.split("/"); -			builder.addAddress(ipv6parts[0],Integer.parseInt(ipv6parts[1])); -		} - - -		for (String dns : mDnslist ) { -			try { -				builder.addDnsServer(dns); -			} catch (IllegalArgumentException iae) { -				OpenVPN.logError(R.string.dns_add_error, dns,iae.getLocalizedMessage()); -			} -		} - - -		builder.setMtu(mMtu); - - -		for (CIDRIP route:mRoutes) { -			try { -				builder.addRoute(route.mIp, route.len); -			} catch (IllegalArgumentException ia) { -				OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage()); -			} -		} - -		for(String v6route:mRoutesv6) { -			try { -				String[] v6parts = v6route.split("/"); -				builder.addRoute(v6parts[0],Integer.parseInt(v6parts[1])); -			} catch (IllegalArgumentException ia) { -				OpenVPN.logMessage(0, "", getString(R.string.route_rejected) + v6route + " " + ia.getLocalizedMessage()); -			} -		} - -		if(mDomain!=null) -			builder.addSearchDomain(mDomain); - -		String bconfig[] = new String[6]; - -		bconfig[0]=  getString(R.string.last_openvpn_tun_config); -		bconfig[1] = getString(R.string.local_ip_info,mLocalIP.mIp,mLocalIP.len,mLocalIPv6, mMtu); -		bconfig[2] = getString(R.string.dns_server_info, joinString(mDnslist)); -		bconfig[3] = getString(R.string.dns_domain_info, mDomain); -		bconfig[4] = getString(R.string.routes_info, joinString(mRoutes)); -		bconfig[5] = getString(R.string.routes_info6, joinString(mRoutesv6)); - -		String session = mProfile.mLocation; -		/* we don't want the IP address in the notification bar -		if(mLocalIP!=null && mLocalIPv6!=null) -			session = getString(R.string.session_ipv6string,session, mLocalIP, mLocalIPv6); -		else if (mLocalIP !=null) -			session= getString(R.string.session_ipv4string, session, mLocalIP); -		 */ -		builder.setSession(session); - - -		OpenVPN.logBuilderConfig(bconfig); - -		// No DNS Server, log a warning  -		if(mDnslist.size()==0) -			OpenVPN.logInfo(R.string.warn_no_dns); - -		// Reset information -		mDnslist.clear(); -		mRoutes.clear(); -		mRoutesv6.clear(); -		mLocalIP=null; -		mLocalIPv6=null; -		mDomain=null; - -		builder.setConfigureIntent(getLogPendingIntent()); - -		try { -			ParcelFileDescriptor pfd = builder.establish(); -			return pfd; -		} catch (Exception e) { -			OpenVPN.logMessage(0, "", getString(R.string.tun_open_error)); -			OpenVPN.logMessage(0, "", getString(R.string.error) + e.getLocalizedMessage()); -			OpenVPN.logMessage(0, "", getString(R.string.tun_error_helpful)); -			return null; -		} - -	} - - -	// Ugly, but java has no such method -	private <T> String joinString(Vector<T> vec) { -		String ret = ""; -		if(vec.size() > 0){  -			ret = vec.get(0).toString(); -			for(int i=1;i < vec.size();i++) { -				ret = ret + ", " + vec.get(i).toString(); -			} -		} -		return ret; -	} - - - - - - -	public void addDNS(String dns) { -		mDnslist.add(dns);		 -	} - - -	public void setDomain(String domain) { -		if(mDomain==null) { -			mDomain=domain; -		} -	} - - -	public void addRoute(String dest, String mask) { -		CIDRIP route = new CIDRIP(dest, mask);		 -		if(route.len == 32 && !mask.equals("255.255.255.255")) { -			OpenVPN.logMessage(0, "", getString(R.string.route_not_cidr,dest,mask)); -		} - -		if(route.normalise()) -			OpenVPN.logMessage(0, "", getString(R.string.route_not_netip,dest,route.len,route.mIp)); - -		mRoutes.add(route); -	} - -	public void addRoutev6(String extra) { -		mRoutesv6.add(extra);		 -	} - - -	public void setLocalIP(String local, String netmask,int mtu, String mode) { -		mLocalIP = new CIDRIP(local, netmask); -		mMtu = mtu; - -		if(mLocalIP.len == 32 && !netmask.equals("255.255.255.255")) { -			// get the netmask as IP -			long netint = CIDRIP.getInt(netmask); -			if(Math.abs(netint - mLocalIP.getInt()) ==1) { -				if(mode.equals("net30")) -					mLocalIP.len=30; -				else -					mLocalIP.len=31; -			} else { -				OpenVPN.logMessage(0, "", getString(R.string.ip_not_cidr, local,netmask,mode)); -			} -		} -	} - -	public void setLocalIPv6(String ipv6addr) { -		mLocalIPv6 = ipv6addr; -	} - -	public boolean isRunning() { -		if (mStarting == true || mProcessThread != null) -			return true; -		else -			return false; -	} -	 -	@Override -	public void updateState(String state,String logmessage, int resid) { -		// If the process is not running, ignore any state,  -		// Notification should be invisible in this state -		if(mProcessThread==null) -			return;	 -		if("CONNECTED".equals(state)) { -			mNotificationManager.cancel(OPENVPN_STATUS); -		} else if(!"BYTECOUNT".equals(state)) { - -			// Other notifications are shown, -			// This also mean we are no longer connected, ignore bytecount messages until next -			// CONNECTED -			String ticker = getString(resid); -			boolean persist = false; -			if (("NOPROCESS".equals(state) ) || ("EXITING").equals(state)){ -				showNotification(state, getString(R.string.eip_state_not_connected), ticker, false, 0, persist); -			} -			else if (state.equals("GET_CONFIG") || state.equals("ASSIGN_IP")){ //don't show them in the notification message -			} -			else{ -				persist = true; -				showNotification(state, getString(resid) +" " + logmessage,ticker,false,0,persist); -			}			  -		} -	} - -	@Override -	public boolean handleMessage(Message msg) { -		Runnable r = msg.getCallback(); -		if(r!=null){ -			r.run(); -			return true; -		} else { -			return false; -		} -	} -} diff --git a/src/se/leap/openvpn/ProfileManager.java b/src/se/leap/openvpn/ProfileManager.java deleted file mode 100644 index b9eb3ab6..00000000 --- a/src/se/leap/openvpn/ProfileManager.java +++ /dev/null @@ -1,220 +0,0 @@ -package se.leap.openvpn; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.StreamCorruptedException; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.preference.PreferenceManager; - -public class ProfileManager { -	private static final String PREFS_NAME =  "VPNList"; - - - -	private static final String ONBOOTPROFILE = "onBootProfile"; - - - -	private static ProfileManager instance; - - - -	private static VpnProfile mLastConnectedVpn=null; -	private HashMap<String,VpnProfile> profiles=new HashMap<String, VpnProfile>(); -	private static VpnProfile tmpprofile=null; - - -	public static VpnProfile get(String key) { -		if (tmpprofile!=null && tmpprofile.getUUIDString().equals(key)) -			return tmpprofile; -			 -		if(instance==null) -			return null; -		return instance.profiles.get(key); -		 -	} - - -	 -	private ProfileManager() { } -	 -	private static void checkInstance(Context context) { -		if(instance == null) { -			instance = new ProfileManager(); -			instance.loadVPNList(context); -		} -	} - -	synchronized public static ProfileManager getInstance(Context context) { -		checkInstance(context); -		return instance; -	} -	 -	public static void setConntectedVpnProfileDisconnected(Context c) { -		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); -		Editor prefsedit = prefs.edit(); -		prefsedit.putString(ONBOOTPROFILE, null); -		prefsedit.apply(); -		 -	} - -	public static void setConnectedVpnProfile(Context c, VpnProfile connectedrofile) { -		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); -		Editor prefsedit = prefs.edit(); -		 -		prefsedit.putString(ONBOOTPROFILE, connectedrofile.getUUIDString()); -		prefsedit.apply(); -		mLastConnectedVpn=connectedrofile; -		 -	} -	 -	public static VpnProfile getOnBootProfile(Context c) { -		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); - -		boolean useStartOnBoot = prefs.getBoolean("restartvpnonboot", false); - -		 -		String mBootProfileUUID = prefs.getString(ONBOOTPROFILE,null); -		if(useStartOnBoot && mBootProfileUUID!=null) -			return get(c, mBootProfileUUID); -		else  -			return null; -	} -	 -	 -	 -	 -	public Collection<VpnProfile> getProfiles() { -		return profiles.values(); -	} -	 -	public VpnProfile getProfileByName(String name) { -		for (VpnProfile vpnp : profiles.values()) { -			if(vpnp.getName().equals(name)) { -				return vpnp; -			} -		} -		return null;			 -	} - -	public void saveProfileList(Context context) { -		SharedPreferences sharedprefs = context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE); -		Editor editor = sharedprefs.edit(); -		editor.putStringSet("vpnlist", profiles.keySet()); -		 -		// For reasing I do not understand at all  -		// Android saves my prefs file only one time  -		// if I remove the debug code below :( -		int counter = sharedprefs.getInt("counter", 0); -		editor.putInt("counter", counter+1); -		editor.apply(); - -	} - -	public void addProfile(VpnProfile profile) { -		profiles.put(profile.getUUID().toString(),profile); -		 -	} -	 -	public static void setTemporaryProfile(VpnProfile tmp) { -		ProfileManager.tmpprofile = tmp; -	} -	 -	 -	public void saveProfile(Context context,VpnProfile profile) { -		// First let basic settings save its state -		 -		ObjectOutputStream vpnfile; -		try { -			vpnfile = new ObjectOutputStream(context.openFileOutput((profile.getUUID().toString() + ".vp"),Activity.MODE_PRIVATE)); - -			vpnfile.writeObject(profile); -			vpnfile.flush(); -			vpnfile.close(); -		} catch (FileNotFoundException e) { - -			e.printStackTrace(); -			throw new RuntimeException(e); -		} catch (IOException e) { - -			e.printStackTrace(); -			throw new RuntimeException(e); - -		} -	} -	 -	 -	private void loadVPNList(Context context) { -		profiles = new HashMap<String, VpnProfile>(); -		SharedPreferences listpref = context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE); -		Set<String> vlist = listpref.getStringSet("vpnlist", null); -		Exception exp =null; -		if(vlist==null){ -			vlist = new HashSet<String>(); -		} - -		for (String vpnentry : vlist) { -			try { -				ObjectInputStream vpnfile = new ObjectInputStream(context.openFileInput(vpnentry + ".vp")); -				VpnProfile vp = ((VpnProfile) vpnfile.readObject()); - -				// Sanity check  -				if(vp==null || vp.mName==null || vp.getUUID()==null) -					continue; -				 -				profiles.put(vp.getUUID().toString(), vp); - -			} catch (StreamCorruptedException e) { -				exp=e; -			} catch (FileNotFoundException e) { -				exp=e; -			} catch (IOException e) { -				exp=e; -			} catch (ClassNotFoundException e) {  -				exp=e; -			} -			if(exp!=null) { -				exp.printStackTrace(); -			} -		} -	} - -	public int getNumberOfProfiles() { -		return profiles.size(); -	} - - - -	public void removeProfile(Context context,VpnProfile profile) { -		String vpnentry = profile.getUUID().toString(); -		profiles.remove(vpnentry); -		saveProfileList(context); -		context.deleteFile(vpnentry + ".vp"); -		if(mLastConnectedVpn==profile) -			mLastConnectedVpn=null; -		 -	} - - - -	public static VpnProfile get(Context context, String profileUUID) { -		checkInstance(context); -		return get(profileUUID); -	} - - - -	public static VpnProfile getLastConnectedVpn() { -		return mLastConnectedVpn; -	} - -} diff --git a/src/se/leap/openvpn/ProxyDetection.java b/src/se/leap/openvpn/ProxyDetection.java deleted file mode 100644 index c7b3d196..00000000 --- a/src/se/leap/openvpn/ProxyDetection.java +++ /dev/null @@ -1,54 +0,0 @@ -package se.leap.openvpn; - -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.SocketAddress; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.List; - -import se.leap.bitmaskclient.R; - -public class ProxyDetection { -	static SocketAddress detectProxy(VpnProfile vp) { -		// Construct a new url with https as protocol -		try { -			URL url = new URL(String.format("https://%s:%s",vp.mServerName,vp.mServerPort)); -			Proxy proxy = getFirstProxy(url); - -			if(proxy==null) -				return null; -			SocketAddress addr = proxy.address(); -			if (addr instanceof InetSocketAddress) { -				return addr;  -			} -			 -		} catch (MalformedURLException e) { -			OpenVPN.logError(R.string.getproxy_error,e.getLocalizedMessage()); -		} catch (URISyntaxException e) { -			OpenVPN.logError(R.string.getproxy_error,e.getLocalizedMessage()); -		} -		return null; -	} - -	static Proxy getFirstProxy(URL url) throws URISyntaxException { -		System.setProperty("java.net.useSystemProxies", "true"); - -		List<Proxy> proxylist = ProxySelector.getDefault().select(url.toURI()); - - -		if (proxylist != null) { -			for (Proxy proxy: proxylist) { -				SocketAddress addr = proxy.address(); - -				if (addr != null) { -					return proxy; -				} -			} - -		} -		return null; -	} -}
\ No newline at end of file diff --git a/src/se/leap/openvpn/VPNLaunchHelper.java b/src/se/leap/openvpn/VPNLaunchHelper.java deleted file mode 100644 index 418cf7e9..00000000 --- a/src/se/leap/openvpn/VPNLaunchHelper.java +++ /dev/null @@ -1,76 +0,0 @@ -package se.leap.openvpn; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import se.leap.bitmaskclient.R; - -import android.content.Context; -import android.content.Intent; -import android.os.Build; - -public class VPNLaunchHelper { -	static private boolean writeMiniVPN(Context context) { -		File mvpnout = new File(context.getCacheDir(),VpnProfile.MINIVPN); -		if (mvpnout.exists() && mvpnout.canExecute()) -			return true; - -		IOException e2 = null; - -		try { -			InputStream mvpn; -			 -			try { -				mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI); -			} -			catch (IOException errabi) { -				OpenVPN.logInfo("Failed getting assets for archicture " + Build.CPU_ABI); -				e2=errabi; -				mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI2); -				 -			} - - -			FileOutputStream fout = new FileOutputStream(mvpnout); - -			byte buf[]= new byte[4096]; - -			int lenread = mvpn.read(buf); -			while(lenread> 0) { -				fout.write(buf, 0, lenread); -				lenread = mvpn.read(buf); -			} -			fout.close(); - -			if(!mvpnout.setExecutable(true)) { -				OpenVPN.logMessage(0, "","Failed to set minivpn executable"); -				return false; -			} -				 -			 -			return true; -		} catch (IOException e) { -			if(e2!=null) -				OpenVPN.logMessage(0, "",e2.getLocalizedMessage()); -			OpenVPN.logMessage(0, "",e.getLocalizedMessage()); -			e.printStackTrace(); -			return false; -		} -	} -	 - -	public static void startOpenVpn(VpnProfile startprofile, Context context) { -		if(!writeMiniVPN(context)) { -			OpenVPN.logMessage(0, "", "Error writing minivpn binary"); -			return; -		} -		OpenVPN.logMessage(0, "", context.getString(R.string.building_configration)); - -		Intent startVPN = startprofile.prepareIntent(context); -		if(startVPN!=null) -			context.startService(startVPN); - -	} -} diff --git a/src/se/leap/openvpn/VpnProfile.java b/src/se/leap/openvpn/VpnProfile.java deleted file mode 100644 index 481819ad..00000000 --- a/src/se/leap/openvpn/VpnProfile.java +++ /dev/null @@ -1,758 +0,0 @@ -package se.leap.openvpn; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.Collection; -import java.util.UUID; -import java.util.Vector; - -import org.spongycastle.util.io.pem.PemObject; -import org.spongycastle.util.io.pem.PemWriter; - -import se.leap.bitmaskclient.ConfigHelper; -import se.leap.bitmaskclient.Dashboard; -import se.leap.bitmaskclient.EIP; -import se.leap.bitmaskclient.Provider; -import se.leap.bitmaskclient.R; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; -import android.preference.PreferenceManager; -import android.security.KeyChain; -import android.security.KeyChainException; - -public class VpnProfile implements  Serializable{ -	// Parcable -	/** -	 *  -	 */ -	private static final long serialVersionUID = 7085688938959334563L; -	static final int TYPE_CERTIFICATES=0; -	static final int TYPE_PKCS12=1; -	static final int TYPE_KEYSTORE=2; -	public static final int TYPE_USERPASS = 3; -	public static final int TYPE_STATICKEYS = 4; -	public static final int TYPE_USERPASS_CERTIFICATES = 5; -	public static final int TYPE_USERPASS_PKCS12 = 6; -	public static final int TYPE_USERPASS_KEYSTORE = 7; - -	// Don't change this, not all parts of the program use this constant -	public static final String EXTRA_PROFILEUUID = "se.leap.bitmaskclient.profileUUID"; // TODO this feels wrong.  See Issue #1494 -	public static final String INLINE_TAG = "[[INLINE]]"; -	private static final String OVPNCONFIGFILE = "android.conf"; - -	protected transient String mTransientPW=null; -	protected transient String mTransientPCKS12PW=null; -	private transient PrivateKey mPrivateKey; -	protected boolean profileDleted=false; - - -	public static String DEFAULT_DNS1="131.234.137.23"; -	public static String DEFAULT_DNS2="131.234.137.24"; - -	// Public attributes, since I got mad with getter/setter -	// set members to default values -	private UUID mUuid; -	public int mAuthenticationType = TYPE_CERTIFICATES ; -	public String mName; -	public String mLocation; -	public String mAlias; -	public String mClientCertFilename; -	public String mTLSAuthDirection=""; -	public String mTLSAuthFilename; -	public String mClientKeyFilename; -	public String mCaFilename; -	public boolean mUseLzo=true; -	public String mServerPort= "1194" ; -	public boolean mUseUdp = true; -	public String mPKCS12Filename; -	public String mPKCS12Password; -	public boolean mUseTLSAuth = false; -	public String mServerName = "openvpn.blinkt.de" ; -	public String mDNS1=DEFAULT_DNS1; -	public String mDNS2=DEFAULT_DNS2; -	public String mIPv4Address; -	public String mIPv6Address; -	public boolean mOverrideDNS=false; -	public String mSearchDomain="blinkt.de"; -	public boolean mUseDefaultRoute=true; -	public boolean mUsePull=true; -	public String mCustomRoutes; -	public boolean mCheckRemoteCN=false; -	public boolean mExpectTLSCert=true; -	public String mRemoteCN=""; -	public String mPassword=""; -	public String mUsername=""; -	public boolean mRoutenopull=false; -	public boolean mUseRandomHostname=false; -	public boolean mUseFloat=false; -	public boolean mUseCustomConfig=false; -	public String mCustomConfigOptions=""; -	public String mVerb="1"; -	public String mCipher=""; -	public boolean mNobind=false; -	public boolean mUseDefaultRoutev6=true; -	public String mCustomRoutesv6=""; -	public String mKeyPassword=""; -	public boolean mPersistTun = false; -	public String mConnectRetryMax="5"; -	public String mConnectRetry="10"; -	public boolean mUserEditable=true; -	 -	static final String MINIVPN = "miniopenvpn"; -	 -	 -	 - - - -	public void clearDefaults() { -		mServerName="unkown"; -		mUsePull=false; -		mUseLzo=false; -		mUseDefaultRoute=false; -		mUseDefaultRoutev6=false; -		mExpectTLSCert=false; -		mPersistTun = false; -	} - - -	public static String openVpnEscape(String unescaped) { -		if(unescaped==null) -			return null; -		String escapedString = unescaped.replace("\\", "\\\\"); -		escapedString = escapedString.replace("\"","\\\""); -		escapedString = escapedString.replace("\n","\\n"); - -		if (escapedString.equals(unescaped) && !escapedString.contains(" ") && !escapedString.contains("#")) -			return unescaped; -		else -			return '"' + escapedString + '"'; -	} - - -	static final String OVPNCONFIGCA = "android-ca.pem"; -	static final String OVPNCONFIGUSERCERT = "android-user.pem"; - - -	public VpnProfile(String name) { -		mUuid = UUID.randomUUID(); -		mName = name; -	} - -	public UUID getUUID() { -		return mUuid; - -	} - -	public String getName() { -		return mName; -	} - - -	public String getConfigFile(Context context) -	{ - -		File cacheDir= context.getCacheDir(); -		String cfg=""; - -		// Enable managment interface -		cfg += "# Enables connection to GUI\n"; -		cfg += "management "; - -		cfg +=cacheDir.getAbsolutePath() + "/" +  "mgmtsocket"; -		cfg += " unix\n"; -		cfg += "management-client\n"; -		// Not needed, see updated man page in 2.3 -		//cfg += "management-signal\n"; -		cfg += "management-query-passwords\n"; -		cfg += "management-hold\n\n"; - -		/* tmp-dir patched out :)  -		cfg+="# /tmp does not exist on Android\n"; -		cfg+="tmp-dir "; -		cfg+=cacheDir.getAbsolutePath(); -		cfg+="\n\n"; */ - -		cfg+="# Log window is better readable this way\n"; -		cfg+="suppress-timestamps\n"; - - - -		boolean useTLSClient = (mAuthenticationType != TYPE_STATICKEYS); - -		if(useTLSClient && mUsePull) -			cfg+="client\n"; -		else if (mUsePull) -			cfg+="pull\n"; -		else if(useTLSClient) -			cfg+="tls-client\n"; - - -		cfg+="verb " + mVerb + "\n"; - -		if(mConnectRetryMax ==null) { -			mConnectRetryMax="5"; -		} -		 -		if(!mConnectRetryMax.equals("-1")) -				cfg+="connect-retry-max " + mConnectRetryMax+ "\n"; -	 -		if(mConnectRetry==null) -			mConnectRetry="10"; -		 -	 -		cfg+="connect-retry " + mConnectRetry + "\n"; -		 -		cfg+="resolv-retry 60\n"; - - - -		// We cannot use anything else than tun -		cfg+="dev tun\n"; - -		// Server Address -		cfg+="remote "; -		cfg+=mServerName; -		cfg+=" "; -		cfg+=mServerPort; -		if(mUseUdp) -			cfg+=" udp\n"; -		else -			cfg+=" tcp-client\n"; - - - - -		switch(mAuthenticationType) { -		case VpnProfile.TYPE_USERPASS_CERTIFICATES: -			cfg+="auth-user-pass\n"; -		case VpnProfile.TYPE_CERTIFICATES: -			/*// Ca -			cfg+=insertFileData("ca",mCaFilename); - -			// Client Cert + Key -			cfg+=insertFileData("key",mClientKeyFilename); -			cfg+=insertFileData("cert",mClientCertFilename); -*/ -			// FIXME This is all we need...The whole switch statement can go... -			SharedPreferences preferences = context.getSharedPreferences(Dashboard.SHARED_PREFERENCES, context.MODE_PRIVATE); -			cfg+="<ca>\n"+preferences.getString(Provider.CA_CERT, "")+"\n</ca>\n"; -			cfg+="<key>\n"+preferences.getString(EIP.PRIVATE_KEY, "")+"\n</key>\n"; -			cfg+="<cert>\n"+preferences.getString(EIP.CERTIFICATE, "")+"\n</cert>\n"; -			 -			break; -		case VpnProfile.TYPE_USERPASS_PKCS12: -			cfg+="auth-user-pass\n"; -		case VpnProfile.TYPE_PKCS12: -			cfg+=insertFileData("pkcs12",mPKCS12Filename); -			break; - -		case VpnProfile.TYPE_USERPASS_KEYSTORE: -			cfg+="auth-user-pass\n"; -		case VpnProfile.TYPE_KEYSTORE: -			cfg+="ca " + cacheDir.getAbsolutePath() + "/" + OVPNCONFIGCA + "\n"; -			cfg+="cert " + cacheDir.getAbsolutePath() + "/" + OVPNCONFIGUSERCERT + "\n"; -			cfg+="management-external-key\n"; -			 -			break; -		case VpnProfile.TYPE_USERPASS: -			cfg+="auth-user-pass\n"; -			cfg+=insertFileData("ca",mCaFilename); -		} - -		if(mUseLzo) { -			cfg+="comp-lzo\n"; -		} - -		if(mUseTLSAuth) { -			if(mAuthenticationType==TYPE_STATICKEYS) -				cfg+=insertFileData("secret",mTLSAuthFilename); -			else -				cfg+=insertFileData("tls-auth",mTLSAuthFilename); - -			if(nonNull(mTLSAuthDirection)) { -				cfg+= "key-direction "; -				cfg+= mTLSAuthDirection; -				cfg+="\n"; -			} - -		} - -		if(!mUsePull ) { -			if(nonNull(mIPv4Address)) -				cfg +="ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n"; - -			if(nonNull(mIPv6Address)) -				cfg +="ifconfig-ipv6 " + mIPv6Address + "\n"; -		} - -		if(mUsePull && mRoutenopull) -			cfg += "route-nopull\n"; - -		String routes = ""; -		int numroutes=0; -		if(mUseDefaultRoute) -			routes += "route 0.0.0.0 0.0.0.0\n"; -		else -			for(String route:getCustomRoutes()) { -				routes += "route " + route + "\n"; -				numroutes++; -			} - - -		if(mUseDefaultRoutev6) -			cfg += "route-ipv6 ::/0\n"; -		else -			for(String route:getCustomRoutesv6()) { -				routes += "route-ipv6 " + route + "\n"; -				numroutes++; -			} - -		// Round number to next 100  -		if(numroutes> 90) { -			numroutes = ((numroutes / 100)+1) * 100; -			cfg+="# Alot of routes are set, increase max-routes\n"; -			cfg+="max-routes " + numroutes + "\n"; -		} -		cfg+=routes; -		 -		if(mOverrideDNS || !mUsePull) { -			if(nonNull(mDNS1)) -				cfg+="dhcp-option DNS " + mDNS1 + "\n"; -			if(nonNull(mDNS2)) -				cfg+="dhcp-option DNS " + mDNS2 + "\n"; -			if(nonNull(mSearchDomain)) -				cfg+="dhcp-option DOMAIN " + mSearchDomain + "\n"; - -		} - -		if(mNobind) -			cfg+="nobind\n"; - - - -		// Authentication -		if(mCheckRemoteCN) { -			if(mRemoteCN == null || mRemoteCN.equals("") ) -				cfg+="tls-remote " + mServerName + "\n"; -			else -				cfg += "tls-remote " + openVpnEscape(mRemoteCN) + "\n"; -		} -		if(mExpectTLSCert) -			cfg += "remote-cert-tls server\n"; - - -		if(nonNull(mCipher)){ -			cfg += "cipher " + mCipher + "\n"; -		} - - -		// Obscure Settings dialog -		if(mUseRandomHostname) -			cfg += "#my favorite options :)\nremote-random-hostname\n"; - -		if(mUseFloat) -			cfg+= "float\n"; - -		if(mPersistTun) { -			cfg+= "persist-tun\n"; -			cfg+= "# persist-tun also sets persist-remote-ip to avoid DNS resolve problem\n"; -			cfg+= "persist-remote-ip\n"; -		} -		 -		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);         -		boolean usesystemproxy = prefs.getBoolean("usesystemproxy", true); -		if(usesystemproxy) { -			cfg+= "# Use system proxy setting\n"; -			cfg+= "management-query-proxy\n"; -		} -		 -		 -		if(mUseCustomConfig) { -			cfg += "# Custom configuration options\n"; -			cfg += "# You are on your on own here :)\n"; -			cfg += mCustomConfigOptions; -			cfg += "\n"; - -		} - - - -		return cfg; -	} - -	//! Put inline data inline and other data as normal escaped filename -	private String insertFileData(String cfgentry, String filedata) { -		if(filedata==null) { -			return String.format("%s %s\n",cfgentry,"missing"); -		}else if(filedata.startsWith(VpnProfile.INLINE_TAG)){ -			String datawoheader = filedata.substring(VpnProfile.INLINE_TAG.length()); -			return String.format("<%s>\n%s\n</%s>\n",cfgentry,datawoheader,cfgentry); -		} else { -			return String.format("%s %s\n",cfgentry,openVpnEscape(filedata)); -		} -	} - -	private boolean nonNull(String val) { -		if(val == null || val.equals(""))  -			return false; -		else -			return true; -	} - -	private Collection<String> getCustomRoutes() { -		Vector<String> cidrRoutes=new Vector<String>(); -		if(mCustomRoutes==null) { -			// No routes set, return empty vector -			return cidrRoutes; -		} -		for(String route:mCustomRoutes.split("[\n \t]")) { -			if(!route.equals("")) { -				String cidrroute = cidrToIPAndNetmask(route); -				if(cidrRoutes == null) -					return null; - -				cidrRoutes.add(cidrroute); -			} -		} - -		return cidrRoutes; -	} - -	private Collection<String> getCustomRoutesv6() { -		Vector<String> cidrRoutes=new Vector<String>(); -		if(mCustomRoutesv6==null) { -			// No routes set, return empty vector -			return cidrRoutes; -		} -		for(String route:mCustomRoutesv6.split("[\n \t]")) { -			if(!route.equals("")) { -				cidrRoutes.add(route); -			} -		} - -		return cidrRoutes; -	} - - - -	private String cidrToIPAndNetmask(String route) { -		String[] parts = route.split("/"); - -		// No /xx, assume /32 as netmask -		if (parts.length ==1) -			parts = (route + "/32").split("/"); - -		if (parts.length!=2) -			return null; -		int len; -		try {  -			len = Integer.parseInt(parts[1]); -		}	catch(NumberFormatException ne) { -			return null; -		} -		if (len <0 || len >32) -			return null; - - -		long nm = 0xffffffffl; -		nm = (nm << (32-len)) & 0xffffffffl; - -		String netmask =String.format("%d.%d.%d.%d", (nm & 0xff000000) >> 24,(nm & 0xff0000) >> 16, (nm & 0xff00) >> 8 ,nm & 0xff  );	 -		return parts[0] + "  " + netmask; -	} - - - -	private String[] buildOpenvpnArgv(File cacheDir) -	{ -		Vector<String> args = new Vector<String>(); - -		// Add fixed paramenters -		//args.add("/data/data/se.leap.openvpn/lib/openvpn"); -		args.add(cacheDir.getAbsolutePath() +"/" + VpnProfile.MINIVPN); - -		args.add("--config"); -		args.add(cacheDir.getAbsolutePath() + "/" + OVPNCONFIGFILE); -		// Silences script security warning - -		args.add("script-security"); -		args.add("0"); - - -		return  (String[]) args.toArray(new String[args.size()]); -	} - -	public Intent prepareIntent(Context context) { -		String prefix = context.getPackageName(); - -		Intent intent = new Intent(context,OpenVpnService.class); - -		if(mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) { -			/*if(!saveCertificates(context)) -				return null;*/ -		} - -		intent.putExtra(prefix + ".ARGV" , buildOpenvpnArgv(context.getCacheDir())); -		intent.putExtra(prefix + ".profileUUID", mUuid.toString()); - -		ApplicationInfo info = context.getApplicationInfo(); -		intent.putExtra(prefix +".nativelib",info.nativeLibraryDir); - -		try { -			FileWriter cfg = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE); -			cfg.write(getConfigFile(context)); -			cfg.flush(); -			cfg.close(); -		} catch (IOException e) { -			e.printStackTrace(); -		} - -		return intent; -	} - -	private boolean saveCertificates(Context context) { -		PrivateKey privateKey = null; -		X509Certificate[] cachain=null; -		try { -			privateKey = KeyChain.getPrivateKey(context,mAlias); -			mPrivateKey = privateKey; -			 -			cachain = KeyChain.getCertificateChain(context, mAlias); -			if(cachain.length <= 1 && !nonNull(mCaFilename)) -				OpenVPN.logMessage(0, "", context.getString(R.string.keychain_nocacert)); -			 -			for(X509Certificate cert:cachain) { -				OpenVPN.logInfo(R.string.cert_from_keystore,cert.getSubjectDN()); -			} -		 -			 -			 - -			if(nonNull(mCaFilename)) { -				try { -					Certificate cacert = getCacertFromFile(); -					X509Certificate[] newcachain = new X509Certificate[cachain.length+1]; -					for(int i=0;i<cachain.length;i++) -						newcachain[i]=cachain[i]; -					 -					newcachain[cachain.length-1]=(X509Certificate) cacert; -					 -				} catch (Exception e) { -					OpenVPN.logError("Could not read CA certificate" + e.getLocalizedMessage()); -				} -			} - -			 -			FileWriter fout = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + VpnProfile.OVPNCONFIGCA); -			PemWriter pw = new PemWriter(fout); -			for(X509Certificate cert:cachain) { -				pw.writeObject(new PemObject("CERTIFICATE", cert.getEncoded())); -			} - -			pw.close(); -			 -			 -			if(cachain.length>= 1){ -				X509Certificate usercert = cachain[0]; - -				FileWriter userout = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + VpnProfile.OVPNCONFIGUSERCERT); - -				PemWriter upw = new PemWriter(userout); -				upw.writeObject(new PemObject("CERTIFICATE", usercert.getEncoded())); -				upw.close(); - -			} -			 -			return true; -		} catch (InterruptedException e) { -			e.printStackTrace(); -		} catch (FileNotFoundException e) { -			e.printStackTrace(); -		} catch (CertificateException e) { -			e.printStackTrace(); -		} catch (IOException e) { -			e.printStackTrace(); -		} catch (KeyChainException e) { -			OpenVPN.logMessage(0,"",context.getString(R.string.keychain_access)); -		} -		return false; -	} -	private Certificate getCacertFromFile() throws FileNotFoundException, CertificateException { -		 CertificateFactory certFact = CertificateFactory.getInstance("X.509"); -		  -		 InputStream inStream; -		 -		 if(mCaFilename.startsWith(INLINE_TAG)) -			 inStream = new ByteArrayInputStream(mCaFilename.replace(INLINE_TAG,"").getBytes()); -		else  -			inStream = new FileInputStream(mCaFilename); -		  -		 return certFact.generateCertificate(inStream); -	} - - -	//! Return an error if somethign is wrong -	public int checkProfile(Context context) { -/*		if(mAuthenticationType==TYPE_KEYSTORE || mAuthenticationType==TYPE_USERPASS_KEYSTORE) { -			if(mAlias==null)  -				return R.string.no_keystore_cert_selected; -		}*/ - -		if(!mUsePull) { -			if(mIPv4Address == null || cidrToIPAndNetmask(mIPv4Address) == null) -				return R.string.ipv4_format_error; -		} -		if(isUserPWAuth() && !nonNull(mUsername)) { -			return R.string.error_empty_username; -		} -		if(!mUseDefaultRoute && getCustomRoutes()==null) -			return R.string.custom_route_format_error; - -		// Everything okay -		return R.string.no_error_found; - -	} - -	//! Openvpn asks for a "Private Key", this should be pkcs12 key -	// -	public String getPasswordPrivateKey() { -		if(mTransientPCKS12PW!=null) { -			String pwcopy = mTransientPCKS12PW; -			mTransientPCKS12PW=null; -			return pwcopy; -		} -		switch (mAuthenticationType) { -		case TYPE_PKCS12: -		case TYPE_USERPASS_PKCS12: -			return mPKCS12Password; - -		case TYPE_CERTIFICATES: -		case TYPE_USERPASS_CERTIFICATES: -			return mKeyPassword; - -		case TYPE_USERPASS: -		case TYPE_STATICKEYS: -		default: -			return null; -		} -	} -	private boolean isUserPWAuth() { -		switch(mAuthenticationType) { -		case TYPE_USERPASS: -		case TYPE_USERPASS_CERTIFICATES: -		case TYPE_USERPASS_KEYSTORE: -		case TYPE_USERPASS_PKCS12: -			return true; -		default: -			return false; - -		} -	} - - -	public boolean requireTLSKeyPassword() { -		if(!nonNull(mClientKeyFilename)) -			return false; - -		String data = ""; -		if(mClientKeyFilename.startsWith(INLINE_TAG)) -			data = mClientKeyFilename; -		else { -			char[] buf = new char[2048]; -			FileReader fr; -			try { -				fr = new FileReader(mClientKeyFilename); -				int len = fr.read(buf); -				while(len > 0 ) { -					data += new String(buf,0,len); -					len = fr.read(buf); -				} -				fr.close(); -			} catch (FileNotFoundException e) { -				return false; -			} catch (IOException e) { -				return false; -			} - -		} -		 -		if(data.contains("Proc-Type: 4,ENCRYPTED")) -			return true; -		else if(data.contains("-----BEGIN ENCRYPTED PRIVATE KEY-----")) -			return true; -		else -			return false; -	} - -	public int needUserPWInput() { -		if((mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12)&& -				(mPKCS12Password == null || mPKCS12Password.equals(""))) { -			if(mTransientPCKS12PW==null) -				return R.string.pkcs12_file_encryption_key; -		} -		 -		if(mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) { -			if(requireTLSKeyPassword() && !nonNull(mKeyPassword)) -				if(mTransientPCKS12PW==null) { -					return R.string.private_key_password; -				} -		} -		 -		if(isUserPWAuth() && (mPassword.equals("") || mPassword == null)) { -			if(mTransientPW==null) -				return R.string.password; - -		} -		return 0; -	} - -	public String getPasswordAuth() { -		if(mTransientPW!=null) { -			String pwcopy = mTransientPW; -			mTransientPW=null; -			return pwcopy; -		} else { -			return mPassword; -		} -	} - - -	// Used by the Array Adapter -	@Override -	public String toString() { -		return mName; -	} - - -	public String getUUIDString() { -		return mUuid.toString(); -	} - - -	public PrivateKey getKeystoreKey() { -		return mPrivateKey; -	} - - -	 -} - - - -  | 
