SH execution from Java GUI application don't work - java

I'm trying to execute a SH script from my java GUI application. I'm using jsch to connect to the machine.
I can execute commands like "ls" or "pwd". When I try to execute my SH I only get all output from it, if I execute it directly in the machine it take several time (that's what is expected) and works fine.
The script begins with
"#!/bin/bash"
and the code that call it is:
String command= "cd /opt/app/ordersync/scripts/RE-INJEC;sh ./proc_reinjec.sh"; // enter any command you need to execute
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
in = channel.getInputStream();
channel.connect();
When I execute it
I get TERM environment variable not set
I can't figure it out what is the problem. I tried to the same in php with shell_exec and I the problem (result) was the same.

This is only a guess. So consider that mostly as a (long) comment. But you are assuming your "command" will in fact be parsed by an intermediate shell, that might even be responsible to set a proper environment. But, does ChannelExec really launch a shell? Or does it instead execute directly the command?
Anyway, try that:
String command= "sh -l -c 'cd /opt/app/ordersync/scripts/RE-INJEC;sh ./proc_reinjec.sh'";
// ^^^^^^^^^^ ^
// explicit sub-shell don't forget the closing quote >-->-->----/
// '-l' is for login shell: reads /etc/profile, ... at startup
// I don't know if this is required here
But maybe in fact you are searching for ChannelShell instead?
From RFC 4254, section 6.5. Starting a Shell or a Command:
6.5. Starting a Shell or a Command
Once the session has been set up, a program is started at the
remote end. The program can be a shell, an application program, or
a subsystem with a host-independent name. Only one of these
requests can succeed per channel.
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "shell"
boolean want reply
This message will request that the user's default shell (typically
defined in /etc/passwd in UNIX systems) be started at the other end.
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string **"exec"**
boolean want reply
string command
This message will request that the server start the execution of
the given command. The 'command' string may contain a path.
Normal precautions MUST be taken to prevent the execution of
unauthorized commands.

Related

scp command does not work from process builder in java

I have been facing a strange issue in running scp command via my java application.
I am supposed to run this scp command with "-i" option where in ,I pass the identify key of a low privileged user(for an instance user B) while my java process is run by another logged in user(for an instance user A).
This is how my command looks in the application log when it's run by the logged in user "user A".
scp -l 10000 -o BatchMode=yes -o LogLevel=DEBUG -i "PathToIdentitykeyOfuserB" remoteUser#remoteHost:"PathToRemoteFile" "localPathofCopiedFile"
This command fails in my java application with errors saying
stdErr: Warning: Identity file not accessible: No such file or directory.
stdErr: remoteUser#remoteHost: Permission denied (publickey,password,keyboard-interactive).
what makes me wondering is the very same command runs perfectly, when it is run either in cygwin command line or windows command line.
I later added "-o LogLevel=DEBUG" in order to debug the internal logging for scp command to ascertain any difference in the logging informations of scp command itself (when it was run in windows cmd line) and when it is run via process builder of java application.
I observed that while SCP's(run through user A in windows command line)internal logging says it takes in the very same identity key of user B but its not this case when scp is run via process builder in my java application. Internal debug logging of SCP shows that it attempts to authenticate using the default private key of user A even after explicitly passing the identity key of user B.
Please find below few screenshots.
Identity key loaded in the SCP's internal logging from Windows CMD.
Authentication successful via Window CMD
Identity Key loaded in SCP's internal logging from process builder of java Application.
I fail to understand as to why SCP does not attempt to authenticate with the explicitly passed identity key of user B but rather tries to authenticate with its default identity key(user A).
However, its evident from the attached screenshots that from windows command line, it authenticates with the explicitly passed identity key and as a result, authentication succeeds.
I request experts to help me out with some tips to resolve this problem.
How can I make the process builder to take into account the identity key of passed identity key of another user instead of default key of user initiating it?
Any help would be greatly appreciated.
Here is how, I was creating process builder.
I have created a list of strings which basically holds scp command constructed with the list of strings and then pass this list directly as a parameter to command method of process builder.
I have managed to solve it now by creating a temporary file and then writing scp commands to it and run this temporary file in the process builder as against running scp command directly in the process builder earlier.
Instead of passing the list of strings which was used to construct scp command and passing the same to process builder, I have resorted to creating a temporary file and then writing scp command to it and lastly running this temporary file by passing to java process builder.
This solution seems to work now for me.

How to get Welcome message after connecting to SSH using JSch

When I connect to SSH using PuTTY, I get the following message as given below.
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-98-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
deb#ubuntu:~$
Similarly, when I use JSch library to connect, I should also get the same message in Java. Please help me about how to get this. I provide below my code details.
public String connect() {
String errorMessage = null;
try {
sesConnection = jschSSHChannel.getSession(userName, ipOrHostName, PORT);
sesConnection.setPassword(password);
sesConnection.setConfig("StrictHostKeyChecking", "no");
sesConnection.connect(TIMEOUT);
//After connecting, I should get the welcome message
} catch (JSchException jschX) {
errorMessage = jschX.getMessage();
}
return errorMessage;
}
I want to get the welcome message from a unix system before executing the commands in JSch. Please help about how to get it.
The message you are seeing is simply printed on a shell output.
That does not go well with automatic its reading and executing commands.
I general to automate a command execution, you correctly plan to use SSH channel "exec" (ChannelExec in JSch). But that channel won't give you the message.
You would have to use "shell" channel (ChannelShell in JSch). But that channel is intended for implementing an interactive shell session. Not to automate command execution and not for parsing command output. Particularly in the context of your question, there's no realiable way to find out the end of the "welcome message". You would have to read the output line by line, until you get the prompt ("deb#ubuntu:~$").
Or, if your use case allows that, you can use ChannelShell to get the message and then use ChannelExec to execute the commands.
You better talk to the server administrator to make the information you need available using a different API (like using SSH2_MSG_USERAUTH_BANNER, or even other way).
See my answer to SSH MOTD per user to understand the different ways how the server can provide the "welcome message". Had the server used SSH2_MSG_USERAUTH_BANNER, you could use UserInfo.showMessage to capture the message. See also How to read the SSH key-sig pair banner (for generating SSH password) after connecting to host in Java?

Java API for SSH Secondary Login Validation

Currently when I connect from windows to our linux host server, I use putty with my credentials in a .bat file to automatically access the machine. However the connection does not automatically direct me to the terminal shell but there's a secondary interactive login prompt that requires me to manually input another username and password, as of now I don't know how to get pass these with automation.
My question, is it possible to automate these specifically on java or just a .bat?
One of my co-workers managed to do it on VB script using the "sendkey" method. The information online states "sendkey" send one or more keystrokes to the active window as if they were typed at the keyboard. May I know is there a counterpart of sendkey in Java in JSCH or SSHJ?
NOTE: I'm not after to connect directly to the terminal, what I'm after is to automate the interactive login as if I were manually typing it like what the sendkey does.
Injecting typed characters into a ssh session is pretty simple. Just inject the characters to be written into the OutputStream provided by sshj. I assume that you log-in and then execute something that requires the interactive console login.
I simulate the executed process using the following simple script named test.sh. It reads a typed line and prints it.
#/bin/bash
read varname
echo You typed $varname
I am executing this script using a modified Exec example from sshj:
final Session session = ssh.startSession();
try {
Command cmd = session.exec("/home/username/test.sh");
OutputStream out = cmd.getOutputStream();
out.write("1234567\n".getBytes()); // we type 1234567
out.flush();
System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
cmd.join(5, TimeUnit.SECONDS);
System.out.println("\n** exit status: " + cmd.getExitStatus());
} finally {
session.close();
}
If you execute the script using the sshj code you will get the result
You typed 1234567
By reading the inputStream line by line you can wait for the line that asks for the username or password and send the right data to the server, simulating your input.

Execute a unix program from a Java class using java.lang.Process with a specific user

I am trying to run a unix command from Java using java.lang.Process class.
How can we pass a specific user so that the command executes with the permissions of that specific user ?
I don't want to execute the command with a superuser.
You could use a ssh session, that logs with the user you know its password and run a specific command.
E.g. using java shell JSch
or
Expect4J
or
Ganymed-ssh-2
I found a good thread here by the way:
Jsch or SSHJ or Ganymed SSH-2?
You could start a login command first and then input credentials into it.
I would guess that starting su - [USER] should do the trick.
After reading through apropos user I came across the pkexec command which should do what you need.
You can run a new shell and execute commands which will switch to another user and then run the programm

Java intercept command prompt reply

I was doing some cmd commands via java that are only input in the command prompt.
I was wondering if there was a way to programatically fetch and reply to a command prompt question via Java?
e.g.: I add a remote GIT repository to my GIT structure locally, so when I execute:
$ git remote add [url],
I get prompted for a password. Can i catch this message (for example to pass the message to the user) AND reply in the same command prompt programming object/cmd window.
(the AND is explicitly in there because it would be useless to execute above command, read prompt reply, close command prompt, send password via a new cmd command in a new and thus non-related new prompt window).
If you are executing the command using Runtime.getRuntime().exec, capture/monitor the sub process's input stream and write to the output stream to send message to it.
E.g
Process process = Runtime.getRuntime().exec("Command ");
OutputStream pout = process.getOutputStream();
PrintWriter pw = new PrintWriter(pout);
pw.println("Command response here");
YOu can interact with the standard input / output / error streams of another command by using a ProcessBuilder to start that command as a Process. In that case, the process usually won't directly talk to a command window, so you'll have to print its output to the user if that is needed.
Note that some processes take particular care not to read passwords from standard input, but from the console window instead. In that case, the above might not work. Usually commands do provide some means to specify a different source for passwords. In the case of git, please search for the GIT_ASKPASS environment variable as well as the core.askpass configuration setting.

Categories

Resources