- when running crosstap script, if the host does not exist in known_hosts, the 
interface blocks until the user enters "yes" or "no" in Eclipse console
- in order to prevent this, we try to connect to the host beforehand printing 
all the debug messages and wait  to see if there was a key found
  - if there was no key found, a message dialog is shown to the user asking to 
confirm adding this new host to known_host.
    - if approved - we run "ssh -o StrictHostKeyChecking=no" which does not 
require any input from the user and automatically adds the host & proceed to 
running crosstap command
    - if the user does not approve -> message is displayed that authentication 
failed
  - if there was at least one key found
    - parse the debug messages further to see if the keys match
          - message "Authentication succeeded" is encountered -> proceed to 
running crosstap command
          - authentication failed due to change in keys -> collect error 
message and display it to the user

[Yocto #4307]
Signed-off-by: Ioana Grigoropol <ioanax.grigoro...@intel.com>
---
 .../org/yocto/sdk/remotetools/ShellSession.java    |   89 ++++++++++++++++++++
 .../sdk/remotetools/actions/SystemtapModel.java    |   17 ++--
 2 files changed, 98 insertions(+), 8 deletions(-)

diff --git 
a/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/ShellSession.java
 
b/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/ShellSession.java
index bd1cb38..5602798 100644
--- 
a/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/ShellSession.java
+++ 
b/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/ShellSession.java
@@ -19,6 +19,10 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.lang.reflect.InvocationTargetException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.dialogs.MessageDialog;
 
 public class ShellSession {
        /**
@@ -213,6 +217,91 @@ public class ShellSession {
                        interrupt = false;
                }
        }
+       synchronized
+       public boolean ensureKnownHostKey(String user, String host) throws 
IOException {
+
+               boolean loadKeysMatch = false;
+               boolean accepted = false;
+               Process proc = Runtime.getRuntime().exec("ssh -o 
LogLevel=DEBUG3 " + user + "@" + host);
+               Pattern patternLoad = Pattern.compile("^debug3: load_hostkeys: 
loaded (\\d+) keys");
+               Pattern patternAuthSucceeded = Pattern.compile("^debug1: 
Authentication succeeded.*");
+
+               try {
+                       InputStream es = proc.getErrorStream();
+                       String info;
+                       while (!loadKeysMatch) {
+                               info = null;
+                               StringBuffer buffer = new StringBuffer();
+                               int c;
+                               while (es.available() > 0) {
+                                       c = es.read();
+                                       char ch = (char) c;
+                                       buffer.append(ch);
+                                       if (ch == '\r') {
+                                               info = buffer.toString().trim();
+                                               Matcher m = 
patternLoad.matcher(info);
+                                               if(m.matches()) {
+                                                       int keys = new 
Integer(m.group(1));
+                                                       if (keys == 0) {
+                                                               proc.destroy();
+                                                               accepted = 
MessageDialog.openQuestion(null, "Host authenticity", "The authenticity of host 
'" + host + "(" + host + ")' can't be established.\nAre you sure you want to 
continue connecting ?");
+                                                               if (accepted){
+                                                                       proc = 
Runtime.getRuntime().exec("ssh -o StrictHostKeyChecking=no " + user + "@" + 
host);//add host key to known_hosts
+                                                                       try {
+                                                                               
Thread.sleep(2000); //wait for process to finish
+                                                                       } catch 
(InterruptedException e) {
+                                                                               
e.printStackTrace();
+                                                                       }
+                                                                       
proc.destroy();
+                                                               } else {
+                                                                       
MessageDialog.openError(null, "Host authenticity", "Host key verification 
failed.");
+                                                               }
+                                                       } else {
+                                                               String errorMsg 
= "";
+                                                               // wait to 
check if key is the same and authentication succeeds
+                                                               while 
(es.available() > 0) {
+                                                                       c = 
es.read();
+                                                                       ch = 
(char) c;
+                                                                       
buffer.append(ch);
+                                                                       if (ch 
== '\r') {
+                                                                               
info = buffer.toString().trim();
+                                                                               
Matcher mAuthS = patternAuthSucceeded.matcher(info);
+                                                                               
if(mAuthS.matches()) {
+                                                                               
        accepted = true;
+                                                                               
        break;
+                                                                               
} else {
+                                                                               
        if (!info.startsWith("debug"))
+                                                                               
                errorMsg += info + "\n";
+                                                                               
}
+                                                                               
try {
+                                                                               
        Thread.sleep(100);
+                                                                               
} catch (InterruptedException e) {
+                                                                               
        // TODO Auto-generated catch block
+                                                                               
        e.printStackTrace();
+                                                                               
}
+                                                                               
buffer.delete(0, buffer.length());
+                                                                       }
+                                                               }
+                                                               if (!accepted 
&& !errorMsg.isEmpty())
+                                                                       
MessageDialog.openError(null, "Host authenticity", errorMsg);
+                                                       }
+                                                       loadKeysMatch = true;
+                                                       break;
+                                               }
+                                               buffer.delete(0, 
buffer.length());
+                                       }
+                               }
+                       }
+                       es.close();
+               } catch (IOException e) {
+                       try {
+                               throw new InvocationTargetException(e);
+                       } catch (InvocationTargetException e1) {
+                               e1.printStackTrace();
+                       }
+               }
+               return accepted;
+       }
        
        private void clearErrorStream(InputStream is) {
        
diff --git 
a/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/actions/SystemtapModel.java
 
b/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/actions/SystemtapModel.java
index 79f2dd1..0d22d97 100644
--- 
a/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/actions/SystemtapModel.java
+++ 
b/plugins/org.yocto.sdk.remotetools/src/org/yocto/sdk/remotetools/actions/SystemtapModel.java
@@ -10,8 +10,8 @@
  
*******************************************************************************/
 package org.yocto.sdk.remotetools.actions;
 
-import java.lang.reflect.InvocationTargetException;
 import java.io.File;
+import java.lang.reflect.InvocationTargetException;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.swt.widgets.Display;
@@ -19,7 +19,6 @@ import org.eclipse.ui.console.ConsolePlugin;
 import org.eclipse.ui.console.IConsole;
 import org.eclipse.ui.console.IConsoleManager;
 import org.eclipse.ui.console.MessageConsole;
-
 import org.yocto.sdk.remotetools.ShellSession;
 
 public class SystemtapModel extends BaseModel {
@@ -64,18 +63,20 @@ public class SystemtapModel extends BaseModel {
        public void preProcess(IProgressMonitor monitor)
                        throws InvocationTargetException, InterruptedException {
        }
-
+    
        public void process(IProgressMonitor monitor)
        throws InvocationTargetException, InterruptedException {
                try {
                        ShellSession shell = new 
ShellSession(ShellSession.SHELL_TYPE_BASH, 
                                                                                
                new File(this.metadata_location),
                                                                                
                DEFAULT_INIT_SCRIPT, sessionConsole.newOutputStream());
-                       String crosstapCmd = "crosstap " + user_id + "@" + 
remote_host + " " + systemtap_script;
-                       if (systemtap_args != null)
-                               crosstapCmd = crosstapCmd + " " + 
systemtap_args;
-                       shell.execute(crosstapCmd);
-                                                                       
+                       boolean acceptedKey = shell.ensureKnownHostKey(user_id, 
remote_host);
+                       if (acceptedKey) {
+                               String crosstapCmd = "crosstap " + user_id + 
"@" + remote_host + " " + systemtap_script;
+                               if (systemtap_args != null)
+                                       crosstapCmd = crosstapCmd + " " + 
systemtap_args;
+                               shell.execute(crosstapCmd);
+                       }
                } catch (Exception e) {
                        throw new InvocationTargetException(e,e.getMessage());
                }
-- 
1.7.9.5

_______________________________________________
yocto mailing list
yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/yocto

Reply via email to