Windows cmd simulate console input a command - windows

I need to write a batch script which connects to a vpn automatically when username and password is saved somewhere (Ex: in a file). VPN client is openconnect which provides a CLI but the problem is user input needs to be provided interactively to the command in order for it to complete.
See the output below when I run :
openconnect <serverhostname>
OUTPUT
POST https://<serverhostname>/
Connected to <serverhostname>:443
SSL negotiation with <serverhostname>
Server certificate verify failed: signer not found
Certificate from VPN server "<serverhostname>" failed verification.
Reason: signer not found
To trust this server in future, perhaps add this to your command line:
--servercert pin-sha256:<somesha>
Enter 'yes' to accept, 'no' to abort; anything else to view:
So I basically have to type yes manually and press Enter (it also prompts for further input), this needs to be automated in a script. Also, it's worth noting that the output is suggesting to provide --server-cert option and I could do that but when it asks the password, there's no option for it.
I tried putting the input lines in a file and redirecting that to the stdin of the command (which did not work but same the method worked on zsh on linux)
openconnect <serverhostname> < inputfile.txt
I also tried piping to stdin of the command which also didn't work.
I think the particular command doesn't read from stdin but directly from the console somehow which I really don't know how, but I could find a bit of information about something called "CON" on cmd.
Any solution is highly appreciated.

Related

Redirect input to a Java application inside a bash script

I am using the ftm cli by Oracle. When I run a command, it asks for a password by saying "Enter a password". I am writing a script which uses this command and so I want to enter the password programatically.
Here's what I have tried -
echo "password" | java -jar ftmcli.jar list
But this doesn't work. Any idea what to do to make it work?
Without being able to look into the source code of ftmcli, I presume that Oracle is using Console.readPassword() from the java.io.Console class. However, there is a snag with this function:
public final class Console
Methods to access the character-based console device, if any,
associated with the current Java virtual machine.
Whether a virtual machine has a console is dependent upon the
underlying platform and also upon the manner in which the virtual
machine is invoked. If the virtual machine is started from an
interactive command line without redirecting the standard input and
output streams then its console will exist and will typically be
connected to the keyboard and display from which the virtual machine
was launched. If the virtual machine is started automatically, for
example by a background job scheduler, then it will typically not have
a console.
If this virtual machine has a console then it is represented by a
unique instance of this class which can be obtained by invoking the
System.console() method. If no console device is available then an
invocation of that method will return null.
By piping/redirecting the stdout of echo to the JVM, the Java method System.console() will return null and hence not read anything from your redirection.
Look at the following questions which handle the same problem, but on Java side: "How to handle java passwd reading when System.console() returns null?" or How to pipe input to Java program with bash
On your side, there is more or less nothing you can really do. Executing echo $password | java -jar ftmcli.jar list or java -jar ftmcli.jar list <<< $password will always fail as long Oracle doesn't change the way how ftmcli reads the password from stdin.
If you are ready for a one time password setup, then follow the below steps.
run java -jar ftmcli.jar --save-auth-key
You will be prompted for teh password and once it is given, the file will be uploaded and a ftmclikeystore file is created under ftmcli folder.
Now as long as if you don't change the user, then ftmcli will take the password from this file.
Found this little but fantastic tool called expect does the magic:
$ ./expect.script
spawn java -cp /tmp/brm-test/oraclepki.jar:/tmp/brm-test/BRMActions.jar com.oracle.installer.brm.BRMInstallHelper 7 /tmp/brm-test/client upgC
Enter Password for the wallet:
$
Perhaps it's not very much visible in the snippet above, but it is working:
$ cat /tmp/brm-test/client/.wp
upgC=MyMag1cPa$$word#
What is in the expect.script?
$ cat expect.script
#!/usr/bin/expect
stty -echo
spawn java -cp /tmp/brm-test/oraclepki.jar:/tmp/brm-test/BRMActions.jar com.oracle.installer.brm.BRMInstallHelper 7 /tmp/brm-test/client upgC
expect "Enter Password for the wallet:"
send "MyMag1cPa$$word#\r"
interact
Seems this can be used also in Chef, see this cookbook.
I hope it will help,
Jarek

Suppress welcome message on bash remote command execution

I'm executing some commands on remote server within a shell script like this:
ssh user#host <<ENDSSH
...
ENDSSH
Upon login I'm getting a standard server welcome message echoed. Is there a way to send it to \dev\null but to keep displaying the output of executed commands?
Thanks.
Create a file ~user/.hushlogin on the remote host. This will suppress output from the login program when user logs in (such as time of last login and any message of the day).
You can edit /etc/ssh/sshd_config (for debian/ubuntu, your server might be different file) and turn the following setting to 'no'.
PrintMotd no
PrintLastLog no

BASH scripting for username/password constructs

I want to write a simple bash script using ncat to open a connection to a ISP and its port.
The first command would be:
nc address port
Upon doing this, I am prompted first to provide a username. I must hit ENTER, and then I will be prompted to provide a password and then I must hit ENTER again.
After this, I want to open a Terminal process window. Can anyone point me to sufficient resources for this type of scripting?
I know the username and password already, but I'm not too sure how to work around the fact that I must provide it and then hit enter. I'm also unsure how to open a new Terminal proceses.
Thanks in advance!
Check out expect script
Expect
Example:
# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
The secret lies in the HEREDOC
You can solve this problem with something akin to:
$ command-that-needs-input <<EOF
authenticate here
issue a command
issue another command
EOF
Look at the link I provided for here documents - it includes support for variable substitution and lots of other useful things. Enjoy!

FTP inside a shell script not working

My host upgraded my version of FreeBSD and now one of my scripts is broken. The script simply uploads a data feed to google for their merchant service.
The script (that was working prior to the upgrade):
ftp ftp://myusername:mypassword#uploads.google.com/<<END_SCRIPT
ascii
put /usr/www/users/myname/feeds/mymerchantfile.txt mymerchantfile.txt
exit
END_SCRIPT
Now the script says "unknown host". The same script works on OSX.
I've tried removing the "ftp://". - No effect
I can log in from the command line if I enter the username and password manually.
I've search around for other solutions and have also tried the following:
HOST='uploads.google.com'
USER='myusername'
PASSWD='mypassword'
ftp -dni <<END_SCRIPT
open $HOST
quote USER $USER
quote PASS $PASS
ascii
put /usr/www/users/myname/feeds/mymerchantfile.txt mymerchantfile.txt
END_SCRIPT
And
HOST='uploads.google.com'
USER='myusername'
PASSWD='mypassword'
ftp -dni <<END_SCRIPT
open $HOST
user $USER $PASS
ascii
put /usr/www/users/myname/feeds/mymerchantfile.txt mymerchantfile.txt
END_SCRIPT
Nothing I can find online seems to be doing the trick. Does anyone have any other ideas? I don't want to use a .netrc file since it is executed by cron under a different user.
ftp(1) shows that there is a simple -u command line switch to upload a file; and since ascii is the default (shudder), maybe you can replace your whole script with one command line:
ftp -u ftp://username:password#uploads.google.com/mymerchantfile.txt\
/usr/www/users/myname/feeds/mymerchantfile.txt
(Long line wrapped with \\n, feel free to remove the backslash and place it all on one line.)
ftp $HOSTNAME <<EOFEOF
$USER
$PASS
ascii
put $LOCALFILE $REMOTETEMPFILE
rename $REMOTETEMPFILE $REMOTEFINALFILE
EOFEOF
Please note that the above code can be easily broken by, for example, using spaces in the variables in question. Also, this method gives you virtually no way to detect and handle failure reliably.
Look into the expect tool if you haven't already. You may find that it solves problems you didn't know you had.
Some ideas:
just a thought since this is executed in a subshell which should inherit correctly from parent, does an env show any difference when executed from within the script than from the shell?
Do you use a correct "shebang"?
Any proxy that requires authentication?
Can you ping the host?
In BSD, you can create a NETRC script that ftp can use for logging on. You can even specify the NETRC file in your ftp command too using the -N parameter. Otherwise, the default NETRC is used (which is $HOME/.netrc).
Can you check if there's a difference in the environment between your shell-login, and the cron-job? From your login, run env, and look out for ftp_proxy and http_proxy.
Next, include a line in the cron-job that will dump the environment, e.g. env >/tmp/your.env.
Maybe there's some difference...Also, did you double-check your correct usage of the -n switch?

Ruby scripting - Telnet Hangs During Login

I am trying to do some basic scripting using ruby to log in to a windows machine via telnet and pull some files over using the dos command line ftp. When I do this manually everything goes swimmingly but when I try it via ruby I'm getting an error in the login call.
Here is my test program in its entirety:
require 'net/telnet'
tn = Net::Telnet::new("Host"=>"xxx.xxx.xxx.xxx", "Timeout"=>25, "Output_log"=>"output_log.log", "Dump_log"=> "dump_log.log", "Prompt"=>"C:.*>")
tn.login("administrator", "xxxxxxx") {}
tn.cmd('dir')
exit
The contents of output_log don't betray anything as being wrong:
Trying 208.10.202.187...
Connected to 208.10.202.187.
Welcome to Microsoft Telnet Service
login: administrator
password:
*===============================================================
Welcome to Microsoft Telnet Server.
*===============================================================
C:\Documents and Settings\Administrator>
Same for the dump_log which has very similar but awkwardly formatted contents. When I run the program it sits around for a while and then outputs the following error:
PS C:\code\tools\deployment> ruby test.rb
C:/Ruby/lib/ruby/1.8/net/telnet.rb:551:in `waitfor': timed out while waiting for more data (Timeout::Error)
from C:/Ruby/lib/ruby/1.8/net/telnet.rb:685:in `cmd'
from C:/Ruby/lib/ruby/1.8/net/telnet.rb:730:in `login'
from test.rb:3
Which leads me to suspect that the telnet class is not recognizing the command prompt. I've tried several different regex strings for the Prompt parameter, including the default and nothing seems to help.
I think the prompt field needs to be a regexp, not a string
Try
tn = Net::Telnet::new("Host"=>"xxx.xxx.xxx.xxx", "Timeout"=>25,
"Output_log"=>"output_log.log", "Dump_log"=> "dump_log.log",
"Prompt"=> /C:.*>/)

Resources