Several problems:
to read a line, it's IFS= read -r line. Your read -s -p "Enter the password : " passd in particular won't work properly for users whose password contains backslashes or start or end in characters of $IFS. So it should be IFS= read -rsp 'Enter the password: ' passd || exit
in bash, parameter expansions in list contexts must be quoted. "$user@$1", not $user@$1 for instance.
that -o StrictHostKeyChecking=no sounds a bit like please hack me. Unless the network can be fully trusted, authenticating the server to the client is almost as important as authenticating the client to the server. And that directive would be like saying "trust the user to be whoever they say they are without asking them for proof of identity" if it were done on the server side.
passwords and other secret information should never be passed in command arguments which are public information within a system. The sshpass man page has a big warning about that. Use SSHPASS="$passd" sshpass -e ssh..., or better still use better forms of authentication than password authentication.
It's good practice to unset variables before having them store secret data to make sure they're not exported to the environment (and leak to commands that might themselves leak them further afield; likely not the case here). In bash, that's with unset -v passd.
With sshpass ... ssh ... << 'HEREDOC', the here-document becomes the stdin of sshpass which passes it along to ssh which passes it along to the remote command. Here, you're not specifying which command to run, so it will be the login shell of the remote user, whichever it it.
Since ssh's stdin is not a terminal device, it will request sshd
not to create a pseudo-terminal on the remote side, even with -t
which is just as well, so that shell will be started
non-interactively which again is just as well as it would otherwise start
echoing a prompt and do all the things an interactive shell does while here you want to to execute a script.
So here, that shell will read the code to execute from its stdin.
But that code also happens to read from its stdin. That read -p "Enter your choice [ 1 - 3 ]" choice, would read from that heredoc. Thankfully, that read won't be run until the code for the full while loop has been read by the shell, so it will only read what's after that in that here-doc, or if there's nothing after that, it will just read nothing and return failure upon eof.
Here, you need to run a bash shell (since you're using bash-specific syntax) on the remote host, not the user's login shell (who would use bash as their login shell? :-b), non-interactively and pass it the code some other way than via stdin. If the ssh server has some AcceptEnv LC_* in its configuration which is common, you could do:
code=$(
cat <<'EOF'
the code there
EOF
)
And then:
SSHPASS="$passd" LC_CODE="$code" sshpass -e ssh -o SendEnv=LC_CODE -qt "$user@$1" '
exec bash -c -- "$LC_CODE"'
Here assuming the login shell of $user on the remote host understands that syntax, that is where $var is used to refer to variables and double-quotes can be used for quoting (and which are necessary on Bourne-like ones to avoid the split+glob). If their login shell is rc or derivative or zsh or fish, exec bash -c -- $LC_CODE is enough (though the quotes would only be harmful for rc-like shells); if it's csh or tcsh: exec bash -c -- $LC_CODE:q.
Writing it:
SSHPASS="$passd" LC_CODE="$code" sshpass -e ssh -o SendEnv=LC_CODE -qt "$user@$1" '
exec bash -c '\''eval -- "$LC_CODE"'\'
Would work if the user's login shell is any of the ones above, as the bash -c 'eval -- "$LC_CODE"' code is understood the same by all of Bourne-like, rc-like, csh-like and fish shells at least. Also has the advantage of not exposing that code in the output of ps -Awww on the remote host.
You can learn more about that at: How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?
SSHPASS="$passd" sshpass -e ssh -qt "$user@$1" " $code"
As in @aviro's answer (with the addition of that extra space before $code, needed for the cases where $code starts with - or +¹) would only work if the login shell of the user happened to be bash. Also note that it exposes the code in the output of ps -Awww on both the local and remote system.
¹ as in that case, it's sshd that does bash -c thatcode, and at least in current versions of openssh, it doesn't do bash -c -- thatcode (possibly because not all shells support or need that -- or more likely because the issue (unlikely to happen in practice) has been overlooked; that same issue for C's system() has been overlooked for many decades)
readEnterKeyroutine, and also there isn't the exit condition of thewhileloop and it's closing.scpto copy it to the remote host (perhaps to /tmp), and then usingsshto run it. This also avoids issues with stdin being redirected.