#!/bin/bash if [ -t 0 ]; then echo 'You are not allowed to login to this shell.' else /bin/bash ${1} "${2}" fi exit 0
After making the script executable, it has the following results:
> scp filename.txt username@machine: username@machine's password: filename.txt 100% 9695 9.5KB/s 00:00 > ssh username@machine username@machine's password: You are not allowed to login to this shell. Connection to machine closed.
The reason that this works is that both scp and sftp work by initializing an ssh connection and starting scp or sftp on the server side. Basically, the command
scp filename username@machine:
is, initially at least, the same as sending the command
ssh username@machine ${SHELL} -c "scp -t ."
By changing the user’s shell to my script, I am effectively running that test “-t 0″ before giving them the opportunity to start the command that they are sending over. The test checks to see if the command is being run on a terminal or not.
Now, there are several issues with the approach that I took. The first is that a user who understands what I’m doing could very easily get around this. There’s nothing to stop them from sending their own commands instead of scp or sftp. This could be fixed rather easily though, all that someone would need to do is test ${2} to make certain that the string begins with either scp or sftp. The other issue that I have is that a user could easily write to files outside of their home directory. After testing to see if the command is scp or sftp all someone would have to do is replace ${2} with the appropriate command followed by a †-t .†That would effectively close those two holes.