All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xebialabs.overthere.ssh.SshElevatedPasswordHandlingStream Maven / Gradle / Ivy

There is a newer version: 5.6.16
Show newest version
/**
 * Copyright (c) 2008-2016, XebiaLabs B.V., All rights reserved.
 *
 *
 * Overthere is licensed under the terms of the GPLv2
 * , like most XebiaLabs Libraries.
 * There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
 * this software, see the FLOSS License Exception
 * .
 *
 * 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; version 2
 * of the License.
 *
 * 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 St, Fifth
 * Floor, Boston, MA 02110-1301  USA
 */
package com.xebialabs.overthere.ssh;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Detects password prompts in the output stream and sends the password in response.
 */
class SshElevatedPasswordHandlingStream extends FilterInputStream {
    private final OutputStream remoteStdin;
    private final byte[] passwordBytes;
    private final String passwordRegex;
    private final Pattern passwordPattern;

    private final StringBuilder receivedOutputBuffer = new StringBuilder();

    private boolean sentPassword = false;

    protected SshElevatedPasswordHandlingStream(InputStream remoteStdout, OutputStream remoteStdin, String password, String passwordPromptRegex) {
        super(remoteStdout);
        this.remoteStdin = remoteStdin;
        this.passwordBytes = (password + "\r\n").getBytes();

        this.passwordRegex = passwordPromptRegex;
        this.passwordPattern = Pattern.compile(passwordRegex);
    }

    @Override
    public int read() throws IOException {
        int readInt = super.read();
        if (readInt > -1) {
            handleChar((char) readInt);
        }
        return readInt;
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int numBytesRead = super.read(b, off, len);
        if (numBytesRead > -1) {
            for (int i = 0; i < numBytesRead; i++) {
                handleChar((char) b[off + i]);
            }
        }
        return numBytesRead;
    }

    private void handleChar(char c) {
//        if (!sentPassword) {
            logger.trace("Received: {}", c);
            if (c == '\n') {
                receivedOutputBuffer.setLength(0);
            } else {
                receivedOutputBuffer.append(c);

                if (c == passwordRegex.charAt(passwordRegex.length() - 1)) {
                    String receivedOutput = receivedOutputBuffer.toString();
                    if (passwordPattern.matcher(receivedOutput).matches()) {
                        logger.info("Found password prompt in output: {}", receivedOutput);
                        sentPassword = true;
                        try {
                            remoteStdin.write(passwordBytes);
                            remoteStdin.flush();
                            logger.debug("Sent password");
                        } catch (IOException exc) {
                            logger.error("Cannot send password", exc);
                        }
                    }
                }
            }
//        }
    }

    private static Logger logger = LoggerFactory.getLogger(SshElevatedPasswordHandlingStream.class);

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy