<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>2718.us blog &#187; applescript</title>
	<atom:link href="http://2718.us/blog/tag/applescript/feed/" rel="self" type="application/rss+xml" />
	<link>http://2718.us/blog</link>
	<description>Miscellaneous Technological Geekery</description>
	<lastBuildDate>Tue, 18 May 2010 02:42:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>A New Trick for When the OS X Screensaver Password Window Hangs</title>
		<link>http://2718.us/blog/2009/05/19/a-new-trick-for-when-the-os-x-screensaver-password-window-hangs/</link>
		<comments>http://2718.us/blog/2009/05/19/a-new-trick-for-when-the-os-x-screensaver-password-window-hangs/#comments</comments>
		<pubDate>Wed, 20 May 2009 03:38:35 +0000</pubDate>
		<dc:creator>2718.us</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[osascript]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[screensaver]]></category>
		<category><![CDATA[securityagent]]></category>

		<guid isPermaLink="false">http://2718.us/blog/?p=148</guid>
		<description><![CDATA[I have multiple computers, so I can easily ssh into my desktop when the screensaver password is hanging and won&#8217;t let me log in. The not-so-new trick has been to use AppleScript on the command line to not-so-harshly close some applications (run osascript, then tell application "program name" to quit, followed by ctrl-D (EOF). The [...]]]></description>
			<content:encoded><![CDATA[<p>I have multiple computers, so I can easily ssh into my desktop when the screensaver password is hanging and won&#8217;t let me log in.</p>
<p>The not-so-new trick has been to use AppleScript on the command line to not-so-harshly close some applications (run <code>osascript</code>, then <code>tell application "program name" to quit</code>, followed by ctrl-D (EOF).</p>
<p>The new trick is to sudo kill SecurityAgent, sudo run SecurityAgent, put the machine to sleep, then wake it back up (necessary to get SecurityAgent to put up a new password window).</p>
]]></content:encoded>
			<wfw:commentRss>http://2718.us/blog/2009/05/19/a-new-trick-for-when-the-os-x-screensaver-password-window-hangs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML-RPC and Mac Programming, Revisited</title>
		<link>http://2718.us/blog/2009/04/26/xml-rpc-and-mac-programming-revisited/</link>
		<comments>http://2718.us/blog/2009/04/26/xml-rpc-and-mac-programming-revisited/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 05:59:02 +0000</pubDate>
		<dc:creator>2718.us</dc:creator>
				<category><![CDATA[asLJ]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[objective c]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[utf8]]></category>
		<category><![CDATA[xml-rpc]]></category>
		<category><![CDATA[xmlrpc]]></category>

		<guid isPermaLink="false">http://2718.us/blog/?p=139</guid>
		<description><![CDATA[I might have been wrong, or at least not entirely right, when I said that AppleScript&#8217;s XML-RPC was doing something screwy with UTF8-encoded responses to XML-RPC requests.  I&#8217;m not sure if it&#8217;s LiveJournal (and other sites based on their code), or if it&#8217;s something inherent in XML-RPC, but whether I make the XML-RPC calls in [...]]]></description>
			<content:encoded><![CDATA[<p>I might have been wrong, or at least not entirely right, when I said that <a href="http://2718.us/blog/2009/02/14/applescripts-xml-rpc-doesnt-get-along-with-utf8/">AppleScript&#8217;s XML-RPC was doing something screwy with UTF8-encoded responses to XML-RPC requests</a>.  I&#8217;m not sure if it&#8217;s LiveJournal (and other sites based on their code), or if it&#8217;s something inherent in XML-RPC, but whether I make the XML-RPC calls in AppleScript (with its built-in mechanism for calling XML-RPC), in Python (with xmlrpclib), or in Objective-C/Cocoa (using <a href="http://github.com/eczarny/xmlrpc/tree/2.0">the XML-RPC framework</a> from <a href="http://divisiblebyzero.com/">here</a>), things that I was expecting to be UTF8 strings were instead coming through as binary data that needed to be decoded.</p>
<p>Beyond that point, however, AppleScript was severely lacking in that the form in which that data was stored made it entirely unusable&#8211;AppleScript couldn&#8217;t convert it, couldn&#8217;t pass it off to an Objective-C method, etc.  As suggested in my previous post, there was a way around it, and messy though it was, I went about implementing that fix and by and large it worked (though it exposed another minor bug elsewhere).  But it really bothered me.</p>
<p>So I went back to looking at trying to integrate Python code into my tangled web of AppleScript and Objective-C, since XML-RPC is fairly easy in Python, though not quite as easy as in AppleScript.  And, eventually, I succeeded in integrating a class written in Python into the program (documentation on using the PyObjC bridge in this direction is woefully inadequate), using a less ineligant means of fixing the binary UTF8 data—</p>
<pre>unicode(theResult.data,'utf-8')</pre>
<p>(and Python also allowed me to generically recurse through the entire return structure, which wasn&#8217;t possible in Applescript).  Unfortunately, this version was <em>substantially</em> slower than the broken-Unicode version and not particularly any faster (perhaps slower) than the AppleScript-fixed Unicode version.</p>
<p>This led me to look for a way to do the XML-RPC stuff in Objective-C.  Now, mind you, the single thing that enabled me to even think about writing a client for LJ for Mac was seeing just how easy AppleScript XML-RPC calls were.  While I didn&#8217;t particularly want to try Python, the XML-RPC calls there weren&#8217;t that much harder.  But going to Objective-C for XML-RPC&#8230;  that&#8217;s a fundamental change in the program.  At least, to me.</p>
<p>I did a lot of Googling and found that there are actually a few XML-RPC frameworks for Objective-C/Cocoa (<a href="http://github.com/eczarny/xmlrpc/tree/2.0">the one I used by Eric Czarny</a>, <a href="http://ranchero.com/cocoa/xmlrpc/">the one from Brent Simmons</a>, <a href="http://www.mulle-kybernetik.com/software/XMLRPC/">the Mulle one</a>, <a href="http://www.padl.com/Research/XMLRPCObjC.html">XMLRPCObjC</a>, <a href="http://sope.opengroupware.org/en/docs/snippets/xmlrpc_client.html">SOPE</a>).  Supposedly, there&#8217;s a way to do it with Apple&#8217;s own Cocoa stuff, but the documentation is woefully inadequate (none of the frameworks have amazing and wonderful documentation, but Apple&#8217;s documentation is <em>bad</em>) and almost every mention of it that I found on mailing lists and discussion boards said it was broken.  In the end, my framework choice was largely dictated by licensing, though there were also some issues with usability and dependencies.  As with AppleScript and Python, the UTF8 strings weren&#8217;t coming through as strings, but as NSData objects, which are fairly easy to convert with</p>
<pre>[[NSString alloc] initWithData:theObject encoding:NSUTF8StringEncoding]</pre>
<p>Recursing through the entire returned structure wasn&#8217;t particularly any harder in Objective-C than in Python.</p>
<p>The best part is that the resulting client with Objective-C-based-XML-RPC feels <em>faster</em> than the non-Unicode AppleScript-based-XML-RPC client.  In vaguely-objective tests (determine a set of steps that constitute a test and record the total time for just the XML-RPC calls in those steps, run the test several times under each app, compare times), the new version is <em>measurably</em> faster than the old version.</p>
<p>Bottom lines: (1) expect a new version of <a href="http://2718.us/asLJ/">asLJ</a> in the next few days, as soon as I get feedback from my early testers; (2) expect another post or two about other things I&#8217;ve learned in rewriting the XML-RPC aspect of asLJ in Objective-C.</p>
]]></content:encoded>
			<wfw:commentRss>http://2718.us/blog/2009/04/26/xml-rpc-and-mac-programming-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AppleScript&#8217;s XML-RPC Doesn&#8217;t Get Along with UTF8</title>
		<link>http://2718.us/blog/2009/02/14/applescripts-xml-rpc-doesnt-get-along-with-utf8/</link>
		<comments>http://2718.us/blog/2009/02/14/applescripts-xml-rpc-doesnt-get-along-with-utf8/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 00:53:02 +0000</pubDate>
		<dc:creator>2718.us</dc:creator>
				<category><![CDATA[asLJ]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[rdat]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[utf8]]></category>
		<category><![CDATA[xml-rpc]]></category>
		<category><![CDATA[xmlrpc]]></category>

		<guid isPermaLink="false">http://2718.us/blog/?p=131</guid>
		<description><![CDATA[While the ease of making XML-RPC calls in AppleScript is wonderful for, say, writing a LiveJournal Client in mostly AppleScript Studio, it seems to be doing something really messed up with UTF8 strings returned by the server—they come into AppleScript as raw data objects, which it seems can&#8217;t be cast into any other type and [...]]]></description>
			<content:encoded><![CDATA[<p>While the ease of making XML-RPC calls in AppleScript is wonderful for, say, writing <a href="http://2718.us/asLJ/">a LiveJournal Client</a> in mostly AppleScript Studio, it seems to be doing something really messed up with UTF8 strings returned by the server—they come into AppleScript as raw data objects, which it seems can&#8217;t be cast into any other type and can&#8217;t be passed easily into a Cocoa method to convert them.  The easiest way to properly decode them seems to be the following:</p>
<div class="geshi no applescript">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">if</span> class <span class="kw1">of</span> theReturnedValue <span class="kw1">is</span> <span class="st0">&quot;data&quot;</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">try</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="coMULTI">(* this will fail on a data object and then we will pull the (hex) bytes out as text</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp; and bring them back as a utf8 string object *)</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; theReturnedValue <span class="kw3">as</span> text</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">on</span> <span class="kw1">error</span> errmess <span class="co1">&#8211; extract the data from the error message</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> bytesString <span class="kw1">to</span> text <span class="br0">&#40;</span><span class="br0">&#40;</span>offset <span class="kw1">of</span> <span class="st0">&quot;«&quot;</span> <span class="kw1">in</span> errmess<span class="br0">&#41;</span> <span class="sy0">+</span> <span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw2">thru</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>offset <span class="kw1">of</span> <span class="st0">&quot;»&quot;</span> <span class="kw1">in</span> errmess<span class="br0">&#41;</span> <span class="sy0">-</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw1">of</span> errmess</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> theReturnedValue <span class="kw1">to</span> <span class="br0">&#40;</span><span class="kw3">run</span> <span class="kw1">script</span> <span class="st0">&quot;«data utf8&quot;</span> <span class="sy0">&amp;</span> bytesString <span class="sy0">&amp;</span> <span class="st0">&quot;»&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">end</span> <span class="kw1">try</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
</ol>
</div>
<p>This checks the class of the returned value and, if it&#8217;s a raw data object, attempts to cast it as text which raises an error, then extracts the string of hexadecimal values from the error message and puts it into a proper UTF8 object, making everything happy again.</p>
<p>If anyone wants to tell me I&#8217;m wrong and there&#8217;s a simpler fix, I&#8217;d love to hear it, since this is essentially unworkable.</p>
]]></content:encoded>
			<wfw:commentRss>http://2718.us/blog/2009/02/14/applescripts-xml-rpc-doesnt-get-along-with-utf8/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dynamic URLs for XML-RPC Calls in AppleScript</title>
		<link>http://2718.us/blog/2009/02/12/dynamic-urls-for-xml-rpc-calls-in-applescript/</link>
		<comments>http://2718.us/blog/2009/02/12/dynamic-urls-for-xml-rpc-calls-in-applescript/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 16:42:38 +0000</pubDate>
		<dc:creator>2718.us</dc:creator>
				<category><![CDATA[asLJ]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[applescript studio]]></category>
		<category><![CDATA[livejournal]]></category>
		<category><![CDATA[lj]]></category>
		<category><![CDATA[xml-rpc]]></category>
		<category><![CDATA[xmlrpc]]></category>

		<guid isPermaLink="false">http://2718.us/blog/?p=123</guid>
		<description><![CDATA[I started working on asLJ after I came across this. One of the problems that I quickly ran into was that the URLs in the tell application "&#60;url&#62;" to call xmlrpc ... bits had to be hard-coded. That is, AppleScript didn&#8217;t like it when I tried to assemble the URL string on the fly. It [...]]]></description>
			<content:encoded><![CDATA[<p>I started working on <a href="http://2718.us/asLJ/">asLJ</a> after I came across <a href="http://community.livejournal.com/applescript/18386.html">this</a>.  One of the problems that I quickly ran into was that the URLs in the
<pre>tell application "&lt;url&gt;" to call xmlrpc ...</pre>
<p> bits had to be hard-coded.  That is, AppleScript didn&#8217;t like it when I tried to assemble the URL string on the fly.  It took me a while to come up with a workaround, which should slightly impact the speed of the call, but doesn&#8217;t seem to make a noticeable difference.  Here&#8217;s my generic handler for making LJ-based server XML-RPC calls:</p>
<div class="geshi no applescript">
<div class="head">&#8211; make a LiveJournal-type XML-RPC call to serverString for the method methodName with the parameters in parameterArray</div>
<ol>
<li class="li1">
<div class="de1"><span class="kw1">on</span> callLJraw<span class="br0">&#40;</span>serverString, methodName, parameterArray<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">    <span class="kw3">run</span> <span class="kw1">script</span> <span class="st0">&quot;on run {paramArray}</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">                tell application <span class="es0">\&quot;</span>http://&quot;</span> <span class="sy0">&amp;</span> serverString <span class="sy0">&amp;</span> <span class="st0">&quot;/interface/xmlrpc<span class="es0">\&quot;</span> to call xmlrpc ¬</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">                    {method name:<span class="es0">\&quot;</span>LJ.XMLRPC.<span class="es0">\&quot;</span> &amp; <span class="es0">\&quot;</span>&quot;</span> <span class="sy0">&amp;</span> methodName <span class="sy0">&amp;</span> <span class="st0">&quot;<span class="es0">\&quot;</span>, parameters:{paramArray}}</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">            end run&quot;</span> <span class="kw1">with</span> parameters <span class="br0">&#123;</span>parameterArray<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">    <span class="kw1">return</span> <span class="kw3">result</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> callLJraw</div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://2718.us/blog/2009/02/12/dynamic-urls-for-xml-rpc-calls-in-applescript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>asLJ: a Mac OS X 10.5+ LiveJournal Client</title>
		<link>http://2718.us/blog/2009/02/09/aslj/</link>
		<comments>http://2718.us/blog/2009/02/09/aslj/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 08:24:18 +0000</pubDate>
		<dc:creator>2718.us</dc:creator>
				<category><![CDATA[asLJ]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[applescript studio]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[keychain]]></category>
		<category><![CDATA[keychain.framework]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[livejournal]]></category>
		<category><![CDATA[livejournal client]]></category>
		<category><![CDATA[lj]]></category>
		<category><![CDATA[lj client]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[macintosh]]></category>
		<category><![CDATA[objective c]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[sparkle]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://2718.us/blog/?p=121</guid>
		<description><![CDATA[asLJ is a new client for Macs running Leopard that easily handles multiple accounts on LiveJournal and other LJ-based sites and facilitates cross-posting across accounts. Release notes and download link are in aslj_client. The community for users is aslj_users. (As it is very LJ-centric, most of the information about it will be over at LJ, [...]]]></description>
			<content:encoded><![CDATA[<p>asLJ is a new client for Macs running Leopard that easily handles multiple accounts on LiveJournal and other LJ-based sites and facilitates cross-posting across accounts. Release notes and download link are in <span style="white-space: nowrap;"><a href="http://aslj-client.livejournal.com/profile"><img style="border: 0pt none; vertical-align: bottom; padding-right: 1px;" src="http://p-stat.livejournal.com/img/userinfo.gif" alt="[info]" width="17" height="17" /></a><a href="http://aslj-client.livejournal.com/"><strong>aslj_client</strong></a></span>.  The community for users is <span style="white-space: nowrap;"><a href="http://community.livejournal.com/aslj_users/profile"><img style="border: 0pt none; vertical-align: bottom; padding-right: 1px;" src="http://p-stat.livejournal.com/img/community.gif" alt="[info]" width="16" height="16" /></a><a href="http://community.livejournal.com/aslj_users/"><strong>aslj_users</strong></a></span>.</p>
<p>(As it is very LJ-centric, most of the information about it will be over at LJ, in the two places linked above, but there is a page for it <a href="http://2718.us/asLJ/">here</a>, as well.)</p>
]]></content:encoded>
			<wfw:commentRss>http://2718.us/blog/2009/02/09/aslj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSH Tunneling on a Mac</title>
		<link>http://2718.us/blog/2008/06/13/ssh-tunneling-on-a-mac/</link>
		<comments>http://2718.us/blog/2008/06/13/ssh-tunneling-on-a-mac/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 22:55:27 +0000</pubDate>
		<dc:creator>2718.us</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[firefox system proxy]]></category>
		<category><![CDATA[location]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[network location]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[secure shell]]></category>
		<category><![CDATA[socks]]></category>
		<category><![CDATA[socks proxy]]></category>
		<category><![CDATA[socks5]]></category>
		<category><![CDATA[socks5 proxy]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[ssh tunnel]]></category>
		<category><![CDATA[system proxy]]></category>
		<category><![CDATA[tunnel]]></category>
		<category><![CDATA[tunnelier]]></category>

		<guid isPermaLink="false">http://2718.us/blog/?p=45</guid>
		<description><![CDATA[Since my employer&#8217;s wireless network is unencrypted and since I use other open WiFi networks with some frequency, I&#8217;ve gotten in the habbit of tunneling everything through SSH, using the SOCKS5 proxy mechanism built in to SSH.  In WinXP, there&#8217;s a nice little program called Tunnelier that makes the setup of the tunnel simple and [...]]]></description>
			<content:encoded><![CDATA[<p>Since my employer&#8217;s wireless network is unencrypted and since I use other open WiFi networks with some frequency, I&#8217;ve gotten in the habbit of tunneling everything through SSH, using the SOCKS5 proxy mechanism built in to SSH.  In WinXP, there&#8217;s a nice little program called <a href="http://www.bitvise.com/tunnelier">Tunnelier</a> that makes the setup of the tunnel simple and it reconnects automatically, so the tunneling part is virtually automatic (even though proxy setup is still tricky and/or annoying).</p>
<p>On the Mac, however, I have tried several programs and never really been happy.  So I wrote a little AppleScript that not only sets up the SSH tunnel, but also deals with switching my location to set the system&#8217;s network settings to use the proxy (the code is after the cut).  Combine this with <a href="http://blog.curthread.org/projects/systemproxy">System Proxy</a> for Firefox and all my application traffic goes through the SSH tunnel.  Note also that if you&#8217;re using a SOCKS5 proxy with Firefox, you probably want to set it to do DNS lookups through the proxy.<span id="more-45"></span></p>
<p>This script also stores the info for creating the tunnel (server, login, pw) in the keychain.</p>
<p>Here&#8217;s the &#8220;library&#8221; script where I put the functions to do the underlying work (since I have various different tunnels I use):</p>
<div class="geshi no applescript">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">on</span> startTunnel<span class="br0">&#40;</span>targetServer<span class="br0">&#41;</span> <span class="co1">&#8211;returns PID of ssh for killing later</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">tell</span> application <span class="st0">&quot;Keychain Scripting&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> sshTunnelKeys <span class="kw1">to</span> <span class="kw2">every</span> Internet key <span class="kw1">of</span> current keychain <span class="kw2">whose</span> <span class="br0">&#40;</span>name <span class="kw1">is</span> <span class="st0">&quot;autoSSHTunnel&quot;</span><span class="br0">&#41;</span> <span class="kw3">and</span> <span class="br0">&#40;</span>server <span class="kw1">is</span> targetServer<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> sshTunnelKeys <span class="kw1">is</span> <span class="br0">&#123;</span><span class="br0">&#125;</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> sshKey <span class="kw1">to</span> <span class="kw1">my</span> makeSSHKeyWithServer<span class="br0">&#40;</span>targetServer<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> sshKey <span class="kw1">to</span> item <span class="nu0">1</span> <span class="kw1">of</span> sshTunnelKeys</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> user <span class="kw1">to</span> account <span class="kw1">of</span> sshKey</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> passwd <span class="kw1">to</span> password <span class="kw1">of</span> sshKey <span class="kw3">as</span> string</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> sshHost <span class="kw1">to</span> server <span class="kw1">of</span> sshKey <span class="kw3">as</span> string</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">end</span> <span class="kw1">tell</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">set</span> sshCommand <span class="kw1">to</span> <span class="st0">&quot;ssh -fND 9999 &quot;</span> <span class="sy0">&amp;</span> user <span class="sy0">&amp;</span> <span class="st0">&quot;@&quot;</span> <span class="sy0">&amp;</span> sshHost</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">set</span> expectScript <span class="kw1">to</span> <span class="st0">&quot;spawn &quot;</span> <span class="sy0">&amp;</span> sshCommand <span class="sy0">&amp;</span> <span class="st0">&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">expect assword</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">send <span class="es0">\&quot;</span>&quot;</span> <span class="sy0">&amp;</span> passwd <span class="sy0">&amp;</span> <span class="st0">&quot;<span class="es0">\\</span>n<span class="es0">\&quot;</span></span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">sleep 1&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;do shell <span class="kw1">script</span> <span class="st0">&quot;/usr/bin/expect -c &#39;&quot;</span> <span class="sy0">&amp;</span> expectScript <span class="sy0">&amp;</span> <span class="st0">&quot;&#39; &amp;&gt;/dev/null &amp;&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">set</span> tries <span class="kw1">to</span> <span class="nu0">0</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> tries <span class="kw1">to</span> tries <span class="sy0">+</span> <span class="nu0">1</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">try</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> sshPIDstring <span class="kw1">to</span> <span class="br0">&#40;</span>do shell <span class="kw1">script</span> <span class="st0">&quot;sleep 1;bash -c &#39;ps ax -o pid,tt,command | grep <span class="es0">\&quot;</span>??<span class="es0">\&quot;</span> | grep <span class="es0">\&quot;</span>&quot;</span> <span class="sy0">&amp;</span> sshCommand <span class="sy0">&amp;</span> <span class="st0">&quot;<span class="es0">\&quot;</span> | grep -v grep | grep -v expect&#39;&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> sshPID <span class="kw1">to</span> <span class="kw2">first</span> word <span class="kw1">of</span> sshPIDstring</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> gotPID <span class="kw1">to</span> <span class="kw3">true</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">on</span> <span class="kw1">error</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> gotPID <span class="kw1">to</span> <span class="kw3">false</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span> <span class="kw1">try</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> gotPID <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">exit</span> <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> tries &gt; <span class="nu0">10</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">exit</span> <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">end</span> <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">if</span> gotPID <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">return</span> sshPID</div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">return</span> <span class="kw3">false</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> startTunnel</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">on</span> setUseTunnel<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;do shell <span class="kw1">script</span> <span class="st0">&quot;scselect &#39;Use SOCKS5 Proxy on localhost:9999&#39;&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> setUseTunnel</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">on</span> clearUseTunnel<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;do shell <span class="kw1">script</span> <span class="st0">&quot;scselect &#39;Automatic&#39;&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> clearUseTunnel</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">on</span> stopTunnel<span class="br0">&#40;</span>pid<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;do shell <span class="kw1">script</span> <span class="st0">&quot;kill &quot;</span> <span class="sy0">&amp;</span> pid</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> stopTunnel</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">on</span> makeSSHKeyWithServer<span class="br0">&#40;</span>targetServer<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">tell</span> application <span class="st0">&quot;Keychain Scripting&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> acctBox <span class="kw1">to</span> display dialog <span class="st0">&quot;Enter your SSH login for host &quot;</span> <span class="sy0">&amp;</span> targetServer <span class="sy0">&amp;</span> <span class="st0">&quot;:&quot;</span> default answer <span class="st0">&quot;&quot;</span> buttons <span class="br0">&#123;</span><span class="st0">&quot;Cancel&quot;</span>, <span class="st0">&quot;OK&quot;</span><span class="br0">&#125;</span> default button <span class="nu0">2</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> myAcct <span class="kw1">to</span> <span class="kw2">the</span> text returned <span class="kw1">of</span> acctBox</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> myButton <span class="kw1">to</span> <span class="kw2">the</span> button returned <span class="kw1">of</span> acctBox</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> myButton <span class="kw1">is</span> <span class="st0">&quot;Cancel&quot;</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">&#8211;quit</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> myAcct <span class="kw1">is</span> <span class="kw3">not</span> <span class="st0">&quot;&quot;</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw1">exit</span> <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;display dialog <span class="st0">&quot;bad login&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span> <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> passBox <span class="kw1">to</span> display dialog <span class="st0">&quot;Enter your password:&quot;</span> default answer <span class="st0">&quot;&quot;</span> buttons <span class="br0">&#123;</span><span class="st0">&quot;Cancel&quot;</span>, <span class="st0">&quot;OK&quot;</span><span class="br0">&#125;</span> default button <span class="nu0">2</span> <span class="kw1">with</span> <span class="kw3">hidden</span> answer</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> myPass <span class="kw1">to</span> <span class="kw2">the</span> text returned <span class="kw1">of</span> passBox</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">set</span> myButton <span class="kw1">to</span> <span class="kw2">the</span> button returned <span class="kw1">of</span> passBox</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">if</span> myButton <span class="kw1">is</span> <span class="st0">&quot;Cancel&quot;</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">&#8211;quit</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> myPass <span class="kw1">is</span> <span class="kw3">not</span> <span class="st0">&quot;&quot;</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;<span class="kw1">exit</span> <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;display dialog <span class="st0">&quot;can&#39;t use blank passwd&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">end</span> <span class="kw1">repeat</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">set</span> newSSHKey <span class="kw1">to</span> <span class="kw3">make</span> new Internet key <span class="kw1">with</span> properties <span class="br0">&#123;</span>name:<span class="st0">&quot;autoSSHTunnel&quot;</span>, account:myAcct, password:myPass, server:targetServer, authentication:default, protocol:SSH<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">end</span> <span class="kw1">tell</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">return</span> newSSHKey</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> makeSSHKeyWithServer</div>
</li>
</ol>
</div>
<p>And here&#8217;s the actual script I run.</p>
<div class="geshi no applescript">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">property</span> Lib : <span class="br0">&#40;</span>path <span class="kw1">to</span> scripts folder <span class="kw1">from</span> user domain <span class="kw3">as</span> text<span class="br0">&#41;</span> <span class="sy0">&amp;</span> <span class="st0">&quot;Script Library:&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">property</span> sshTunnelLib : load <span class="kw1">script</span> Lib <span class="sy0">&amp;</span> <span class="st0">&quot;ssh_tunnel.scpt&quot;</span> <span class="kw3">as</span> alias</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">sshTunnelLib<span class="st0">&#39;s setUseTunnel()</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="st0">set sshPID to sshTunnelLib&#39;</span>s startTunnel<span class="br0">&#40;</span><span class="st0">&quot;fqdn.of.your.server&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> sshPID <span class="kw1">is</span> <span class="kw3">not</span> <span class="kw3">false</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">set</span> noPIDtxt <span class="kw1">to</span> <span class="st0">&quot;&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">set</span> buttonTxt <span class="kw1">to</span> <span class="st0">&quot;Kill SSH and Exit&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">set</span> noPIDtxt <span class="kw1">to</span> <span class="st0">&quot; (but couldn&#39;t get PID)&quot;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;<span class="kw1">set</span> buttonTxt <span class="kw1">to</span> <span class="st0">&quot;Exit&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">end</span> <span class="kw1">if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">display dialog <span class="st0">&quot;SSH-tunneled SOCKS5 proxy running on localhost:9999&quot;</span> <span class="sy0">&amp;</span> noPIDtxt buttons <span class="br0">&#123;</span>buttonTxt<span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> sshPID <span class="kw1">is</span> <span class="kw3">not</span> <span class="kw3">false</span> <span class="kw1">then</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;sshTunnelLib<span class="st0">&#39;s stopTunnel(sshPID)</span></div>
</li>
<li class="li1">
<div class="de1"><span class="st0">end if</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="st0">sshTunnelLib&#39;</span>s clearUseTunnel<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://2718.us/blog/2008/06/13/ssh-tunneling-on-a-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

