<?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>Tyler Oderkirk&#039;s Blog &#187; Python programming</title>
	<atom:link href="http://unsyncopated.com/blog/index.php/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://unsyncopated.com/blog</link>
	<description>&#34;No matter how cynical you get, it&#039;s impossible to keep up&#34; - Lily Tomlin</description>
	<lastBuildDate>Tue, 17 Aug 2010 14:23:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Creds101 v0.1 Release</title>
		<link>http://unsyncopated.com/blog/index.php/2010/02/20/creds101-v0-1-release/</link>
		<comments>http://unsyncopated.com/blog/index.php/2010/02/20/creds101-v0-1-release/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 14:38:45 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Python programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Table of Contents]]></category>

		<guid isPermaLink="false">http://unsyncopated.com/blog/index.php/2010/02/20/creds101-v0-1-release/</guid>
		<description><![CDATA[I&#8217;m happy to announce the first release of a credentials (e.g. &#8220;usernames and passwords&#8221;) management system that I&#8217;ve been working on for the past few weeks. It&#8217;s called Creds101 and this excerpt from the documentation gives some more detail: Creds101 has 2 parts: Software that you run on your computer (the &#8220;host&#8221;) to send commands [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce the first release of a credentials (e.g. &#8220;usernames and passwords&#8221;) management system that I&#8217;ve been working on for the past few weeks. It&#8217;s called Creds101 and this excerpt from <a href="http://unsyncopated.com/corral/creds101-0.1/index.html">the documentation</a> gives some more detail:</p>
<hr />Creds101 has 2 parts:</p>
<ol>
<li>Software that you run on your computer (the &#8220;host&#8221;) to send commands to&#8230;</li>
<li>A USB &#8220;token&#8221; which A) encrypts and stores credentials from the host and B) decrypts and displays them on its LCD.</li>
</ol>
<p>Creds101 serves the same purpose as traditional &#8220;password database&#8221; solutions but it is different in two fundamental ways:</p>
<ol>
<li>Credentials aren&#8217;t stored on the user&#8217;s computer &#8211; they&#8217;re stored on a USB &#8220;token&#8221;.</li>
<li>Sensitive credential data &#8221;cannot be read by malicious software on the user&#8217;s computer&#8221; &#8211; credentials can only be viewed on the token&#8217;s &#8220;trusted LCD display&#8221;.</li>
</ol>
<hr />
<span id="Contents"><h3>Contents</h3></span>
<div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#Contents">Contents</a>
	</li>
	<li>
		<a href="#Whats_in_v0.1">What's in v0.1?</a>
	</li>
	<li>
		<a href="#Whats_next">What's next?</a>
	</li>
	<li>
		<a href="#What_I_learned">What I learned</a>
	</li>
	<li>
		<a href="#Download__Quickstart">Download / Quickstart</a>
	</li>
	<li>
		<a href="#Further_reading">Further reading</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div>
<span id="What8217s_in_v0.1"><h3>What&#8217;s in v0.1?</h3></span>
<ul>
<li><a href="http://www.methods.co.nz/asciidoc/">AsciiDoc</a>-based documentation including the &#8220;host-&gt;token&#8221; serial command protocol and data-flow diagrams illustrating how credentials are encrypted, stored, decrypted, and displayed by the token.</li>
<li>A <a href="http://docs.python.org/library/unittest.html">unittest</a> test suite which exercises each of the commands accepted by the token. Install <a href="http://twistedmatrix.com/trac/">Twisted</a> and try
<pre class="brush: bash;">PYTHONPATH=src trial src/TestSimulatorToken.py</pre>
</li>
<li>A cross-platform &#8220;token administration&#8221; GUI for storing and retrieving credentials. Try
<pre class="brush: bash;">bin/creds101-admin-gui --use-simulator</pre>
<p>or see screenshot 1.						<div class="flickr-gallery image none"><a href="http://www.flickr.com/photos/55502932@N00/4373389528"><img class="flickr small" title="Screenshot 1 - GUIs" alt="Screenshot 1 - GUIs" src="http://farm5.static.flickr.com/4066/4373389528_7f97d950e4_m.jpg" /></a></div>
					</li>
<li>A command-line &#8220;token administration&#8221; interface. Try
<pre class="brush: bash;">bin/creds101 --help</pre>
</li>
<li>A &#8220;token simulator&#8221; that allows us to 1) develop tests 2) iron out token design issues &#8221;before&#8221; coding in C for an embedded platform. Try
<pre class="brush: bash;">bin/creds101-simulator --gui</pre>
<p>or see screenshot 1.</li>
<li>						<div class="flickr-gallery image right"><a href="http://www.flickr.com/photos/55502932@N00/4372493561"><img class="flickr small" title="Photo 2 - Desoldering flash part" alt="Photo 2 - Desoldering flash part" src="http://farm3.static.flickr.com/2709/4372493561_13955be0f6_m.jpg" /></a></div>
					The beginnings of the code for an <a href="http://www.arduino.cc/en/Main/ArduinoBoardDuemilanove">Arduino</a>-based token. Take a look in `src/arduino`. This includes code for&#8230;
<ul>
<li>Receiving commands from the &#8220;host&#8221; via the Arduino&#8217;s FTDI serial-over-USB chip.</li>
<li>Reading and writing data to the 512 bytes of internal EEPROM or an attached SPI <a href="http://www.atmel.com/products/dataflash/default.asp">DataFlash</a> part. See photos 2 and 3.</li>
<li>Displaying text on a <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=9394">SparkFun SerLCD</a> LCD module.</li>
<li>Encrypting and decrypting data with 128-bit AES.</li>
</ul>
</li>
</ul>
<span id="What8217s_next"><h3>What&#8217;s next?</h3></span>
<ul>
<li>						<div class="flickr-gallery image right"><a href="http://www.flickr.com/photos/55502932@N00/4373266740"><img class="flickr small" title="Photo 3 - New leads" alt="Photo 3 - New leads" src="http://farm3.static.flickr.com/2706/4373266740_32369563b4_m.jpg" /></a></div>
					Completing the Arduino token implementation so that we have something that&#8217;s suitable for everyday use.</li>
<li>Completing a thumbdrive-sized token implementation &#8211; the ideal form factor.</li>
<li>The smaller tasks that can be found in the `TODO` file.</li>
</ul>
<span id="What_I_learned"><h3>What I learned</h3></span>
<ul>
<li>How to create slick, source-based docs with the AsciiDoc tool suite. As much as I like MoinMoin markup, the wiki engine itself isn&#8217;t amenable to being invoked from a build automation tool.</li>
<li>GUI design with <a href="http://glade.gnome.org/">Glade</a>, a slick <a href="http://en.wikipedia.org/wiki/Rapid_application_development">RAD</a> tool used by many free software projects.</li>
<li>GUI interaction with <a href="http://www.pygtk.org/">PyGTK</a>. I wrote a well-behaved worker thread that runs alongside the GTK main loop for the token simulator component.</li>
<li>The theory and implementation of &#8220;Secret Sharing&#8221; schemes especially Shamir&#8217;s Secret Sharing Scheme (SSSS). We discarded SSSS in favor of the current &#8220;store-the-key-on-the-host, store-the-ciphertext-on-the-token&#8221; design.</li>
<li>A handful of Python skills&#8230;
<ul>
<li>Finding a script&#8217;s location &#8221;from within the script&#8221;. Handy for using `bin/foo -&gt; src/foo.py` symlinks in conjunction with external (e.g. Glade XML) resources.</li>
<li>Python&#8217;s built-in <a href="http://docs.python.org/library/xmlrpclib.html">XML-RPC</a> library. Reconciling UNIX socket semantics with thread semantics gave me fits before I switched to this IPC mechanism.</li>
<li>Steven Bethard&#8217;s superior <a href="http://code.google.com/p/argparse/">argparse</a> module which makes handling subcommands and required positional arguments a breeze compared with Python&#8217;s standard optparse module.</li>
</ul>
</li>
</ul>
<span id="Download__Quickstart"><h3>Download / Quickstart</h3></span>
<p>Creds101 is licensed under the GPL.</p>
<p>Here are the steps to grab the v0.1 source tarball from <a href="http://unsyncopated.com/hg/creds101/">the hgweb interface</a> and take the GUIs for a test drive!</p>
<pre class="brush: bash;">
$ wget http://unsyncopated.com/hg/creds101/archive/0.1.tar.gz
$ tar xzf 0.1.tar.gz
$ cd creds101-0.1
$ bin/creds101-simulator --gui &amp;           # launch the token simulator
$ bin/creds101-admin-gui --use-simulator &amp; # connect to the simulator
</pre>
<span id="Further_reading"><h3>Further reading</h3></span>
<p>You can see our design notes, plans, and a list of similar projects at <a href="https://www.unsyncopated.com/wiki/Creds101">the wiki page</a> but beware the outdated Secret Sharing content.</p>
<p>I&#8217;m accumulating all the research papers, datasheets, and application notes I&#8217;ve encountered during this project in <a href="http://unsyncopated.com/hg/creds101-research_materials/file/tip">a &#8220;research materials&#8221; repository</a>. You might find the contents useful if you&#8217;re trying to choose an AES implementation for an AVR microcontroller or if your project falls into one of these categories: &#8220;cryptographic co-processor&#8221;, &#8220;hardware security module&#8221;, &#8220;embedded secret secret sharing&#8221;, &#8220;ubiquitous/pervasive computer security&#8221;, or &#8220;tamper evidence/proof&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://unsyncopated.com/blog/index.php/2010/02/20/creds101-v0-1-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sending data via cellular voice connections with Linux</title>
		<link>http://unsyncopated.com/blog/index.php/2009/11/19/sending-data-via-cellular-voice-connections-with-linux/</link>
		<comments>http://unsyncopated.com/blog/index.php/2009/11/19/sending-data-via-cellular-voice-connections-with-linux/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 10:45:03 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Flickr]]></category>
		<category><![CDATA[Footnotes]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python programming]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Shell programming]]></category>
		<category><![CDATA[Syntax highlighter]]></category>
		<category><![CDATA[Table of Contents]]></category>

		<guid isPermaLink="false">http://unsyncopated.com/blog/index.php/2009/11/20/sending-data-via-cellular-voice-connections-with-linux/</guid>
		<description><![CDATA[&#8220;A5/1 [the encryption scheme used in most cellular voice calls] has operated unchanged for the last 21 years but it has now reached its cryptographic end-of-life, engulfed by the march of Moore&#8217;s Law. However, the operational end-of-life of A5/1 may still be decades away as there are approximately 2 billion GSM subscribers, commanding about 80% of [...]]]></description>
			<content:encoded><![CDATA[<div>
<p style="padding-left: 30px;">&#8220;A5/1 [the encryption scheme used in most cellular voice calls] has operated unchanged for the last 21 years but it has now reached its cryptographic end-of-life, engulfed by the march of Moore&#8217;s Law. However, the operational end-of-life of A5/1 may still be decades away as there are approximately 2 billion GSM subscribers, commanding about 80% of the global mobile market. This would be a tough product recall indeed. A5/1 is well-positioned to become the NT of the mobile crypto world, and I see the makings of a long tail of GSM vulnerability.&#8221; - <a href="http://ch.linkedin.com/pub/luke-o-connor/1/bb6/152">Dr. Luke O&#8217;Connor</a> at <a href="http://lukenotricks.blogspot.com/2009/09/another-crack-at-open-rainbow-tables.html">NoTricks: Another crack at open Rainbow Tables for A5/1</a></p>
<div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#Introduction">Introduction</a>
	</li>
	<li>
		<a href="#The_modem__Hardware_components">The modem / Hardware components</a>
	</li>
	<li>
		<a href="#Transmitting_audio_from_a_PC_to_a_cell_phone__Software_components">Transmitting audio from a PC to a cell phone / Software components</a>
	</li>
	<li>
		<a href="#Demonstration__OKCrypto_scripts">Demonstration / OKCrypto scripts</a>
	</li>
	<li>
		<a href="#Encryption">Encryption</a>
	</li>
	<li>
		<a href="#Further_work">Further work</a>
	</li>
	<li>
		<a href="#What_I_learned">What I learned</a>
	</li>
	<li>
		<a href="#Conclusion__Download">Conclusion / Download</a>
	</li>
	<li>
		<a href="#Further_reading">Further reading</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div>
<span id="Introduction"><h3>Introduction</h3></span>
<p>The ability to intercept and decrypt GSM cell phone conversations is now well within the reach of hobbyists.<sup>1</sup><sup>2</sup></p>
<p>My friend Scott and I were discussing this sobering fact one night and we began wondering if any systems exist which provide end-to-end encryption for this insecure link.</p>
<p>Sure, there are plenty of solutions for people with access to cellular dataconnections, but what can voice call participants use to foil eavesdroppers?</p>
<p>We didn&#8217;t find any low-cost systems so we decided to create our own. OKCrypto is the Linux-based encrypting software modem that we&#8217;ve made. It consists of two components: the modem component and crypto component.</p>
<span id="The_modem__Hardware_components"><h3>The modem / Hardware components</h3></span>
<p>We needed the ability to send data before we could try sending  encrypteddata, so the first step was to design a simple software modem.</p>
<p>Rather than executing the modem code on the cell phones themselves, I decided to host the modem code on a the sender and receiver&#8217;s Linux systems. This design provides two benefits:</p>
<ol>
<li>The modem code and crypto code has access to the rich Linux API.</li>
<li>Sensitive code and data are isolated from the both the cell phone itself and from the cell infrastructure. We have clean separation between trusted (PC) and untrusted (cell) environments.</li>
</ol>
<p>Thus, the &#8220;real work&#8221; in OKCrypto is done on the PC &#8211; the cell phones simply allow the PCs to talk to each other. See figure 1 for an overview of the hardware involved in the system. 						<div class="flickr-gallery image right"><a href="http://www.flickr.com/photos/55502932@N00/4153181728"><img class="flickr small" title="Fig. 1 - Hardware components" alt="Fig. 1 - Hardware components" src="http://farm3.static.flickr.com/2534/4153181728_a0fe8e3a63_m.jpg" /></a></div>
					</p>
<p>Conceptually, the modem is similar to the analog Plain Old Telephone Service (POTS) modems from the Bad Old Days before broadband service became popular. Instead of an audio coupler, we&#8217;re using Bluetooth to connect our PC to our phone line. Instead of custom hardware, our modem is comprised of some glue scripts and the software packages they connect &#8211; all running on a Linux PC.</p>
<p>The modem doesn&#8217;t provide an asynchronous full-duplex communication link like traditional modems. This modem&#8217;s operation is simpler: The sender&#8217;s modem dials the number of, and subsequently transmits a pre-prepared chunk of data to, the recipient&#8217;s modem. It then hangs up.</p>
<p>The modem uses Dual-tone multi-frequency (DTMF) signaling to encode the data it transmits. I chose DTMF because I was familiar with it and because Debian provides a package for <a href="http://www.baycom.org/~tom/ham/linux/multimon.html">Multimon</a>. OKCrypto uses two utilities that Multimon provides:</p>
<ol>
<li>gen &#8211; a DTMF generation utility (digits-&gt;wav file)</li>
<li>multimon &#8211; a DTMF detection utility (wav file-&gt;digits)</li>
</ol>
<span id="Transmitting_audio_from_a_PC_to_a_cell_phone__Software_components"><h3>Transmitting audio from a PC to a cell phone / Software components</h3></span>
<p>I&#8217;d been working on a few Bluetooth security projects at the time, so the Hands-Free Profile (HFP)<sup>3</sup> came immediately to mind as a convenient way to transfer audio (and any data we&#8217;ve encoded in the audio) between a PC and a cell phone during a call.</p>
<p>-flickr size=&#8221;small&#8221; float=&#8221;right&#8221;-4153181752-/flickr-In most cases HFP is used to connect a a Bluetooth phone to a Bluetooth headset so that the headset can be used to make calls via the phone. See figure 2.</p>
<p>-flickr size=&#8221;small&#8221; float=&#8221;right&#8221;-4153181518-/flickr-In the PC world, HFP is typically used to connect a desktop computer to a bluetooth headset. See figure 3. In that configuration, the PC fulfills the first of two roles mandated by the HFP specification: the Audio Gateway (AG) role. The headset fulfills the hands-free (HF) role.</p>
						<div class="flickr-gallery image right"><a href="http://www.flickr.com/photos/55502932@N00/4152393267"><img class="flickr small" title="Fig. 4 - PC ~ Cell phone" alt="Fig. 4 - PC ~ Cell phone" src="http://farm3.static.flickr.com/2737/4152393267_95526e2aaf_m.jpg" /></a></div>
					For our purposes, we need the PC to appear to be a bluetooth headset to a cell phone &#8211; the PC must fulfill the HF role. See figure 4. This is similar to how call-handling in-vehicle GPS/stereo units work.</p>
<p>Support for the HF role in <a href="http://www.bluez.org/">bluez</a>, the Linux Bluetooth stack (pronounced &#8220;blue-zee&#8221;), is just now maturing<sup>4</sup> so I went searching for a userspace implementation of the HFP protocol stack.</p>
<p>One of the best, chan_mobile, is distributed as an add-on to the popular open-source private branch exchange (PBX) <a href="http://www.asterisk.org/">Asterisk</a> system. If you configure chan_mobile to use your cell phone, Asterisk can make both outbound calls and receive inbound calls with the phone.</p>
<p>Asterisk is the largest software component of the OKCrypto modem. It not only provides a reliable HFP HF role implementation which works with a wide array of modern phones (see above), but also many essential telephony operations:</p>
<ol>
<li>Recording audio during a call. OKCrypto uses Asterisk&#8217;s built-in voicemail capabilities.</li>
<li>Transmitting audio during a call.</li>
<li>Pausing for a given time period.</li>
<li>Logging phone call details.</li>
</ol>
<p>See figure 5 for an overview of the software components in the OKCrypto system. Note that the same software is used on both the sender and receiver&#8217;s PCs.						<div class="flickr-gallery image right"><a href="http://www.flickr.com/photos/55502932@N00/4153379126"><img class="flickr small" title="Fig. 5 - Software components" alt="Fig. 5 - Software components" src="http://farm3.static.flickr.com/2521/4153379126_22a0fbc569_m.jpg" /></a></div>
					
<span id="Demonstration__OKCrypto_scripts"><h3>Demonstration / OKCrypto scripts</h3></span>
<p>Let&#8217;s look at how we can use this modem to send a 16-byte binary file over a cellular voice connection.</p>
<p>First, the sender and recipient will need to perform some set-up steps:</p>
<ol>
<li>1. Acquire a Linux-supported computer and Bluetooth adapter. I found that using a virtual machine introduces latency that bluez/btusb cannot tolerate.</li>
<li>Acquire a HFP-capable cell phone.</li>
<li>Install Linux, <a href="http://sox.sourceforge.net/">SoX</a>, Python, multimon, Asterisk, the Asterisk &#8220;add-ons&#8221;, GPG, and the OKCrypto scripts.</li>
<li>Pair cell phone with computer. Grant HFP access.</li>
<li>Configure chan_mobile</li>
<li>Start Asterisk Next, the sender can issue this command at a shell to send the file &#8216;/tmp/foo&#8217; to the recipient at 585-555-3258.
<pre class="brush: bash;">$ ./bin_to_int_seq.py /tmp/foo | ./ast_send.sh 5855553258 [...]
$ cksum /tmp/foo 668417501 16 /tmp/foo</pre>
<p>She&#8217;ll notice her PC making a call with her phone, silently transmitting the data, and disconnecting. Behind the scenes, the OKCrypto scripts will&#8230;</li>
<li>Convert the bytes in /tmp/foo to a series of decimal digits.</li>
<li>Encode the digits as DTMF tones with gen from the multimon package. 1. Increase the pitch (time-independent) to prevent any intermediary systems (esp. Asterisk) from interpreting the tones.</li>
<li>Queue the final audio file for transmission by Asterisk.</li>
</ol>
<p>The recipient will hear his phone ring once before his PC answers the call, records the audio, and disconnects. When the call is complete, Asterisk will invoke one of the OKCrypto scripts to&#8230;</p>
<ol>
<li>Decrease the pitch to yield the original DTMF tones.</li>
<li>Decode the DTMF tones to a series of decimal digits.</li>
<li>Convert the digits to a series of bytes which is written to &#8216;/tmp/bar&#8217;.
<pre class="brush: bash;">$ tr -d '\n' &lt; /tmp/newest_vm.txt | ./int_seq_to_bin.py /tmp/bar [...]
$ cksum /tmp/bar 668417501 16 /tmp/bar</pre>
</li>
</ol>
<span id="Encryption"><h3>Encryption</h3></span>
<p>Now that we can reliably send data, let&#8217;s make sure that it&#8217;s encrypted first. This turns out to be one of the simplest components of the system &#8211; many good crypto APIs are available.</p>
<p>I use <a href="http://www.gnupg.org/">GnuPG</a>:</p>
<pre class="brush: bash;">$ gpg --symmetric --force-mdc --cipher-algo AES256 filetoencrypt </pre>
<p>The `&#8211;force-mdc` option provides integrity checking &#8211; useful for handling transmission errors. Consider these GPG options carefully and make sure they fit your requirements.</p>
<span id="Further_work"><h3>Further work</h3></span>
<p>Here are a few ideas we&#8217;re pursuing for the future of this project:</p>
<ul>
<li>Moving the modem code to the cell phone. This would simplify the setup but potentially risk security.</li>
<li>Improving modem error rate. Data is often erroneously duplicated during transmission.</li>
<li>Increasing the modem throughput. The current code averages a meager 10 bytes/second.</li>
<li>Hiding the data within a steganographic channel in a normal voice conversation.</li>
<li>Incorporating GPG into the OKCrypto scripts.</li>
<li>Packaging the system as a LiveCD/Live flash drive.</li>
<li>Implementing key exchange.</li>
<li>Building an embedded device dedicated to OKCrypto.</li>
</ul>
<span id="What_I_learned"><h3>What I learned</h3></span>
<p>I gained experience in the follow areas during the design, implementation. and testing:</p>
<ul>
<li>GSM, CDMA crypto. I suspect the cellular phone industry would make a great case study in protocol security by obscurity.</li>
<li>Cellular voice codecs used by large carriers. Trivia: your calls only require ~10kbps.<sup>5</sup></li>
<li>Bluetooth HFP specification and available implementations.</li>
<li>Debugging latency tolerances in virtual machine USB &#8220;passthrough&#8221; subsystems.</li>
<li>The <a href="http://www.twilio.com/">Twilio</a> telephony API. I used Twilio when I only had one cell phone to debug with.</li>
<li>Asterisk administration.</li>
</ul>
<span id="Conclusion__Download"><h3>Conclusion / Download</h3></span>
<p>I&#8217;ve described a method to securely transmit data over any of the widely-available cell voice networks. The implementation requires only commodity hardware, open-source software, and minimal setup.</p>
<p>Be aware that transmitting data by &#8220;automated means&#8221; may violate the terms of your cellular service contract. I disclaim all liability. This information is provided for educational purposes only.</p>
<p>You can download the OKCrypto system here: http://www.unsyncopated.com/corral/okcrypto_v0.1.tar.gz</p>
<p>It is licensed under the LGPL.</p>
<span id="Further_reading"><h3>Further reading</h3></span>
<ul>
<li>You&#8217;ll find lots of links to cell security architecture articles, Bluetooth HFP implementations, and Asterisk administration web pages on the wiki at <a href="http://www.unsyncopated.com/wiki/Crypto%20Phone/Stacked%20Linux-based%20CPhone%20Brainstorming">Crypto Phone/Stacked Linux-based CPhone Brainstorming</a></li>
</ul>
<p>Update 1/13/09 - Check out some technical notes on our recent progress with a faster and more reliable modem: <a href="https://www.unsyncopated.com/wiki/OKCrypto/Progress%20Report%20for%2001-09-2010">OKCrypto/Progress Report for 01-09-2010</a></p>
</div>
<ol class="footnotes">
<li id="footnote_0_317" class="footnote"><a href="http://spectrum.ieee.org/telecom/wireless/open-source-effort-to-hack-gsm">Open-Source Effort to Hack GSM</a> John Blau &#8211; IEEE Spectrum Magazine &#8211; December 2009 issue</li>
<li id="footnote_1_317" class="footnote"><a href="https://har2009.org/program/attachments/119_GSM.A51.Cracking.Nohl.pdf">Subverting the security base of GSM</a> Karsten Nohl &#8211; Hacking at Random &#8211; 8/15/2009</li>
<li id="footnote_2_317" class="footnote"><a href="http://www.bluetooth.com/Bluetooth/Technology/Works/HFP.htm">Bluetooth Hands-Free Profile (HFP) 1.5</a> &#8211; Bluetooth Special Interest Group &#8211; 11/25/2005</li>
<li id="footnote_3_317" class="footnote"><a href="https://bugs.maemo.org/show_bug.cgi?id=2754#c1">Comment #1 on Maemo bug #2754</a> &#8211; Johan Hedberg &#8211; 1/25/2009</li>
<li id="footnote_4_317" class="footnote"><a href="http://en.wikipedia.org/w/index.php?title=Adaptive_Multi-Rate_audio_codec&amp;oldid=327719647">Adaptive Multi-Rate audio codec</a> &#8211; Wikipedia &#8211; 11/24/2009</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://unsyncopated.com/blog/index.php/2009/11/19/sending-data-via-cellular-voice-connections-with-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Downloading photos from Facebook with Linux</title>
		<link>http://unsyncopated.com/blog/index.php/2009/11/02/downloading-photos-from-facebook-with-linux/</link>
		<comments>http://unsyncopated.com/blog/index.php/2009/11/02/downloading-photos-from-facebook-with-linux/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 02:37:49 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python programming]]></category>
		<category><![CDATA[Syntax highlighter]]></category>

		<guid isPermaLink="false">http://unsyncopated.com/blog/index.php/2009/11/03/downloading-photos-from-facebook-with-linux/</guid>
		<description><![CDATA[Tommy Murphy recently released photograbber, a simple Python/tkinter app that uses the Facebook API to&#8230; 1. Find all the photos that you&#8217;ve been tagged in and&#8230; 2. Download each photo to a chosen directory. It worked fine for me after I fixed a trivial tkinter bug. Right now I&#8217;m adapting photograbber to download entire albums [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://eat.ourbunny.com/">Tommy Murphy</a> recently released <a href="http://code.google.com/p/photograbber">photograbber</a>, a simple Python/tkinter app that uses the Facebook API to&#8230;</p>
<p>1. Find all the photos that you&#8217;ve been tagged in and&#8230;<br />
2. Download each photo to a chosen directory.</p>
<p>It worked fine for me after I <a href="http://code.google.com/p/photograbber/issues/detail?id=5">fixed a trivial tkinter bug</a>.</p>
<p>Right now I&#8217;m adapting photograbber to download entire albums for me. Here&#8217;s the crucial code that requests a collection of &#8220;photo&#8221; records using <a href="http://wiki.developers.facebook.com/index.php/FQL">Facebook Query Language</a> (FQL):</p>
<pre class="brush: python;">

photos = self.facebook.fql.query(&quot;SELECT pid, aid, src_big FROM &quot; \
&quot;photo WHERE pid IN (SELECT pid FROM photo_tag WHERE subject=&quot; + \
str(self.facebook.uid) + &quot;)&quot;)
</pre>
<p>Changing the query to&#8230;</p>
<pre class="brush: python;">

&quot;SELECT pid, aid, src_big FROM photo WHERE aid IN (SELECT aid &quot; \
&quot;FROM album WHERE owner IN (SELECT uid FROM user WHERE name=\&quot;&quot; + \
FriendName + &quot;\&quot;) AND name=\&quot;&quot; + AlbumName + &quot;\&quot;)&quot;
</pre>
<p>&#8230; did the trick. Caveat coder: the album IDs that you see in your browser while surfing Facebook <em>aren&#8217;t</em> the same IDs that you should use in your FQL queries. If you slip up, you might receive this misleading message: &#8220;FacebookError: Error 600: An unknown error occurred in FQLPhotoTable::get_ids_for_queries:  should never have a pid or aid without a uid&#8221;</p>
<p>Keep <a href="http://www.facebook.com/terms.php">Facebook&#8217;s terms of service</a> in mind when interacting with their site &#8211; you don&#8217;t want a &#8220;cease and desist&#8221; letter like <a href="http://www.vincentcheung.ca/blog/facedown/cease-and-desist/">Vincent Cheung received for his &#8220;FaceDown&#8221; application</a>.</p>
<p>If all else fails, you might have some luck with a PHP script called &#8220;FBCMD&#8221; as illustrated <a href="http://dieter.plaetinck.be/a_script_that_pulls_photos_from_facebook">here</a>. There&#8217;s also a .NET standalone app: <a href="http://rajitss.com/albumdownloader/index.php">The RajitSS Album Downloader</a>.</p>
<p>I&#8217;ll spare you my internet balkanization rant &#8211; Fred Vogelstein made the argument far better in the June issue of Wired: <a href="http://www.wired.com/techbiz/it/magazine/17-07/ff_facebookwall?currentPage=all">Great Wall of Facebook &#8211; The Social Network&#8217;s Plan to Dominate the Internet &#8211; and Keep Google Out</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://unsyncopated.com/blog/index.php/2009/11/02/downloading-photos-from-facebook-with-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Flickr macro for MoinMoin</title>
		<link>http://unsyncopated.com/blog/index.php/2009/02/24/a-flickr-macro-for-moinmoin/</link>
		<comments>http://unsyncopated.com/blog/index.php/2009/02/24/a-flickr-macro-for-moinmoin/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 20:59:50 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Flickr]]></category>
		<category><![CDATA[Python programming]]></category>
		<category><![CDATA[Syntax highlighter]]></category>

		<guid isPermaLink="false">http://unsyncopated.com/blog/index.php/2009/02/25/a-flickr-macro-for-moinmoin/</guid>
		<description><![CDATA[Would you like to include Flickr photos in your MoinMoin wiki pages? Here&#8217;s a MoinMoin macro that allows you to do just that. The code is a little ugly, but I was inspired by this affirmation of the &#8220;release early, release often&#8221; philosophy to make the source available. Slide on over to my wiki to [...]]]></description>
			<content:encoded><![CDATA[<p>						<div class="flickr-gallery image right"><a href="http://www.flickr.com/photos/wka/1627089248"><img class="flickr small" title="Flickr logo II" alt="Flickr logo II" src="http://farm3.static.flickr.com/2260/1627089248_a53be86ce7_m.jpg" /></a></div>
					<br />
Would you like to include Flickr photos in your MoinMoin wiki pages? Here&#8217;s a MoinMoin macro that allows you to do just that.</p>
<p>The code is a little ugly, but I was inspired by <a href="http://www.contrast.ie/blog/fail-early-fail-often-and-learn/">this affirmation of the &#8220;release early, release often&#8221; philosophy</a> to make the source available.</p>
<p>Slide on over to my wiki to see the <a href="http://unsyncopated.com/wiki/MoinMoin_Flickr_Macro">my design notes for this macro</a>.</p>
<pre class="brush: python;">

#!/usr/bin/env python

&quot;&quot;&quot;
    MoinMoin - Flickr Macro

    A macro to embed Flickr photos on wiki pages.

    Usage: &lt;&gt;

    Parameters:

      photo_id: The ID of the photo you want to embed. You can find
                this within most Flickr URLS.
      size:     One of &quot;Square&quot;, &quot;Thumbnail&quot;, &quot;Small&quot;, &quot;Medium&quot;,
                or &quot;Original&quot;

    @copyright: 2009 by MoinMoin:TylerOderkirk
    @license: GNU GPL.
&quot;&quot;&quot;

from MoinMoin import wikiutil
import flickrapi

def execute(macro, args):

    argParser = wikiutil.ParameterParser(&quot;%(photo_id)i%(size)s&quot;)
    argDict = argParser.parse_parameters(args)
    # print argDict
    # photoid
    photoID = argDict[1][&quot;photo_id&quot;] # &quot;444769890&quot;
    desiredSize = argDict[1][&quot;size&quot;] # &quot;Medium&quot;
    # size Square, Thumbnail, Small, Medium, Original
    # TODO: add img caching/backup
    # TODO: logging as to not overuse API key.
    # TODO: store api_key somewhere else. wikiconfig.py?

    api_key = 'BEEEEEEEEEEEEEEEF'

    flickr = flickrapi.FlickrAPI(api_key)
    sizes = flickr.photos_getSizes(photo_id=photoID)
    info = flickr.photos_getInfo(photo_id=photoID)

    photoSourceURL = &quot;asdf&quot;
    for i in sizes.sizes[0].size:
        # print i['label']
        if i['label'] == desiredSize:
            photoSourceURL = i['source']

    # TODO: ensure this is an URL of type 'photopage'. ref
    # http://www.flickr.com/services/api/flickr.photos.getInfo.html
    photoPageURL = info.photo[0].urls[0].url[0].text
    photoDescription = info.photo[0].description[0].text
    # TODO: XSS here?
    photoTitle = info.photo[0].title[0].text
    photoAuthorUsername = info.photo[0].owner[0]['username']

    # print photoSourceURL, photoPageURL, photoDescription

    # TODO: wrap/truncate long titles. maybe put credits on new line?
    # TODO: potentially include description instead of title

    # TODO: use moin markup for table instead of raw html
    # ref. http://moinmo.in/MacroMarket/MiniPage
    # ref. http://unsyncopated.com/BrainSolvent/MoinMoin Flickr
    #       Macro?action=diff&amp;rev2=29&amp;rev1=28
    #  pypaper.py
    # Thanks to NirSoffer for the CSS
    # ref. http://moinmo.in/HelpOnTables
    return '
&lt;div&gt;
'\
     '
'\
     '&lt;a href=&quot;%s&quot;&gt;&lt;img title=&quot;%s&quot; src=&quot;%s&quot; alt=&quot;%s&quot; /&gt;'\
     '&lt;/a&gt;
%s (Flickr image by'\
     '%s)
&lt;table style=&quot;float: right; font-size: 0.85em; '\&amp;lt;br /&amp;gt;
     'background: #eeeeee; margin: 0 0 1em 1em;&quot;&gt;
&lt;tbody&gt;&lt;/tbody&gt;
&lt;tbody&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
' % (photoPageURL,
     photoTitle, photoSourceURL,photoTitle, photoTitle,
     photoAuthorUsername )

if __name__ == &quot;__main__&quot;:
    print( execute( 0, &quot;photo_id=2088619558,size=Small&quot; ) )4153379126
</pre>
<span id="Caveats"><h3>Caveats</h3></span>
<ul>
<li>Beware copyrighted photos. Luckily, Flickr allows you to specify license criteria on their &#8220;advanced search&#8221; page. I use <a href="http://yubnub.org/kernel/man?args=flcc">yubnub&#8217;s &#8220;flcc&#8221; command</a> to do this.</li>
<li>If the macro experiences an error at runtime and you have MoinMoin tracebacks enabled the tracebacks will contain your Flickr API key. Patches welcome `;]`</li>
</ul>
<p><strong>Update 3-1-09</strong>: Flickr&#8217;s API <a href="http://www.flickr.com/help/forum/en-us/91205/page2/#reply604216">just went down</a>. Seems like a good time to implement exception handling `:]`. Email me for the updated code.</p>
]]></content:encoded>
			<wfw:commentRss>http://unsyncopated.com/blog/index.php/2009/02/24/a-flickr-macro-for-moinmoin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Graphing OpenMoko community membership by country of residence</title>
		<link>http://unsyncopated.com/blog/index.php/2009/01/15/graphing-openmoko-community-membership-by-country-of-residence/</link>
		<comments>http://unsyncopated.com/blog/index.php/2009/01/15/graphing-openmoko-community-membership-by-country-of-residence/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 13:09:37 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Python programming]]></category>

		<guid isPermaLink="false">http://unsyncopated.com/blog/index.php/2009/01/15/graphing-openmoko-community-by-country-of-residence/</guid>
		<description><![CDATA[A group at the Swiss Federal Institute of Technology recently published the results of their survey of OpenMoko community members. I&#8217;ve graphed their data on survey respondents&#8217; country of origin: I&#8217;ve thresholded the output at 1% i.e. countries whose respondents accounted for less than one percent of the total are omitted from the graph. This [...]]]></description>
			<content:encoded><![CDATA[<p>A group at the Swiss Federal Institute of Technology recently published <a href="http://public.smi.ethz.ch/files/MaemoOpenmoko/PublicDescriptiveStatistics.html">the results of their survey of OpenMoko community members</a>.</p>
<p>I&#8217;ve graphed their data on survey respondents&#8217; country of origin:</p>
<p><img class="alignnone" title="" src="http://chart.apis.google.com/chart?chl=AU|AT|BE|CA|DK|FI|FR|DE|IN|IT|NL|NZ|NO|PL|ES|SE|CH|GB|US&amp;chs=300x220&amp;cht=p&amp;chd=t:3.98,1.74,1.74,3.73,1.99,1.37,4.73,15.92,3.23,3.86,3.73,1.37,2.49,2.24,2.99,2.86,2.11,5.6,22.51" alt="" width="300" height="220" /></p>
<p>I&#8217;ve thresholded the output at 1% i.e. countries whose respondents accounted for less than one percent of the total are omitted from the graph.</p>
<p>This data jives with the webserver traffic logs we saw for <a href="http://unsyncopated.com/wiki/Doom Port">Scott&#8217;s Doom Port</a>. Greetz to all you German developers!</p>
<span id="Why_not_a_map"><h3>Why not a map?</h3></span>
<p>In short, I couldn&#8217;t find a collection of colors (i.e. a gradient, the `chco` parameter) that looked good for this data set. This is about the best I could do:</p>
<p><img class="alignnone" title="" src="http://chart.apis.google.com/chart?chd=t:0.12,0.25,3.98,1.74,0.0,0.12,1.74,0.12,0.75,0.12,3.73,0.25,0.25,0.25,0.12,1.0,1.99,0.0,0.12,0.37,1.37,4.73,15.92,0.12,0.37,0.62,3.23,0.0,0.25,0.37,0.87,3.86,0.12,0.12,0.37,0.0,0.37,3.73,1.37,0.12,2.49,0.12,0.0,2.24,0.87,0.5,0.75,0.0,0.0,0.0,0.25,0.62,2.99,2.86,2.11,0.5,0.0,0.25,0.37,0.0,5.6,22.51,0.0,0.0&#038;chf=bg,s,f5f5f5&#038;chco=f5f5f5,edf0d4,6c9642,365e24,13390a&#038;chtm=world&#038;chld=ADARAUATBDBYBEBABRBGCACLCNCOCRCZDKDOEGEEFIFRDEGRHKHUINIDIRIEILITJOLVLTMYMXNLNZNGNOPYPEPLPTRORURWSGSKSIZAESSECHTWTHTRUAAEGBUSVEZM&#038;chs=440x220&#038;cht=t" alt="" width="440" height="220" /></p>
<span id="Colophon"><h3>Colophon</h3></span>
<p>The script that generated that chart&#8217;s parameters is below. It uses BeautifulSoup to dig the data out of HTML. It uses <a href="http://code.google.com/p/google-chartwrapper/">GChartWrapper</a> to generate the chart&#8217;s parameters.</p>
<pre class="brush: python;">

#!/usr/bin/env python

from BeautifulSoup import BeautifulSoup
import urllib2
import sys
import re
from GChartWrapper import Map, Pie3D, Pie

# REF http://www.crummy.com/software/BeautifulSoup/documentation.html
# REF http://www.amk.ca/python/howto/regex/
# REF http://www.python.org/doc/2.4.1/lib/string-methods.html
# REF http://code.google.com/p/google-chartwrapper/

def main(argv=None):
page = urllib2.urlopen(&quot;http://public.smi.ethz.ch/files/MaemoOpenmoko/&quot;
&quot;PublicDescriptiveStatistics.html&quot;)
soup = BeautifulSoup(page)
# the 457th (zero-indexed) table row is the row that contains the first
#  country (e.g. andorra). the 521st row is the last country (e.g. zambia)
j=0
countryCodeList = &quot;&quot;
colorLevelList = &quot;&quot;
for curRow in soup.findAll(&quot;tr&quot;)[457:521]:
# the first (zero-indexed) paragraph contains the country name.
r = re.compile(&quot;\((.*)\)&quot;)
m = r.search(curRow.findAll(&quot;p&quot;)[0].contents[0])
foo = m.group(1)

# the fourth contains the openmoko percentage.
bar = float(curRow.findAll(&quot;p&quot;)[4].contents[0].replace(&quot;%&quot;,&quot;&quot;))
# let's threshold at 1%
if bar &gt; 1.0:
print foo, &quot;,&quot;, bar
colorLevelList += str(bar)
colorLevelList += &quot;,&quot;
countryCodeList += &quot;'&quot; + foo + &quot;'&quot;
countryCodeList += &quot;,&quot;
#print &quot;qqq&quot;, j, curRow.contents
j=j+1

# PUZZLE: can i avoid this annoying step somehow?
colorLevelList = colorLevelList.rstrip(&quot;,&quot;)
countryCodeList = countryCodeList.rstrip(&quot;,&quot;)

# print some debugging info
print colorLevelList, &quot;----&quot;, countryCodeList

# let's make a chart of type &quot;map&quot;
myChart = Map(colorLevelList, encoding='text')
myChart.color( 'f5f5f5','91b86c','6c9642','365e24','13390a')
myChart.fill('bg','s','eaf7fe') # f37b00 is 'openmoko orange'
myChart.size(440,220) # default is 300x150
myChart.map('world', countryCodeList)
print myChart

# let's make a chart of type &quot;pie&quot;. mmm.
herChart = Pie(colorLevelList, encoding='text')
herChart.size(300, 220)
# PUZZLE: can one, at runtime, use a list for a method call's arguments?
eval( &quot;herChart.label(&quot; + countryCodeList + &quot;)&quot;)
print herChart

if __name__ == '__main__':
sys.exit(main())
</pre>
<span id="Potential_improvements"><h3>Potential improvements</h3></span>
<ul>
<li><span style="font-size: 13.3333px;"><a href="http://manyeyes.alphaworks.ibm.com/manyeyes/visualizations/world-map-smokers-countrys-populatio">IBM&#8217;s Many Eyes</a></span></li>
<li><span style="font-size: 13.3333px;"><a href="http://code.google.com/apis/visualization/documentation/gallery/intensitymap.html">Visualization: Intensity Map &#8211; Google Visualization API &#8211; Google Code</a></span></li>
</ul>
<span id="See_also"><h3>See also</h3></span>
<ul>
<li><span style="font-size: 13.3333px;"><a href="http://unsyncopated.com/wiki/Switching to Linux/Software to Try#Graphics">Switching to Linux/Software to Try#Graphics</a> &#8211; Other visualization tools.</span></li>
<li><span style="font-size: 13.3333px;"><a href="http://unsyncopated.com/wiki/OpenMoko/Growth">OpenMoko/Growth</a> &#8211; Notes on graphing community growth.</span></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://unsyncopated.com/blog/index.php/2009/01/15/graphing-openmoko-community-membership-by-country-of-residence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
