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.
Related
I'm attempting to put a POC together that leverages the SQL Server 2019 Extensibility Framework & External Languages feature. This enables execution of external languages in SQL Server Stored procedures. I've written a JAR file that encrypts and decrypts data being passed via a SQL Server stored procedure. I've confirmed that the each method is correct, and returns the correct values when not being sent as a stored procedure. However, when executing the stored procedure I receive an empty data set and see the following error in debug mode:
java.io.FileNotFoundException: <jks-file-location> (Access is denied)
The line of Java code throwing the error is below:
Key _key = readKeyFromStore_cbs("<jks-file-location>, "<password>".toCharArray(), "entityEncryption", "<password>".toCharArray());
_keySpec = new SecretKeySpec(_key.getEncoded(), _key.getAlgorithm());
Again, the code is fine, I don't think there are issues there, and don't think posting the content of those methods is the issue (the SP itself runs fine with dummy data in the place of data being encrypted and decrypted, and the code with encryption and decryption runs as expected when run on its own).
Additional Info:
I'm running this on a local Windows 10 environment and have given "Everyone" full security permissions on the jks.
I've double checked the user running sql server and ensured that user has full permissions on the file as well. (This user also has admin privileges on SQL Server)
I've checked SQL Server sp_configure options as well.
Filestream is enabled and set to full control in sp_configure
I've even disabled clr strict security on sp_configure to see if that was the cause. I still receive the same error.
I've attempted tests with JKS in my User directory (with permissions on the directory and file for the SQL Server user), in the C drive, and in the child directory of the C drive (again, with permissions on the directory and file for the SQL Server user)
The stored procedure runs, but is returning an empty data set. When attempting run without encryption (using the key from the currently inaccessible keystore) and using dummy data, I receive the expected data set.
Anyone know what might be causing this error?
UPDATE:
Moving the JAR and jks into SQL Server directories and starting the Launchpad service resolved the issue. Hope this helps someone avoid similar frustrations.
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.
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
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.
I know there is a lot of thread about this problem but I dont found right: I follow this example: Want to invoke a linux shell command from Java to run command. Problem with ssh command is in authentication. When I run it I need to set password
$ ssh root#server 'fgrep Exception *.log*'
Enter passphrase for key '/././.ssh/id_rsa':
How can I pass here password ?
There are libraries are available to invoke ssh. The Java Secure Channel (JSCH) is a very popular library, used by maven, ant and eclipse. It is open source with a BSD style license.
If you need authentication for ssh, you can use through java.
If your still need to by pass password passing, there are two ways to do what you want. One involves a stored password, and one does not.
Both are non-interactive, meaning that they can work when you're not there to enter a password.
The way that does not require a password. You can use public/private
key authentication instead of passwords with SSH. I'm going to
assume that you're using OpenSSH, which comes with practically every
Linux distribution.
Steps :
Configure your SSH server to accept private key logins. In /etc/ssh/sshd_config make sure that there's a line that says PubkeyAuthentication yes (and that there is no # infront of it). If you change this file, you need to restart the sshd service.
On your local machine (not the server), create yourself a pair of keys with ssh-keygen -t rsa (you can use other options than rsa, but I'm keeping it simple). Do not specify a password. Save the keys in the locations prompted.
Open the contents of the id_rsa.pub file that you just created (it's one very long line of text), and copy the contents into the end of the file $HOME/.ssh/authorized_keys on the server machine. Create the file if it doesn't exist.
Further Detail refer here.
The basic idea is to use expect, which is an
administration automation tool, to type your password in to ssh when
prompted. It might not always work, and when it doesn't, it's hard
to figure out why not. I recommend the first method.
Anyway, here's a command that you can poke at until it does what you
want.
The script Code is:
expect -c 'spawn ssh user#remote.host ; expect assword ; send "passphrase\n" ; interact'
Expect might not be installed on your system. Make sure install that
You need to get the InputStream (which has the output) from the execution and wait for it to ask you for the password, then get the OutputStream (into which you give the command its input) and send it the password you want.
Have a read of this article