Script called from ~/.ssh/config loses TTY - stty

I'm using a site-specific authentication script that issues a 24-hour certificate for password-less login. What I'm trying to do is rig my ~/.ssh/config so ssh triggers the script if the certificate has expired:
Match originalhost remotehost.site exec "test $(file.age ~/.ssh/certificate) -ge 86400" exec ~/bin/authentication_script
This almost works -- it tests the age of the latest certificate file ok, and invokes the authentication_script if it's out-of-date. The problem is that this script is using TTY read operations to take the password input, and giving these errors:
stty: 'standard input': Inappropriate ioctl for device
stty: 'standard input': Inappropriate ioctl for device
authentication_script: The sshproxy server said: Authentication failed. Failed login: myname:
authentication_script: This usually means you did not enter the correct password or OTP:
stty: 'standard input': Inappropriate ioctl for device
stty: 'standard input': Inappropriate ioctl for device
stty: 'standard input': Inappropriate ioctl for device
authentication_script: The sshproxy server said: Authentication failed. Failed login: myname:
authentication_script: This usually means you did not enter the correct password or OTP:
stty: 'standard input': Inappropriate ioctl for device
This doesn't happen when I run the script on the command-line from a regular login session.
Is there some mode that I can flip to get it to work?

I've been told that exec disables the stdin/stdout, and referred to here:
https://unix.stackexchange.com/questions/674759/how-to-make-ssh-config-match-host-exec-inherit-current-shells-tty-name
But for my purposes, I am able to use PTY operations to control the I/O:
PTY=$(ps --no-headers $$ | xargs index 2)
printf "Enter the password}: " > /dev/$PTY
read -r -s pw < /dev/$PTY
(The index operation is just my script to return the nth item from a list)

Related

How do you pass serveral passwords in SCP using expect?

My purpose is control transferring files between two remote machines. If I could use key-pair it would be much easier but I can't choose the options but passing passwords.
Environments : Local(Mac), Remote_source(Linux), Remote_target(Linux)
Here it is my expect.sh. When I run it, source#source's password: pops up, then target#target's password: and nothing else. No files transferred, no stdout, no error message, just disconnected.
#!/usr/bin/expect
set timeout -1
spawn scp -3 scp://remote_source_user#host:port/home/source/test.txt scp://remote_target_user#host:port/home/target/
expect "remote_source_user#host's password:"
send "SOURCE_PASSWORD\r"
expect "remote_target_user#host's password:"
send "TARGET_PASSWORD\r"
expect eof
When I change the sequence the password (meaning send target password first rather than sending source password first.) it occurs error, so I guess it is working but I have got no idea what is going on internally.
I have tried sshpass but it is not working with several passwords.
I debugged it with -v flag and found out that Connection works perfectly but the problem is the directory.
# in debugging mode
Sink: scp: home/username/test.txt: No such file or directory
It seems not recognizing /home/username/test.txt at the beginning.
so the code should be like below:
#!/usr/bin/expect
set timeout -1
spawn scp -3 scp://remote_source_user#host:port/~/test.txt scp://remote_target_user#host:port/~/
expect "remote_source_user#host's password:"
send "SOURCE_PASSWORD\r"
expect "remote_target_user#host's password:"
send "TARGET_PASSWORD\r"
expect eof
Do not explicitly write your home directory /home/username/ but use /~/.
# The Result
debug1: Sending command: scp -v -r -f ~/test.txt
Sending file modes: C0000 00 test.txt
Sink: C0000 00 test.txt

FATAL: password authentication failed for user "username" in PostgreSQL

I'm new to PostgreSQL. I just installed the Postgres.app on my Mac and wanted to use the psql command in the terminal. However, when I type psql in the terminal, I'm asked to input the password. I was never asked to set a password during installation so I'm confused what the password is. I've looked at other similar questions but none of them worked for my case.
$ psql
$ Password for user kaili:
$ psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed:
FATAL: password authentication failed for user "kaili"
Could anyone give me some hints on how to access the database as the user kaili? Thank you!

How does ssh read the password that I type in?

My understanding is that if I type the following command in my xterm:
$ ssh ir#localhost
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ir#localhost's password:
Then the stdin and stdout of the ssh process are both connected to the pty. So when I type in the password, ssh just reads it from stdin.
But my mental model fails to explain this:
$ yes | ssh ir#localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ir#localhost's password:
...
...
zsh: command not found: y
...
Here, yes's stdin is connected to the pty, and yes's stdout is piped to ssh's stdin. So ssh should be getting a deluge of ys, but it is smart enough to tell that its stdin is not a tty, and that the contents of stdin should not be interpreted as the password. Instead, the ys are buffered, and once the login succeeds, they are delivered directly to the bash process on the remote end.
But then how is ssh able to get the password that I am typing in? The pty sends my password to yes, which drops it on the floor.
Also, ssh's claim to not allocate a pty appears to be a lie. The following snippet prints out whether or not stdin is tty:
$ [ -t 0 ] && echo true || echo false;
true
When I pipe this command to ssh, it initially prints out "false", as expected:
$ echo "[ -t 0 ] && echo true || echo false;" | ssh ir#localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ir#localhost's password:
...
false
$ [ -t 0 ] && echo true || echo false;
true
But when I run the same command on the remote shell, it prints out "true". I can even open up vim, and when I resize my local terminal, the vim resizes the text that it is displaying appropriately. This can only be possible if the ssh client sends information about the resizing over the wire, and if sshd notifies the vim process, just like a pty would.
Interestingly, when I hit Ctrl+C, the ssh session is immediately terminated. My explanation for this is that the pty intercepts the Ctrl+C and sends a SIGINT to both yes and ssh. If ssh had allocated a pty, it would intercept the signal and transmit it over the wire to the remote host, and whatever process running remotely would be the one interrupted. But since ssh did not allocate a pty, it simply died. So this part is expected...but I still don't understand why [ -t 0 ] passes on the remote shell, and how ssh is able to read the password even when yes is piped to it.

x2go Connection failed. bash: bash: command not found

I want to connect from my home pc with VPN (ubuntu-18.04) to work pc (ubuntu 18.04) using x2go.
Server side installation:
sudo add-apt-repository ppa:x2go/stable
sudo apt-get update
sudo apt-get install x2goserver x2goserver-xsession
Client side installation:
sudo apt-get install x2goclient
I am able to ssh to my remote desktop, but x2go doesn't work. Problem seems to be in the server side, since I tried to x2go connect from different computer (CentOs) and error was the same.
Client session preferences window:
I tried almost everything in session preferences, even with RSA key (I have it) or single application session type and many else, always the same error.
Client debug log: (x2goclient --debug)
x2go-INFO-1> "Starting X2Go Client 4.1.2.1..." x2go-WARNING-1> English
language requested, not loading translator. x2go-WARNING-1> English
language requested, not loading translator. Object::connect: No such
slot ONMainWindow::slotCheckAgentProcess() x2go-INFO-3> "Started X2Go
Client." x2go-DEBUG-../src/onmainwindow.cpp:563> "$HOME=/home/XXX"
x2go-DEBUG-../src/onmainwindow.cpp:2242> Reading 1 sessions from
config file. x2go-DEBUG-../src/sessionbutton.cpp:342> Creating QPixmap
with session icon: ":/img/icons/128x128/x2gosession.png".
x2go-DEBUG-../src/onmainwindow.cpp:12843> libssh not initialized yet.
Initializing. x2go-DEBUG-../src/onmainwindow.cpp:2728> Creating
QPixmap with session icon: '":/img/icons/128x128/x2gosession.png"'.
x2go-DEBUG-../src/onmainwindow.cpp:2795> Starting session via Smart
Card, SSH Agent or Kerberos token. x2go-INFO-8> "Starting connection
to server: 192.168.29.15:22" x2go-DEBUG-../src/onmainwindow.cpp:2829>
Starting new ssh connection to server:"192.168.29.15":"22" krbLogin:
false x2go-DEBUG-../src/sshmasterconnection.cpp:175>
SshMasterConnection, host "192.168.29.15"; port 22; user "XXX";
useproxy false; proxyserver "192.168.29.15"; proxyport 22
x2go-DEBUG-../src/sshmasterconnection.cpp:248> Starting SSH connection
without Kerberos authentication.
x2go-DEBUG-../src/sshmasterconnection.cpp:252> SshMasterConnection,
instance SshMasterConnection(0x56102247dbe0) created.
x2go-DEBUG-../src/sshmasterconnection.cpp:520> SshMasterConnection,
instance SshMasterConnection(0x56102247dbe0) entering thread.
x2go-DEBUG-../src/sshmasterconnection.cpp:840> Session port before
config file parse: 22 x2go-DEBUG-../src/sshmasterconnection.cpp:850>
Session port after config file parse: 22
x2go-DEBUG-../src/sshmasterconnection.cpp:915> Session port before
config file parse (part 2): 22
x2go-DEBUG-../src/sshmasterconnection.cpp:925> Session port after
config file parse (part 2): 22
x2go-DEBUG-../src/sshmasterconnection.cpp:950> cserverAuth
x2go-DEBUG-../src/sshmasterconnection.cpp:991> state: 1
x2go-DEBUG-../src/sshmasterconnection.cpp:1364> userAuthAuto failed:""
(code 1)
x2go-DEBUG-../src/sshmasterconnection.cpp:1274> Trying password
mechanism if available.
x2go-DEBUG-../src/sshmasterconnection.cpp:1278> Password mechanism
available. Continuing.
x2go-DEBUG-../src/sshmasterconnection.cpp:726> User authentication OK.
x2go-DEBUG-../src/sshmasterconnection.cpp:1789> LOGIN CHECK:"LOGIN OK
" x2go-DEBUG-../src/sshmasterconnection.cpp:1792> don't have
interaction x2go-DEBUG-../src/sshmasterconnection.cpp:1825> LOOP
FINISHED x2go-DEBUG-../src/sshmasterconnection.cpp:1829> No
interaction needed, continue session
x2go-DEBUG-../src/sshmasterconnection.cpp:735> Login Check - OK
x2go-DEBUG-../src/onmainwindow.cpp:2923> SSH connection established.
x2go-DEBUG-../src/onmainwindow.cpp:3336> Continue normal X2Go session
x2go-DEBUG-../src/sshprocess.cpp:199> Executing remote command via
SshProcess object 0: "x2golistsessions"
x2go-DEBUG-../src/sshprocess.cpp:213> this=SshProcess(0x5610224a1f30)
Running masterCon->addChannelConnection(this, '
"1d4dfc1a-7f4d-4f00-b39e-07273d3d973d" ', ' "bash -l -c 'echo
"X2GODATABEGIN:1d4dfc1a-7f4d-4f00-b39e-07273d3d973d"; export
PATH="/usr/local/bin:/usr/bin:/bin";export TERM="dumb";
x2golistsessions; echo "X2GODATAEND:1d4dfc1a-7f4d-4f00-b39e-07273d"
'); x2go-DEBUG-../src/sshmasterconnection.cpp:1891> Locking SSH
channel connection MUTEX.
x2go-DEBUG-../src/sshmasterconnection.cpp:1893> Passing new channel
connection object to channelConnections.
x2go-DEBUG-../src/sshmasterconnection.cpp:1895> Unlocking SSH channel
connection MUTEX. x2go-DEBUG-../src/sshmasterconnection.cpp:2083>
Creating new channel.
x2go-DEBUG-../src/sshmasterconnection.cpp:2100> New
channel:0x7fcf84012aa0
x2go-DEBUG-../src/sshmasterconnection.cpp:2185> Executing remote:
"bash -l -c 'echo
"X2GODATABEGIN:1d4dfc1a-7f4d-4f00-b39e-07273d3d973d"; export
PATH="/usr/local/bin:/usr/bin:/bin";export TERM="dumb";
x2golistsessions; echo
"X2GODATAEND:1d4dfc1a-7f4d-4f00-b39e-07273d3d973d";'"
x2go-DEBUG-../src/sshmasterconnection.cpp:2208> New exec channel
created.
x2go-DEBUG-../src/sshmasterconnection.cpp:2257> EOF on channel
0x7fcf84012aa0; SshProcess object: 0
x2go-DEBUG-../src/sshmasterconnection.cpp:2380> EOF sent.
x2go-DEBUG-../src/sshmasterconnection.cpp:2384> Channel closed.
x2go-DEBUG-../src/sshprocess.cpp:526> SSH finished: raw output
(stdout): "" x2go-DEBUG-../src/sshprocess.cpp:532> Have stderr only,
something must be wrong. x2go-DEBUG-../src/sshprocess.cpp:537> SSH
finished: false - "bash: bash: command not found " (0).
x2go-DEBUG-../src/onmainwindow.cpp:3804> "bash: bash: command not
found
If someone was interested, I can show server's side /var/log/syslog
Thank you for your help
Please try moving your .bashrc aside and retry.
It was my bad, silly me. I had a typo in /etc/environment file and I didn't notice it because I haven't restarted my PC after that typo. After fixing it, it worked.

why is the `tcgetattr` error seen when ssh is used for dumping the backup file on another server?

I want to dump a tables backup on another server and I am using ssh for doing it.
when I run the below command, it gives an error but dump file is copied to destination.
mysqldump -u username -ppassword dbname tablename | ssh -t -t servers_username#domain_name 'cat > /tmp/bckp.sql';
tcgetattr: Invalid argument
If I press CTRL+c then it appends error message with Killed by signal 2.
Why is this error?
I've seen this error when forcing pseudo-terminal allocation using ssh -t -t or ssh -tt.
The tcgetattr function is used to look up the attributes of the pseudoterminal represented by a file descriptor; it takes a file descriptor and a pointer to a termios structure to store the terminal metadata in. It looks to me from the stub code in glibc that this error represents a null pointer for the termios struct. I am not sure whether these same error handling semantics are in place for the platform-specific implementations of tcgetattr.
If you want to suppress this error, invoke ssh like so:
ssh 2>/dev/null
This will redirect STDERR to /dev/null; you won't see the error when invoking with this redirection. Note that this will mask other errors with ssh; you may need to remove this for debugging purposes.
In my case, forcing pty allocation on the outer ssh of a two-level ssh invocation fixed the problem.
Details:
When you provide a command for ssh to run ( e.g. ssh some_server "do_some_command" ), then ssh assumes you won't need an interactive session, and it will not allocate a pty as it submits the "do_some_command" job you asked it to.
However, things get interesting if you have two layers of ssh (e.g. let's say you want to ssh into a "gateway" machine first, and from there you ssh into an "inner" machine and run some "inner_command").
The thing is, with a two-layer ssh'ing job, from the perspective of the outer ssh, you are requesting that the outer ssh run a non-interactive command, hence the outer ssh will not allocate a tty.
If the command you are running in the inner ssh is meant to be interactive, it will probably want to query tty attributes and it will (righteously) complain that it is not being run on a tty.
The solution in my case was to force the outer ssh to allocate a pty, by using the -t argument. So it looked like this:
ssh -t <gateway_machine> "ssh <inner_machine> \"<inner_interactive_command>\" "
Greetings to the sysadmins out there