Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: ZSH Local or Remote?




----- Original Message ----- From: "Steven Klass" <sklass@xxxxxxxxxxxxxxx>
To: "zsh-users" <zsh-users@xxxxxxxxxx>
Sent: Sunday, November 27, 2005 3:20 PM
Subject: ZSH Local or Remote?


Hi all,

Does anyone have a nice slick function to determine whether the machine you are logged on to is local or remote? Basically you will get the tty of the current shell and grep for this in who or pinky. If you get :[0-9] you must be local.

Clearly this isn't bullet proof but I was wondering if any of you had a really slick way of figuring this out..

Why you ask? If I am locally logged in I want to run keychain. If a person is remote AND the machine is a trusted_machine I want to run keychain. Otherwise don't...

Keep in mind this needs to run multiplatform - so be carefull which command you use..

I have something like that but it's not especially slick.
I have for example a case statement for what command line args and how to parse the output of the who command.
And it's in the form of 2 seperate scripts. tellip and amilocal

------------------
#!/bin/ksh
#
# tellip - "Tell IP"
# prints the IP or Hostname that the user is connecting from.
# mostly used in other scripts to determine non-static addresses.
#
# can be run on SCO, Linux, FreeBSD
#
# Brian K White - brian@xxxxxxxxx - Aljex Software

# facetwin screws up "who" so try to use facetwin variable instead.
[ -n "${FACETWINIPADDR}" ] && { echo "${FACETWINIPADDR}" ; exit ; }

# "who" tries to show hostname but chops long names, try to use ssh variable. [ -n "${SSH_CLIENT}" ] && { echo "${SSH_CLIENT}" |awk '{print $1}' ; exit ; }

case `uname -s` in
 Linux)  who -m |cut -d\( -f2 |cut -d\) -f1 ;;
 FreeBSD)  who |cut -d\( -f2 |cut -d\) -f1 ;;
 SCO_SV) who -umx | awk '{ print $6 }' ;;
esac
------------------

------------------
#!/bin/ksh
#
# amilocal - "Am I Local?"
# Detects if the user is connecting from inside or outside the local LAN.
#
# Requires "tellip"
#
# Brian K. White - brian@xxxxxxxxx - Aljex Software

TTY=`tty`
LOGFILE=/var/log/WAN-LOGINS
LOGGING=false
VERBOSE=false

for ARG in $@ ; do
   case ${ARG} in
       -l) LOGGING=true ;;
       -v) VERBOSE=true ;;
   esac
done

case ${TTY} in
   /dev/tty[1-9]|/dev/tty[012][0-9])
       ${VERBOSE} && echo "YES: TTY=`tty`"
       exit 0
       ;;
   *)
       IP=`tellip`
       ID=`id -un`
       grep -q ${IP} /etc/LAN && {
           ${VERBOSE} && echo "YES: IP=${IP}"
           exit 0
       } || {
           ${LOGGING} && echo "`date`\t${ID}\t${IP}" >>${LOGFILE}
           ${VERBOSE} && echo "NO: IP=${IP}"
           exit 1
       }
       ;;
esac
--------------


As you can see, /etc/LAN is a text file that lists ip addresses/hostnames on the lan with the server. It starts as a copy of /etc/hosts (which lists all local subnet & vpn ip's that wouldn't be in dns) It would be more automatic to parse ifconfig, but I want to deliberately leave out some ip's once in a while. Still that could be done with a list of exclusions instead of a list of inclusions I guess, except I think a list of inclusions is safer.

At random times I find it handy to say "tellip" at the command line, or "amilocal -v" or testing customers inbound nat/firewall from on-site, by connecting out to my bix and then "telnet `tellip` 25" "ssh `tellip`" etc... But it's main use is in /etc/profile where I set $AMILOCAL and $SRVIP and do some other lan vs wan changes like setting default print destination to passthru-print or not. Then many many other places througout my software I just drop getenv("SRVIP") into urls and/or consult getenv("AMILOCAL") to decide which of 2 ways to do something or if something should be allowed or if something is even possible. $AMILOCAL gets used right of the bat in the users .profile in some cases to decide which starting point they get put into in the app.
$AMILOCAL && start_full_access || start_limited_access

I think it's just about impossible to make something like this that's really elegant and works everywhere. The biggest problem is that you can not predict or know all the possible tty names and know whether they are local or not. Multi-port serial cards and network serial server boxes have no end of types of names, various network servers produce different types of names.
Various session manager apps produce fake ttys of different types of names.
Equinox esp-16 for example, network serial box, lets you invent a tty name prefix of anything you like during driver install. It just checks to make sure it won't collide with something already existing. Granted the serial terminal case is getting pretty rare and you could just do like I did and simply ignore it. Naughty. :) I just check for the known console tty names. Another stanza would have to be added to the tty case statement for each make & model of serial card or serial server, and even if I wanted to look up every one currently existing, new ones get created and things like that equinox that let the user invent anything, makes it impractical. leave it for per-site customization and probably never need to do it anyways.

The facetwin note above is a lesson in assumptions.
In that case, the server daemon for a network telnet-ssh-alike actually puts the computers windows computer name, the netbios name, into the spot where utmp/wtmp readers (like who) look for the users ip/hostname. So it effectively makes who useless for that. But, at the same time it provides an env variable that does have the users ip, as seen from the servers point of view (it also has what the client thinks it's own ip is in another var so the distinction is not meaningless) so it's possible to have the script test for that and transparently provide the right answer.

Brian K. White  --  brian@xxxxxxxxx  --  http://www.aljex.com/bkw/
+++++[>+++[>+++++>+++++++<<-]<-]>>+.>.+++++.+++++++.-.[>+<---]>++.
filePro  BBx    Linux  SCO  FreeBSD    #callahans  Satriani  Filk!



Messages sorted by: Reverse Date, Date, Thread, Author