And now Chicken of the VNC tunneled through SSH on OS X

After I posted yesterday about the VNC Over SSH Startup Script I use with TightVNC on Solaris, I started thinking about how I could do the same thing with my MacBook Pro and Chicken of the VNC.

And I have just completed the first version. Its amazing what you can fumble through with an internet search engine. So here we go...

Password Please -- One thing you don't get with CotVNC is the vncpasswd command. So we need a copy. I just did it the quick and dirty way by grabbing the TightVNC source and compiling only the vncpasswd command:

wget http://umn.dl.sourceforge.net/sourceforge/vnc-tight/tightvnc-1.2.9_unixsrc.tar.bz2
bzip2 -cd tightvnc-1.2.9_unixsrc.tar.bz2 | tar xvf -
cd vnc_unixsrc
gcc -I include -I libvncauth -o vncpasswd/vncpasswd libvncauth/\*.c vncpasswd/\*.c

Now squirrel off the vncpasswd/vncpasswd command in your favorite bin/ directory.

Passphrase Please -- If you look back at my previous post, I make use of ssh-agent and ssh-add to allow tunneling without entering a password. Only problem on OS X is that there is no gnome-ssh-askpass command available. So I had to hack one up myself. Its an odd combination of Bourne Shell and AppleScript, but it appears to work. Save a copy as macos-askpass.

#! /bin/sh

#
# An SSH_ASKPASS command for MacOS X
#
# Author: Joseph Mocker, Sun Microsystems

# 
# To use this script:
#     setenv SSH_ASKPASS "macos-askpass"
#     setenv DISPLAY ":0"
#

TITLE=${MACOS_ASKPASS_TITLE:-"SSH"}

DIALOG="display dialog \\"$@\\" default answer \\"\\" with title \\"$TITLE\\""
DIALOG="$DIALOG with icon caution with hidden answer"

result=`osascript -e 'tell application "Finder"' -e "activate"  \\
 -e "$DIALOG" -e 'end tell'`

if [ "$result" = "" ]; then
  exit 1
else
  echo "$result" | sed -e 's/\^text returned://' -e 's/, button returned:.\*$//'
  exit 0
fi

Now lets put it all together - I'm skipping over a bunch of stuff, assuming you have read my previous entry. But here's the final script that manages asking for all the information via dialogs, creating the SSH tunnel and starting up CotVNC with the appropriate arguments.

One thing to note here is to make sure the macos-askpass and vncpasswd commands are in the PATH. I would suggest you modify the PATH command in the following script to ensure this.

Oh, also, change COTVNC_HOME to the location of your Chicken of the VNC application.

#! /bin/sh

#
# Script to put a GUI front end around Chicken of the VNC over SSH for MacOS X
#
# Author: Joseph Mocker, Sun Microsystems.

#
# This script works only with Chicken of the VNC but needs the 
# "vncpasswd" command from TightVNC.
#

COTVNC_HOME="/Applications/DarwinPorts/Chicken of the VNC.app"
COTVNC_CMD="$COTVNC_HOME/Contents/MacOS/Chicken of the VNC"

PATH=$HOME/bin:$PATH
export PATH

# Define a general Prompt routine

prompt () {
  TITLE="$PROMPT_TITLE"

  DIALOG="display dialog \\"$@\\" default answer \\"\\" with title \\"$TITLE\\""
  DIALOG="$DIALOG with icon caution"
  
  result=`osascript -e 'tell application "Finder"' -e "activate"  \\
   -e "$DIALOG" -e 'end tell'`
  
  if [ "$result" = "" ]; then
    return 1
  else
    echo "$result" | sed -e 's/\^text returned://' -e 's/, button returned:.\*$//'
    return 0
  fi
}

# Prompt for VNC Server 

PROMPT_TITLE="VNC Connection"
export PROMPT
server=`prompt "Connect to server (host:port)"`

if [ "x$server" = "x" ]; then
   exit 0
fi

# Prompt for VNC Password

MACOS_ASKPASS_TITLE="VNC Password"
export MACOS_ASKPASS_TITLE
passwd=`macos-askpass "Password for server ${server}:"`

host=`echo $server | cut -d: -f1`
port=`echo $server | cut -d: -f2`
port=`expr $port + 5900`

touch /tmp/tmpvnc.$$
chmod 600 /tmp/tmpvnc.$$
echo $passwd | vncpasswd -f > /tmp/tmpvnc.$$

# Start up a "private" SSH agent

eval `ssh-agent -s`

# Register SSH Identities with the agent

DISPLAY=:0
export DISPLAY
SSH_ASKPASS=macos-askpass
export SSH_ASKPASS
unset MACOS_ASKPASS_TITLE

ssh-add < /dev/null

# Now lets find an open port for tunnelling

tunnel=41235
while [ "`telnet localhost $tunnel < /dev/null 2>&1 |grep refused`" == "" ]; do
  tunnel=`expr $tunnel + 1`
done

# Start up an SSH with a Local tunnel.

ssh -L $tunnel:$host:$port $host "sleep 60" &

# Wait for the tunnel to activate

while [ "`telnet localhost $tunnel < /dev/null 2>&1 |grep refused`" != "" ]; do
  sleep 1
done

"$COTVNC_CMD" localhost:$tunnel --PasswordFile /tmp/tmpvnc.$$ &

# Give it a little bit to make the connection

sleep 10

# Kill the "private" SSH Agent

eval `ssh-agent -k`

# Cleanup

rm /tmp/tmpvnc.$$

So you can now run the script in a Terminal window and have it do all the wonderful magic to burrow VNC through SSH. But that's not really in the point and click nature of MacOS so...

One tiny invoker -- What would really be the icing is a little AppleScript to invoke this whole thing from, say, the Scripts menu - you do have the Scripts menu enabled don't you? Well then here you go. I call mine VNC Over SSH and shoved it in ~/Library/Scripts

do shell script "$HOME/bin/macos-vncv > /tmp/vncv.$$ 2>&1 &"

Ahh... I don't know about you, but I feel a lot better about using VNC on the Mac now.

Comments:

thanks Joe, this worked like a charm! I was unsure at first whether my CotVNC session was indeed being tunneled over ssh, because an nmap scan of my mac (= vnc client) did not show a port open for ssh. But I'm new to ports, ssh, etc. What convinced me was that killing ssh from the command line immediately took out CotVNC as well. (CotVNC said "could not connect to server localhost", and then the OS said that CotVNC quit "unexpectedly" == perfect!)

Posted by Jeremy on April 03, 2007 at 03:34 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

mock

Search

Top Tags
Categories
Archives
« September 2015
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks
Blogroll

No bookmarks in folder