Beispiel #1
0
 /**
  * Start the application
  *
  * @throws IOException if there is a problem with connection
  * @throws InterruptedException if thread was interrupted
  */
 private void start() throws IOException, InterruptedException {
   Connection c = new Connection(myHost.getHostName(), myHost.getPort());
   try {
     configureKnownHosts(c);
     c.connect(new HostKeyVerifier());
     authenticate(c);
     final Session s = c.openSession();
     try {
       s.execCommand(myCommand);
       // Note that stdin is not being waited using semaphore.
       // Instead, the SSH process waits for remote process exit
       // if remote process exited, none is interested in stdin
       // anyway.
       forward("stdin", s.getStdin(), System.in, false);
       forward("stdout", System.out, s.getStdout(), true);
       forward("stderr", System.err, s.getStderr(), true);
       myForwardCompleted.acquire(2); // wait only for stderr and stdout
       s.waitForCondition(ChannelCondition.EXIT_STATUS, Long.MAX_VALUE);
       Integer exitStatus = s.getExitStatus();
       if (exitStatus == null) {
         // broken exit status
         exitStatus = 1;
       }
       System.exit(exitStatus.intValue() == 0 ? myExitCode : exitStatus.intValue());
     } finally {
       s.close();
     }
   } finally {
     c.close();
   }
 }
Beispiel #2
0
 /**
  * Try public key
  *
  * @param c a ssh connection
  * @param keyPath a path to key
  * @return true if authentication is successful
  */
 private boolean tryPublicKey(final Connection c, final String keyPath) {
   try {
     final File file = new File(keyPath);
     if (file.exists()) {
       // if encrypted ask user for passphrase
       String passphrase = null;
       char[] text = FileUtil.loadFileText(file);
       if (isEncryptedKey(text)) {
         // need to ask passphrase from user
         int i;
         for (i = myHost.getNumberOfPasswordPrompts(); i > 0; i--) {
           passphrase =
               myXmlRpcClient.askPassphrase(
                   myHandlerNo, getUserHostString(), keyPath, myLastError);
           if (passphrase == null) {
             // if no passphrase was entered, just return false and try something other
             return false;
           } else {
             try {
               PEMDecoder.decode(text, passphrase);
               myLastError = "";
             } catch (IOException e) {
               // decoding failed
               myLastError = GitBundle.message("sshmain.invalidpassphrase", keyPath);
               continue;
             }
             break;
           }
         }
         if (i == 0) {
           myLastError =
               GitBundle.message(
                   "sshmain.too.mush.passphrase.guesses",
                   keyPath,
                   myHost.getNumberOfPasswordPrompts());
           return false;
         }
       }
       // try authentication
       if (c.authenticateWithPublicKey(myHost.getUser(), text, passphrase)) {
         myLastError = "";
         return true;
       } else {
         if (passphrase != null) {
           // mark as failed authentication only if passphrase were asked
           myLastError = GitBundle.message("sshmain.pk.authenitication.failed", keyPath);
         } else {
           myLastError = "";
         }
       }
     }
     return false;
   } catch (Exception e) {
     return false;
   }
 }
Beispiel #3
0
 /**
  * A constructor
  *
  * @param xmlRpcPort a xml RPC port
  * @param host a host
  * @param username a name of user (from URL)
  * @param port a port
  * @param command a command
  * @throws IOException if config file could not be loaded
  */
 private SSHMain(final int xmlRpcPort, String host, String username, Integer port, String command)
     throws IOException {
   SSHConfig config = SSHConfig.load();
   myHost = config.lookup(username, host, port);
   myXmlRpcClient = new GitSSHIdeaClient(xmlRpcPort, myHost.isBatchMode());
   myHandlerNo = Integer.parseInt(System.getenv(GitSSHService.SSH_HANDLER_ENV));
   myCommand = command;
 }
Beispiel #4
0
 /**
  * Configure known host database for connection
  *
  * @param c a connection
  * @throws IOException if there is a IO problem
  */
 private void configureKnownHosts(Connection c) throws IOException {
   File knownHostFile = new File(knownHostPath);
   if (knownHostFile.exists()) {
     database.addHostkeys(knownHostFile);
   }
   final List<String> algorithms = myHost.getHostKeyAlgorithms();
   c.setServerHostKeyAlgorithms(algorithms.toArray(new String[algorithms.size()]));
 }
Beispiel #5
0
 /** @return user and host string */
 private String getUserHostString() {
   int port = myHost.getPort();
   return myHost.getUser() + "@" + myHost.getHostName() + (port == 22 ? "" : ":" + port);
 }
Beispiel #6
0
 /**
  * Authenticate using some supported methods. If authentication fails, the method throws {@link
  * IOException}.
  *
  * @param c the connection to use for authentication
  * @throws IOException in case of IO error or authentication failure
  */
 private void authenticate(final Connection c) throws IOException {
   for (String method : myHost.getPreferredMethods()) {
     if (c.isAuthenticationComplete()) {
       return;
     }
     if (PUBLIC_KEY_METHOD.equals(method)) {
       if (!myHost.supportsPubkeyAuthentication()) {
         continue;
       }
       if (!c.isAuthMethodAvailable(myHost.getUser(), PUBLIC_KEY_METHOD)) {
         continue;
       }
       File key = myHost.getIdentityFile();
       if (key == null) {
         for (String a : myHost.getHostKeyAlgorithms()) {
           if (SSH_RSA_ALGORITHM.equals(a)) {
             if (tryPublicKey(c, idRSAPath)) {
               return;
             }
           } else if (SSH_DSS_ALGORITHM.equals(a)) {
             if (tryPublicKey(c, idDSAPath)) {
               return;
             }
           }
         }
       } else {
         if (tryPublicKey(c, key.getPath())) {
           return;
         }
       }
     } else if (KEYBOARD_INTERACTIVE_METHOD.equals(method)) {
       if (!c.isAuthMethodAvailable(myHost.getUser(), KEYBOARD_INTERACTIVE_METHOD)) {
         continue;
       }
       InteractiveSupport interactiveSupport = new InteractiveSupport();
       for (int i = myHost.getNumberOfPasswordPrompts(); i > 0; i--) {
         if (c.isAuthenticationComplete()) {
           return;
         }
         if (c.authenticateWithKeyboardInteractive(myHost.getUser(), interactiveSupport)) {
           myLastError = "";
           return;
         } else {
           myLastError = GitBundle.getString("sshmain.keyboard.interactive.failed");
         }
         if (interactiveSupport.myPromptCount == 0 || interactiveSupport.myCancelled) {
           // the interactive callback has never been asked or it was cancelled, exit the loop
           myLastError = "";
           break;
         }
       }
     } else if (PASSWORD_METHOD.equals(method)) {
       if (!myHost.supportsPasswordAuthentication()) {
         continue;
       }
       if (!c.isAuthMethodAvailable(myHost.getUser(), PASSWORD_METHOD)) {
         continue;
       }
       for (int i = myHost.getNumberOfPasswordPrompts(); i > 0; i--) {
         String password =
             myXmlRpcClient.askPassword(myHandlerNo, getUserHostString(), myLastError);
         if (password == null) {
           break;
         } else {
           if (c.authenticateWithPassword(myHost.getUser(), password)) {
             myLastError = "";
             return;
           } else {
             myLastError = GitBundle.getString("sshmain.password.failed");
           }
         }
       }
     }
   }
   throw new IOException("Authentication failed");
 }