diff options
author | Arne Schwabe <arne@rfc2549.org> | 2014-07-16 11:06:48 +0200 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2014-07-16 11:06:48 +0200 |
commit | 31c067e6a494d020bff0cf4c6ce9f2d63591a400 (patch) | |
tree | fe7626f636301f45f3c7aa792f81880b198142d3 /main/src | |
parent | 67e09d168a5ffaf98e3e72edd9001573c3d65db3 (diff) |
reformat, fix concurrency
--HG--
rename : main/src/main/java/de/blinkt/openvpn/fragments/Settings_Behaviour.java => main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java
extra : rebase_source : c7be2fcfcfc9f049246e305e65cd9a0f6f62eff5
Diffstat (limited to 'main/src')
-rw-r--r-- | main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java | 784 |
1 files changed, 394 insertions, 390 deletions
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 03f52e22..d10f7e17 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -33,49 +33,50 @@ import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
- private static final String TAG = "openvpn";
- private LocalSocket mSocket;
- private VpnProfile mProfile;
- private OpenVpnService mOpenVPNService;
- private LinkedList<FileDescriptor> mFDList=new LinkedList<FileDescriptor>();
+ private static final String TAG = "openvpn";
+ private LocalSocket mSocket;
+ private VpnProfile mProfile;
+ private OpenVpnService mOpenVPNService;
+ private LinkedList<FileDescriptor> mFDList = new LinkedList<FileDescriptor>();
private LocalServerSocket mServerSocket;
- private boolean mReleaseHold=true;
- private boolean mWaitingForRelease=false;
- private long mLastHoldRelease=0;
+ private boolean mReleaseHold = true;
+ private boolean mWaitingForRelease = false;
+ private long mLastHoldRelease = 0;
- private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
+ private static Vector<OpenVpnManagementThread> active = new Vector<OpenVpnManagementThread>();
private LocalSocket mServerSocketLocal;
private pauseReason lastPauseReason = pauseReason.noNetwork;
public OpenVpnManagementThread(VpnProfile profile, OpenVpnService openVpnService) {
- mProfile = profile;
- mOpenVPNService = openVpnService;
-
+ mProfile = profile;
+ mOpenVPNService = openVpnService;
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(openVpnService);
- boolean managemeNetworkState = prefs.getBoolean("netchangereconnect", true);
- if(managemeNetworkState)
- mReleaseHold=false;
- }
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(openVpnService);
+ boolean managemeNetworkState = prefs.getBoolean("netchangereconnect", true);
+ if (managemeNetworkState)
+ mReleaseHold = false;
+
+ }
public boolean openManagementInterface(@NotNull Context c) {
// Could take a while to open connection
- int tries=8;
+ int tries = 8;
- String socketName = (c.getCacheDir().getAbsolutePath() + "/" + "mgmtsocket");
+ String socketName = (c.getCacheDir().getAbsolutePath() + "/" + "mgmtsocket");
// The mServerSocketLocal is transferred to the LocalServerSocket, ignore warning
mServerSocketLocal = new LocalSocket();
- while(tries > 0 && !mServerSocketLocal.isConnected()) {
+ while (tries > 0 && !mServerSocketLocal.isConnected()) {
try {
mServerSocketLocal.bind(new LocalSocketAddress(socketName,
LocalSocketAddress.Namespace.FILESYSTEM));
} catch (IOException e) {
// wait 300 ms before retrying
- try { Thread.sleep(300);
+ try {
+ Thread.sleep(300);
} catch (InterruptedException e1) {
}
@@ -95,165 +96,168 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { }
- public void managmentCommand(String cmd) {
+ public void managmentCommand(String cmd) {
try {
- if(mSocket!=null && mSocket.getOutputStream() !=null) {
- mSocket.getOutputStream().write(cmd.getBytes());
- mSocket.getOutputStream().flush();
- }
- }catch (IOException e) {
- // Ignore socket stack traces
+ if (mSocket != null && mSocket.getOutputStream() != null) {
+ mSocket.getOutputStream().write(cmd.getBytes());
+ mSocket.getOutputStream().flush();
+ }
+ } catch (IOException e) {
+ // Ignore socket stack traces
}
- }
+ }
- @Override
- public void run() {
- byte [] buffer =new byte[2048];
- // mSocket.setSoTimeout(5); // Setting a timeout cannot be that bad
+ @Override
+ public void run() {
+ byte[] buffer = new byte[2048];
+ // mSocket.setSoTimeout(5); // Setting a timeout cannot be that bad
- String pendingInput="";
- active.add(this);
+ String pendingInput = "";
+ synchronized (active) {
+ active.add(this);
+ }
- try {
- // Wait for a client to connect
- mSocket= mServerSocket.accept();
- InputStream instream = mSocket.getInputStream();
+ try {
+ // Wait for a client to connect
+ mSocket = mServerSocket.accept();
+ InputStream instream = mSocket.getInputStream();
// Close the management socket after client connected
mServerSocket.close();
// Closing one of the two sockets also closes the other
//mServerSocketLocal.close();
- while(true) {
- int numbytesread = instream.read(buffer);
- if(numbytesread==-1)
- return;
-
- FileDescriptor[] fds = null;
- try {
- fds = mSocket.getAncillaryFileDescriptors();
- } catch (IOException e) {
- VpnStatus.logException("Error reading fds from socket", e);
- }
- if(fds!=null){
- Collections.addAll(mFDList, fds);
- }
+ while (true) {
+ int numbytesread = instream.read(buffer);
+ if (numbytesread == -1)
+ return;
- String input = new String(buffer,0,numbytesread,"UTF-8");
+ FileDescriptor[] fds = null;
+ try {
+ fds = mSocket.getAncillaryFileDescriptors();
+ } catch (IOException e) {
+ VpnStatus.logException("Error reading fds from socket", e);
+ }
+ if (fds != null) {
+ Collections.addAll(mFDList, fds);
+ }
- pendingInput += input;
+ String input = new String(buffer, 0, numbytesread, "UTF-8");
- pendingInput=processInput(pendingInput);
+ pendingInput += input;
+ pendingInput = processInput(pendingInput);
- }
- } catch (IOException e) {
+ }
+ } catch (IOException e) {
if (!e.getMessage().equals("socket closed"))
VpnStatus.logException(e);
- }
- active.remove(this);
- }
+ }
+ synchronized (active) {
+ active.remove(this);
+ }
+ }
- //! Hack O Rama 2000!
- private void protectFileDescriptor(FileDescriptor fd) {
- Exception exp;
- try {
- Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
- int fdint = (Integer) getInt.invoke(fd);
+ //! Hack O Rama 2000!
+ private void protectFileDescriptor(FileDescriptor fd) {
+ Exception exp;
+ 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 :)
+ // You can even get more evil by parsing toString() and extract the int from that :)
- boolean result = mOpenVPNService.protect(fdint);
+ boolean result = mOpenVPNService.protect(fdint);
if (!result)
VpnStatus.logWarning("Could not protect VPN socket");
- //ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
- //pfd.close();
- NativeUtils.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;
- }
+ //ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
+ //pfd.close();
+ NativeUtils.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;
+ }
Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd);
- VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")" , exp);
- }
+ VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")", exp);
+ }
- private String processInput(String pendingInput) {
+ 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;
- }
+ 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) {
+ private void processCommand(String command) {
//Log.i(TAG, "Line from managment" + command);
if (command.startsWith(">") && command.contains(":")) {
- String[] parts = command.split(":",2);
- String cmd = parts[0].substring(1);
- String argument = parts[1];
+ String[] parts = command.split(":", 2);
+ String cmd = parts[0].substring(1);
+ String argument = parts[1];
- if(cmd.equals("INFO")) {
- /* Ignore greeting from management */
+ if (cmd.equals("INFO")) {
+ /* Ignore greeting from management */
return;
- }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("PROXY")) {
- processProxyCMD(argument);
- } else if (cmd.equals("LOG")) {
- processLogMessage(argument);
- } else if (cmd.equals("RSA_SIGN")) {
- processSignCommand(argument);
- } else {
- VpnStatus.logWarning("MGMT: Got unrecognized command" + command);
- Log.i(TAG, "Got unrecognized command" + command);
- }
- } else if (command.startsWith("SUCCESS:")) {
+ } 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("PROXY")) {
+ processProxyCMD(argument);
+ } else if (cmd.equals("LOG")) {
+ processLogMessage(argument);
+ } else if (cmd.equals("RSA_SIGN")) {
+ processSignCommand(argument);
+ } else {
+ VpnStatus.logWarning("MGMT: Got unrecognized command" + command);
+ Log.i(TAG, "Got unrecognized command" + command);
+ }
+ } else if (command.startsWith("SUCCESS:")) {
/* Ignore this kind of message too */
return;
} else if (command.startsWith("PROTECTFD: ")) {
FileDescriptor fdtoprotect = mFDList.pollFirst();
- if (fdtoprotect!=null)
+ if (fdtoprotect != null)
protectFileDescriptor(fdtoprotect);
- } else {
- Log.i(TAG, "Got unrecognized line from managment" + command);
- VpnStatus.logWarning("MGMT: Got unrecognized line from management:" + command);
- }
- }
+ } else {
+ Log.i(TAG, "Got unrecognized line from managment" + command);
+ VpnStatus.logWarning("MGMT: Got unrecognized line from management:" + command);
+ }
+ }
private void processLogMessage(String argument) {
- String[] args = argument.split(",",4);
+ String[] args = argument.split(",", 4);
// 0 unix time stamp
// 1 log level N,I,E etc.
/*
@@ -287,109 +291,110 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { if (msg.startsWith("MANAGEMENT: CMD"))
ovpnlevel = Math.max(4, ovpnlevel);
- VpnStatus.logMessageOpenVPN(level,ovpnlevel, msg);
+ VpnStatus.logMessageOpenVPN(level, ovpnlevel, msg);
}
private void handleHold() {
- if(mReleaseHold) {
- releaseHoldCmd();
- } else {
- mWaitingForRelease=true;
+ if (mReleaseHold) {
+ releaseHoldCmd();
+ } else {
+ mWaitingForRelease = true;
VpnStatus.updateStatePause(lastPauseReason);
- }
- }
- private void releaseHoldCmd() {
- if ((System.currentTimeMillis()- mLastHoldRelease) < 5000) {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
+ }
+ }
+
+ 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");
+
+ }
+ mWaitingForRelease = false;
+ mLastHoldRelease = System.currentTimeMillis();
+ managmentCommand("hold release\n");
+ managmentCommand("bytecount " + mBytecountInterval + "\n");
managmentCommand("state on\n");
//managmentCommand("log on all\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;
-
- VpnStatus.logInfo(R.string.using_proxy, isa.getHostName(), isa.getPort());
-
- String proxycmd = String.format(Locale.ENGLISH,"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(",,"))
- VpnStatus.updateStateString(currentstate, "");
- else
- VpnStatus.updateStateString(currentstate, args[2]);
- }
-
-
- 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));
-
- VpnStatus.updateByteCount(in, out);
-
- }
-
-
-
- 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(" ");
+ }
+
+ 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;
+
+ VpnStatus.logInfo(R.string.using_proxy, isa.getHostName(), isa.getPort());
+
+ String proxycmd = String.format(Locale.ENGLISH, "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(",,"))
+ VpnStatus.updateStateString(currentstate, "");
+ else
+ VpnStatus.updateStateString(currentstate, args[2]);
+ }
+
+
+ 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));
+
+ VpnStatus.updateByteCount(in, out);
+
+ }
+
+
+ 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(" ");
/*
buf_printf (&out, "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
@@ -397,209 +402,208 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { buf_printf (&out, "%s %s %s", network, netmask, gateway);
*/
- if(routeparts.length==5) {
+ if (routeparts.length == 5) {
if (BuildConfig.DEBUG) Assert.assertEquals("dev", routeparts[3]);
mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]);
- } else if (routeparts.length >= 3) {
+ } else if (routeparts.length >= 3) {
mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null);
} else {
VpnStatus.logError("Unrecognized ROUTE cmd:" + Arrays.toString(routeparts) + " | " + argument);
}
- } else if (needed.equals("ROUTE6")) {
+ } else if (needed.equals("ROUTE6")) {
String[] routeparts = extra.split(" ");
- mOpenVPNService.addRoutev6(routeparts[0],routeparts[1]);
- } 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("PERSIST_TUN_ACTION")) {
+ mOpenVPNService.addRoutev6(routeparts[0], routeparts[1]);
+ } 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("PERSIST_TUN_ACTION")) {
// check if tun cfg stayed the same
status = mOpenVPNService.getTunReopenStatus();
} 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;
- if(!extra.equals("tun")) {
- // We only support tun
- VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!",extra));
-
- 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);
-
- // 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;
- }
- VpnStatus.logException("Could not send fd over socket" , exp);
+ 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;
+ if (!extra.equals("tun")) {
+ // We only support tun
+ VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra));
+
+ 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);
+
+ // 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;
+ }
+ VpnStatus.logException("Could not send fd over socket", exp);
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) {
- VpnStatus.logError("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 {
- VpnStatus.logError(String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed));
- }
-
- }
-
-
-
-
- private void proccessPWFailed(String needed, String args) {
- VpnStatus.updateStateString("AUTH_FAILED", needed + args, R.string.state_auth_failed, ConnectionStatus.LEVEL_AUTH_FAILED);
- }
-
-
- private 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;
- }
+ }
+
+ 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) {
+ VpnStatus.logError("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 {
+ VpnStatus.logError(String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed));
+ }
+
+ }
+
+
+ private void proccessPWFailed(String needed, String args) {
+ VpnStatus.updateStateString("AUTH_FAILED", needed + args, R.string.state_auth_failed, ConnectionStatus.LEVEL_AUTH_FAILED);
+ }
+
+
+ private static boolean stopOpenVPN() {
+ synchronized (active) {
+ 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;
+ }
@Override
public void networkChange() {
- if(!mWaitingForRelease)
+ if (!mWaitingForRelease)
managmentCommand("network-change\n");
}
- public void signalusr1() {
- mReleaseHold=false;
+ public void signalusr1() {
+ mReleaseHold = false;
- if(!mWaitingForRelease)
- managmentCommand("signal SIGUSR1\n");
+ if (!mWaitingForRelease)
+ managmentCommand("signal SIGUSR1\n");
else
// If signalusr1 is called update the state string
// if there is another for stopping
VpnStatus.updateStatePause(lastPauseReason);
- }
+ }
- public void reconnect() {
- signalusr1();
- releaseHold();
- }
+ public void reconnect() {
+ signalusr1();
+ releaseHold();
+ }
- private void processSignCommand(String b64data) {
+ private void processSignCommand(String b64data) {
- String signed_string = mProfile.getSignedData(b64data);
- if(signed_string==null) {
+ String signed_string = mProfile.getSignedData(b64data);
+ if (signed_string == null) {
managmentCommand("rsa-sig\n");
managmentCommand("\nEND\n");
stopOpenVPN();
return;
}
managmentCommand("rsa-sig\n");
- managmentCommand(signed_string);
+ managmentCommand(signed_string);
managmentCommand("\nEND\n");
- }
+ }
- @Override
- public void pause (pauseReason reason) {
+ @Override
+ public void pause(pauseReason reason) {
lastPauseReason = reason;
- signalusr1();
- }
+ signalusr1();
+ }
- @Override
- public void resume() {
- releaseHold();
+ @Override
+ public void resume() {
+ releaseHold();
/* Reset the reason why we are disconnected */
lastPauseReason = pauseReason.noNetwork;
- }
+ }
- @Override
- public boolean stopVPN() {
- return stopOpenVPN();
- }
+ @Override
+ public boolean stopVPN() {
+ return stopOpenVPN();
+ }
}
|