Loading packages/VpnServices/src/com/android/server/vpn/OpenvpnService.java +335 −313 Original line number Diff line number Diff line Loading @@ -33,10 +33,15 @@ import android.util.Log; */ class OpenvpnService extends VpnService<OpenvpnProfile> { private static final String OPENVPN_DAEMON = "openvpn"; private static final String MTPD = "mtpd"; private static final String USE_INLINE = "[[INLINE]]"; private static final String USE_KEYSTORE = "[[ANDROID]]"; private static final String TAG = OpenvpnService.class.getSimpleName(); private static int count = 0; private final String socketName = OPENVPN_DAEMON + getCount(); Loading @@ -44,6 +49,7 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { private transient OpenvpnThread thread = null; private transient String mPassword; private transient String mUsername; private synchronized static String getCount() { Loading @@ -51,8 +57,7 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { } @Override protected void connect(String serverIp, String username, String password) throws IOException { protected void connect(String serverIp, String username, String password) throws IOException { OpenvpnProfile p = getProfile(); ArrayList<String> args = new ArrayList<String>(); Loading @@ -60,22 +65,34 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { mPassword = password; args.add(OPENVPN_DAEMON); args.add("--dev"); args.add("tun"); args.add("--remote"); args.add(serverIp); args.add("--dev"); args.add("tun"); args.add("--remote"); args.add(serverIp); args.add("--nobind"); args.add("--proto"); args.add(p.getProto()); args.add("--proto"); args.add(p.getProto()); args.add("--client"); args.add("--rport"); args.add(p.getPort()); args.add("--rport"); args.add(p.getPort()); if (p.getCAName() != null) { args.add("--ca"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.CA_CERTIFICATE + p.getCAName()); args.add("--ca"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.CA_CERTIFICATE + p.getCAName()); } if (p.getCertName() != null) { args.add("--cert"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_CERTIFICATE + p.getCertName()); args.add("--key"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_PRIVATE_KEY + p.getCertName()); args.add("--cert"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_CERTIFICATE + p.getCertName()); args.add("--key"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_PRIVATE_KEY + p.getCertName()); } args.add("--persist-tun"); args.add("--persist-key"); args.add("--management"); args.add("/dev/socket/" + socketName); args.add("unix"); args.add("--management"); args.add("/dev/socket/" + socketName); args.add("unix"); args.add("--management-hold"); if (p.getUseCompLzo()) { args.add("--comp-lzo"); Loading @@ -85,10 +102,12 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { args.add("--management-query-passwords"); } if (p.getSupplyAddr()) { args.add("--ifconfig"); args.add(p.getLocalAddr()); args.add(p.getRemoteAddr()); args.add("--ifconfig"); args.add(p.getLocalAddr()); args.add(p.getRemoteAddr()); } DaemonProxy mtpd = new VpnDaemons().startDaemon(MTPD); DaemonProxy mtpd = getDaemons().startDaemon(MTPD); mtpd.sendCommand(args.toArray(new String[args.size()])); } Loading Loading @@ -117,22 +136,31 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { } void startConnectivityMonitor() { /* Openvpn is completely event driven, so we don't need * a polling monitor at all, so do nothing here */ /* * Openvpn is completely event driven, so we don't need a polling * monitor at all, so do nothing here */ } private class OpenvpnThread extends Thread { InputStream in; OutputStream out; LocalSocket mSocket; boolean finalDisconnect = false; boolean firstConnect = false; boolean disconnecting = false; boolean passwordError = false; boolean SFbool; volatile String SFreason; String vpnState = "WAIT"; // initial state OpenvpnThread() throws IOException { Loading Loading @@ -222,7 +250,6 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { this.notifyAll(); } private synchronized void sendAsync(String str) throws IOException { str += "\n"; out.write(str.getBytes()); Loading @@ -245,23 +272,15 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { String state = s.substring(first + 1, second); /* * state can be: * * * CONNECTING -- OpenVPN's initial state. * WAIT -- (Client only) Waiting for initial response * from server. * AUTH -- (Client only) Authenticating with server. * GET_CONFIG -- (Client only) Downloading configuration options * from server. * ASSIGN_IP -- Assigning IP address to virtual network * interface. * ADD_ROUTES -- Adding routes to system. * CONNECTED -- Initialization Sequence Completed. * RECONNECTING -- A restart has occurred. * EXITING -- A graceful exit is in progress. * * Really all we care about is connected or not * state can be: CONNECTING -- OpenVPN's initial state. WAIT -- * (Client only) Waiting for initial response from server. AUTH -- * (Client only) Authenticating with server. GET_CONFIG -- (Client * only) Downloading configuration options from server. ASSIGN_IP -- * Assigning IP address to virtual network interface. ADD_ROUTES -- * Adding routes to system. CONNECTED -- Initialization Sequence * Completed. RECONNECTING -- A restart has occurred. EXITING -- A * graceful exit is in progress. Really all we care about is * connected or not */ vpnState = state; this.notifyAll(); Loading @@ -270,23 +289,26 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { } private synchronized void signalPassword(String s) throws IOException { /* message should be Need '<auth type>' password * but coult be Verification Failed: '<auth type' /* * message should be Need '<auth type>' password but coult be * Verification Failed: '<auth type' */ int first = s.indexOf('\''); int second = s.indexOf('\'', first + 1); final String authType = s.substring(first + 1, second); /* AuthType can be one of * * "Auth" - regular client server authentication * "Private Key" - password for private key (unimplemented) /* * AuthType can be one of "Auth" - regular client server * authentication "Private Key" - password for private key * (unimplemented) */ if (s.startsWith("Need")) { /* we're in the processor thread, so we have to send * these asynchronously to avoid a deadlock */ /* * we're in the processor thread, so we have to send these * asynchronously to avoid a deadlock */ sendAsync("username '" + authType + "' '" + mUsername + "'"); sendAsync("password '" + authType + "' '" + mPassword + "'"); } else { Loading Loading
packages/VpnServices/src/com/android/server/vpn/OpenvpnService.java +335 −313 Original line number Diff line number Diff line Loading @@ -33,10 +33,15 @@ import android.util.Log; */ class OpenvpnService extends VpnService<OpenvpnProfile> { private static final String OPENVPN_DAEMON = "openvpn"; private static final String MTPD = "mtpd"; private static final String USE_INLINE = "[[INLINE]]"; private static final String USE_KEYSTORE = "[[ANDROID]]"; private static final String TAG = OpenvpnService.class.getSimpleName(); private static int count = 0; private final String socketName = OPENVPN_DAEMON + getCount(); Loading @@ -44,6 +49,7 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { private transient OpenvpnThread thread = null; private transient String mPassword; private transient String mUsername; private synchronized static String getCount() { Loading @@ -51,8 +57,7 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { } @Override protected void connect(String serverIp, String username, String password) throws IOException { protected void connect(String serverIp, String username, String password) throws IOException { OpenvpnProfile p = getProfile(); ArrayList<String> args = new ArrayList<String>(); Loading @@ -60,22 +65,34 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { mPassword = password; args.add(OPENVPN_DAEMON); args.add("--dev"); args.add("tun"); args.add("--remote"); args.add(serverIp); args.add("--dev"); args.add("tun"); args.add("--remote"); args.add(serverIp); args.add("--nobind"); args.add("--proto"); args.add(p.getProto()); args.add("--proto"); args.add(p.getProto()); args.add("--client"); args.add("--rport"); args.add(p.getPort()); args.add("--rport"); args.add(p.getPort()); if (p.getCAName() != null) { args.add("--ca"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.CA_CERTIFICATE + p.getCAName()); args.add("--ca"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.CA_CERTIFICATE + p.getCAName()); } if (p.getCertName() != null) { args.add("--cert"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_CERTIFICATE + p.getCertName()); args.add("--key"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_PRIVATE_KEY + p.getCertName()); args.add("--cert"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_CERTIFICATE + p.getCertName()); args.add("--key"); args.add(USE_INLINE); args.add(USE_KEYSTORE + Credentials.USER_PRIVATE_KEY + p.getCertName()); } args.add("--persist-tun"); args.add("--persist-key"); args.add("--management"); args.add("/dev/socket/" + socketName); args.add("unix"); args.add("--management"); args.add("/dev/socket/" + socketName); args.add("unix"); args.add("--management-hold"); if (p.getUseCompLzo()) { args.add("--comp-lzo"); Loading @@ -85,10 +102,12 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { args.add("--management-query-passwords"); } if (p.getSupplyAddr()) { args.add("--ifconfig"); args.add(p.getLocalAddr()); args.add(p.getRemoteAddr()); args.add("--ifconfig"); args.add(p.getLocalAddr()); args.add(p.getRemoteAddr()); } DaemonProxy mtpd = new VpnDaemons().startDaemon(MTPD); DaemonProxy mtpd = getDaemons().startDaemon(MTPD); mtpd.sendCommand(args.toArray(new String[args.size()])); } Loading Loading @@ -117,22 +136,31 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { } void startConnectivityMonitor() { /* Openvpn is completely event driven, so we don't need * a polling monitor at all, so do nothing here */ /* * Openvpn is completely event driven, so we don't need a polling * monitor at all, so do nothing here */ } private class OpenvpnThread extends Thread { InputStream in; OutputStream out; LocalSocket mSocket; boolean finalDisconnect = false; boolean firstConnect = false; boolean disconnecting = false; boolean passwordError = false; boolean SFbool; volatile String SFreason; String vpnState = "WAIT"; // initial state OpenvpnThread() throws IOException { Loading Loading @@ -222,7 +250,6 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { this.notifyAll(); } private synchronized void sendAsync(String str) throws IOException { str += "\n"; out.write(str.getBytes()); Loading @@ -245,23 +272,15 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { String state = s.substring(first + 1, second); /* * state can be: * * * CONNECTING -- OpenVPN's initial state. * WAIT -- (Client only) Waiting for initial response * from server. * AUTH -- (Client only) Authenticating with server. * GET_CONFIG -- (Client only) Downloading configuration options * from server. * ASSIGN_IP -- Assigning IP address to virtual network * interface. * ADD_ROUTES -- Adding routes to system. * CONNECTED -- Initialization Sequence Completed. * RECONNECTING -- A restart has occurred. * EXITING -- A graceful exit is in progress. * * Really all we care about is connected or not * state can be: CONNECTING -- OpenVPN's initial state. WAIT -- * (Client only) Waiting for initial response from server. AUTH -- * (Client only) Authenticating with server. GET_CONFIG -- (Client * only) Downloading configuration options from server. ASSIGN_IP -- * Assigning IP address to virtual network interface. ADD_ROUTES -- * Adding routes to system. CONNECTED -- Initialization Sequence * Completed. RECONNECTING -- A restart has occurred. EXITING -- A * graceful exit is in progress. Really all we care about is * connected or not */ vpnState = state; this.notifyAll(); Loading @@ -270,23 +289,26 @@ class OpenvpnService extends VpnService<OpenvpnProfile> { } private synchronized void signalPassword(String s) throws IOException { /* message should be Need '<auth type>' password * but coult be Verification Failed: '<auth type' /* * message should be Need '<auth type>' password but coult be * Verification Failed: '<auth type' */ int first = s.indexOf('\''); int second = s.indexOf('\'', first + 1); final String authType = s.substring(first + 1, second); /* AuthType can be one of * * "Auth" - regular client server authentication * "Private Key" - password for private key (unimplemented) /* * AuthType can be one of "Auth" - regular client server * authentication "Private Key" - password for private key * (unimplemented) */ if (s.startsWith("Need")) { /* we're in the processor thread, so we have to send * these asynchronously to avoid a deadlock */ /* * we're in the processor thread, so we have to send these * asynchronously to avoid a deadlock */ sendAsync("username '" + authType + "' '" + mUsername + "'"); sendAsync("password '" + authType + "' '" + mPassword + "'"); } else { Loading