<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Bryce Boe</title>
	
	<link>http://www.bryceboe.com</link>
	<description>The Adventures of a UCSB Computer Science Ph.D. Candidate and reddit Open Sorcerer</description>
	<lastBuildDate>Sun, 12 May 2013 07:00:51 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BryceBoe" /><feedburner:info uri="bryceboe" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Mother’s Day</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/F-Z1_xezK0o/</link>
		<comments>http://www.bryceboe.com/2013/05/12/mothers-day/#comments</comments>
		<pubDate>Sun, 12 May 2013 07:00:51 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[family]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=1062</guid>
		<description><![CDATA[Many people in the US show appreciation for their mother on the second Sunday of May. While Mother&#8217;s Day may be more commercial, and directed differently than originally intended [ref], I will use the day to thank two women, both mothers, who have made and continue to make a significant impact on my life. First [...]]]></description>
				<content:encoded><![CDATA[<p>Many people in the US show appreciation for their mother on the second Sunday of May. While Mother&#8217;s Day may be more commercial, and directed differently than originally intended [<a href="http://www.babble.com/mom/relationships/anna-jarvis-mothers-day-history-gifts-enough-thank-you/">ref</a>], I will use the day to thank two women, both mothers, who have made and continue to make a significant impact on my life.</p>
<p>First and foremost is my own mother. She brought me into this world, helped raise me (along with my other brothers) and did her best with what she had (sometimes with more than what she had) in order to give me what I required to succeed at a young age. Sadly, recalling concretely how my mother has impacted my life is rather difficult as I am not aware of all the decisions she made on my behalf while I was unable to comprehend them. I do recall, however, after my parents divorce when money was no longer in abundance, a handful of situations where my mother made financial compromises in order to provide me with the essentials for the sports I played, the classes I took, or the other activities I participated in. Most notably she gave in to my request (possibly demand) for broadband Internet thus allowing me learn and explore new facets of technology at a pace that kept me glued to the computer. My mother, whether intentionally or not, gave me many freedoms to do what I desired. This freedom significantly contributed to my independence, which I strongly feel has helped me throughout my adult life. My mother has helped shape me as a person and as such I am incredibly grateful for her impact on my life.</p>
<p>By high school I was a fairly independent person. Due to having access to a car that I paid for, in combination with having two homes not more than ten miles apart, I effectively removed any method of discipline my parents wanted to enforce. While I was occasionally disrespectful to my parents at this time, that disrespect was never directed toward anyone else. When I started dating my high school girlfriend, I was quickly welcomed into her family. As such, Cheri, my high school girlfriend&#8217;s mother, became like a second mother to me at a time when I most needed it. There are numerous times that Cheri (and Tom, but this is Mother&#8217;s Day) encouraged, supported and pushed me to accomplish something. Most notably, Cheri ensured I completed what was necessary to apply for college, when the thought never significantly occurred to me. I distinctly remember sitting in their office on the day of the (extended) UC application deadline being pushed to finish my personal statement, and going through a number of revisions with her. The support I received from Cheri that day may very well have had the single largest impact on my future, and for that I am eternally grateful to Cheri, my second mother.</p>
<p>Both these women, have played a crucial rule in my life. My mother playing a significant part in shaping who I am, and Cheri in pushing me to a brighter future. I would not be where I am today without the numerous things that these women have done for me. Thank you both for everything you have done. I love you both. Happy Mother&#8217;s day.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2013/05/12/mothers-day/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2013/05/12/mothers-day/</feedburner:origLink></item>
		<item>
		<title>Time Zones in Python and Date/Time Representations</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/XcVarG4G2vU/</link>
		<comments>http://www.bryceboe.com/2012/11/05/time-zones-in-python-and-datetime-representations/#comments</comments>
		<pubDate>Mon, 05 Nov 2012 09:57:31 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[time zones]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=1033</guid>
		<description><![CDATA[Early yesterday morning many people gained an extra hour by repeating the second hour of the day. Those people in time zones that were previously on daylight saving time switched back to standard time and thus may have observed their digital devices record the following sequence of times: 2012-11-04 01:59:58 2012-11-04 01:59:59 2012-11-04 01:00:00 2012-11-04 [...]]]></description>
				<content:encoded><![CDATA[<p>Early yesterday morning many people gained an extra hour by repeating the second hour of the day. Those people in time zones that were previously on <a href="http://en.wikipedia.org/wiki/Daylight_saving_time">daylight saving time</a> switched back to standard time and thus may have observed their digital devices record the following sequence of times:</p>
<p><code>2012-11-04 01:59:58<br />
2012-11-04 01:59:59<br />
2012-11-04 01:00:00<br />
2012-11-04 01:00:01</code></p>
<p>The written timestamps make it appear as if time went back one hour, when of course time continued to proceed linearly. This perceived repetition of an hour can be a problem for computer systems that output dates in localized formats. For instance, python&#8217;s logging package produces log entries using a human-readable time. However, by <a href="http://docs.python.org/2/library/logging.html#logging.Formatter.formatTime">default</a>, these human readable times are in localized formats. That means an event could be logged as happening before a preceding event when the localized time zone experiences a change in daylight saving time.</p>
<p>An obvious solution to this problem is to not take into consideration daylight saving time when working with time. For people in the pacific time zone, that could mean always using pacific standard time (<a href="http://en.wikipedia.org/wiki/Pacific_Time_Zone">PST</a>). Likewise for people in the eastern time zone, they could always use eastern standard time (<a href="http://en.wikipedia.org/wiki/Eastern_Time_Zone">EST</a>). Continuing with the log file example, this means all events in a log files will appear linearly. The trade-off is anyone looking at log entries during daylight saving time needs to keep in mind the one hour difference when determining how long ago a logged event actually occurred.</p>
<p>A separate issue has to do with keeping track of dates and times between machines in different time zones. For simplicity, we&#8217;ll ignore the problem of clock synchronization and assume all the machines have the correct time set. The issue is that even when using standard times (non daylight saving times) on respective machines, dates and times on different machines cannot be compared in a human readable format without including time zone specific information. </p>
<p>Fortunately computers need not use a human readable format to store dates and times. In fact, most computers already internally keep track of time using <a href="http://en.wikipedia.org/wiki/Unix_time">unix timestamps</a> that store dates and times as the number of seconds since an agreed upon date and time in coordinated universal time (<a href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a>). In spite of this solution to synchronize dates and times from different time zones, issues such as the logging problem still occur. In the remainder of this article we will look at a few causes of those problems and how to solve them in the context of python. </p>
<p>Within python there are two primary ways to store date and time information. The first, is the unix timestamp, which was previously discussed. Although unix timestamps are time zone agnostic, the major problem is that it is not simple for a human to determine properties about a unix timestamp without first converting to another format. For instance, what day of the month does the unix timestamp <code class="inline">1325448000</code> represent? And, how many years does the previous unix timestamp differ from <code class="inline">473414400</code>? To help answer such questions, programming languages usually have a date and time representation that can be created from unix timestamps. In python, this representation is accomplished through the <a href="http://docs.python.org/2/library/datetime.html#datetime-objects">datetime</a> object:</p>
<p><code>&gt;&gt;&gt; from datetime import datetime<br />
>>> print(datetime.fromtimestamp(1325448000))<br />
2012-01-01 12:00:00<br />
>>> print(datetime.fromtimestamp(473414400))<br />
1985-01-01 00:00:00</code></p>
<p>Using the datetime representation you should be able to more easily answer the previous questions. If you execute the above code, some of you might wonder why <code class="inline">print(datetime.fromtimestamp(1325448000))</code> does not produce the same result on your computer. The difference is due to the fact that datetime objects are created in the context of the local time zone by default. On my system, the local time zone is &#8220;America/Los_Angeles&#8221;, which corresponds to either PST or PDT depending on the time of year. With that in mind let&#8217;s look at instances of datetime around the end of daylight savings time 2012.</p>
<p><code>&gt;&gt;&gt; a = datetime.fromtimestamp(1352019599)<br />
>>> b = datetime.fromtimestamp(1352019600)<br />
>>> print((b - a).total_seconds())<br />
-3599.0</code></p>
<p>Although the timestamp for <em>a</em> is one second less than the timestamp for <em>b</em>, it appears as if <em>b</em> represents a time 3599 seconds (one second less than one hour) prior to <em>a</em>. The reason is that, in addition to datetime objects using the localized time zone by default, they do not maintain the time zone information by default. Thus, naïve datetime objects, that is, those without time zone information, are only compared by their values. Below are the values for <em>a</em> and <em>b</em> from the previous example:</p>
<p><code>&gt;&gt;&gt; print(a)<br />
2012-11-04 01:59:59<br />
>>> print(b)<br />
2012-11-04 01:00:00</code></p>
<p>While these values are correct, we should also be able to compare them correctly. Fortunately python&#8217;s datetime objects allow us to also associate time zone information. Unfortunately, the easiest way is through the non-standard package <a href="http://pytz.sourceforge.net/">pytz</a>. With pytz we can easily create time zone specific datetime objects. Doing so will solve the comparison problem:</p>
<p><code>&gt;&gt;&gt; import pytz<br />
>>> a = datetime.fromtimestamp(1352019599, pytz.timezone('America/Los_Angeles'))<br />
>>> b = datetime.fromtimestamp(1352019600, pytz.timezone('America/Los_Angeles'))<br />
>>> print((b - a).total_seconds())<br />
1.0<br />
>>> print(a)<br />
2012-11-04 01:59:59-07:00<br />
>>> print(b)<br />
2012-11-04 01:00:00-08:00</code></p>
<p>In the previous example we get a <a href="http://docs.python.org/2/library/datetime.html#datetime.tzinfo">tzinfo</a> object by calling <code class="inline">pytz.timezone('America/Los_Angeles')</code> and use that in creating the datetime object. Note that the time zone selected only affects how the datetime object is represented. Observe that the following two datetime objects are the same despite their different representation:</p>
<p><code>&gt;&gt;&gt; a = datetime.fromtimestamp(1352019599, pytz.timezone('America/Los_Angeles'))<br />
>>> b = datetime.fromtimestamp(1352019599, pytz.timezone('America/New_York'))<br />
>>> a == b<br />
True<br />
>>> print(a)<br />
2012-11-04 01:59:59-07:00<br />
>>> print(b)<br />
2012-11-04 03:59:59-05:00</code></p>
<p>It should now be obvious that it is always a good idea to create datetime objects with time zone information included. Two other common ways of creating datetime objects with time zone information are <code class="inline">datetime.now(pytz.timezone('America/Los_Angeles'))</code> to create a datetime object of the current date and time and <code class="inline">datetime(2012, 11, 4, 1, 0, tzinfo=pytz.timezone('America/Los_Angeles'))</code> to create a datetime object for a specific date and time.</p>
<p>With time zone specific datetime objects, it&#8217;s trivial to get a localized representation for any time zone through the <a href="http://docs.python.org/2/library/datetime.html#datetime.datetime.astimezone">astimezone</a> function:</p>
<p><code>&gt;&gt;&gt; print(a)<br />
2012-11-04 01:59:59-07:00<br />
>>> print(a.astimezone(pytz.timezone('America/New_York')))<br />
2012-11-04 03:59:59-05:00<br />
>>> print(a.astimezone(pytz.UTC))<br />
2012-11-04 08:59:59+00:00</code></p>
<p>Thus far we&#8217;ve shown that using unix timestamps is great for date and time consistency between machines at the cost of not being human readable. We then gave a brief overview of datetime objects, including how to create them from unix timestamps. Most importantly we showed that datetime objects are time zone agnostic by default. We then showed how to include time zone information in datetime objects and how to convert between various local datetime representations. We will now show how to correctly convert from datetime objects back to the correct unix timestamp.</p>
<p>In the python standard library there is nothing that directly converts from datetime objects to unix timestamps. However, there are two functions, <a href="http://docs.python.org/2/library/time.html#time.mktime">time.mktime</a>, and <a href="http://docs.python.org/2/library/calendar.html#calendar.timegm">calendar.timegm</a> that will create timestamps from <a href="http://docs.python.org/2/library/time.html#time.struct_time">struct_time</a> objects. These functions, in combination with the datetime <a href="http://docs.python.org/2/library/datetime.html#datetime.date.timetuple">timetuple</a> functions, allow for the conversion. The primary difference between <strong>time.mktime</strong> and <strong>calendar.timegm</strong> is that <strong>time.mktime</strong> expects the struct_time object to store the date and time information in the system localized time zone, whereas <strong>calendar.timegm</strong> expects the date and time information to be stored in UTC.</p>
<p>Making no assumptions about the time zone the datetime object is currently represented in, the following shows how to convert a datetime object to a unix timestamp using <strong>time.mktime</strong>:</p>
<p><code>&gt;&gt;&gt; import time<br />
>>> import pytz.reference<br />
>>> a = datetime.fromtimestamp(1352019599, pytz.timezone('America/New_York'))<br />
>>> time.mktime(a.astimezone(pytz.reference.LocalTimezone()).timetuple())<br />
1352019599.0</code></p>
<p>Notice that we must first convert the datetime object, <em>a</em>, into its identical representation in our localized time zone before calling timetuple. The <code class="inline">pytz.reference.LocalTimezone()</code> code prevents us from needing to hard-code our localized time zone.</p>
<p>The second approach to convert from a datetime object to a unix timestamp is to first convert to UTC and then use <strong>calendar.timegm</strong>:</p>
<p><code>&gt;&gt;&gt; import calendar<br />
>>> calendar.timegm(a.utctimetuple())<br />
1352019599</code></p>
<p>When using <strong>calendar.timegm</strong> we can conveniently use the datetime <a href="http://docs.python.org/2/library/datetime.html#datetime.datetime.utctimetuple">utctimetuple</a> function rather than using the astimezone function.</p>
<p>At this point you should have a decent grasp on converting between unix timestamps and time zone sensitive datetime objects in the context of python applications. If you are anything like me, you will now <em>always</em> create datetime objects with time zone information and ponder why that is not the python library default.</p>
<p>In a future blog post (if I ever get around to it) I will look at storing and retrieving datetime objects in databases using sqlalchemy. A few questions I have are:</p>
<ul>
<li>When the python application and the database are in different time zones, how are the datetime objects represented?</li>
<li>What happens when either the database or the python application changes time zones?</li>
</ul>
<p>That&#8217;s all for now. Happy coding!</p>
<p><ins datetime="2012-11-06T20:14:01+00:00">Update</ins>: I just discovered that python 3.3 now has a <code class="inline">datetime.timestamp</code> function which handles the conversion from datetime objects to unix timestamps (<a href="http://docs.python.org/dev/library/datetime.html#datetime.datetime.timestamp">source</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2012/11/05/time-zones-in-python-and-datetime-representations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2012/11/05/time-zones-in-python-and-datetime-representations/</feedburner:origLink></item>
		<item>
		<title>Bypassing Gogo’s Inflight Internet Authentication</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/I-tZmO_l7Sw/</link>
		<comments>http://www.bryceboe.com/2012/03/12/bypassing-gogos-inflight-internet-authentication/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 00:19:29 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=1025</guid>
		<description><![CDATA[Two weeks ago I attended SIGCSE 2012 in Raleigh, NC. The plane on my return flight had Internet access through Gogo&#8217;s Inflight Internet. While I think it&#8217;s incredibly awesome that Internet access is readily available to those who travel by plane, I personally feel it is not worth $12.95 for a few hours of access. [...]]]></description>
				<content:encoded><![CDATA[<p>Two weeks ago I attended <a href="http://www.sigcse.org/sigcse2012/">SIGCSE 2012</a> in Raleigh, NC. The plane on my return flight had Internet access through <a href="http://www.gogoair.com/">Gogo&#8217;s Inflight Internet</a>. While I think it&#8217;s incredibly awesome that Internet access is readily available to those who travel by plane, I personally feel it is not worth $12.95 for a few hours of access. Nevertheless, I figured I&#8217;d simply connect to Gogo&#8217;s network to see what sort of access was permitted to non-authenticated, i.e.,  non-paying, users. What I discovered surprised me: I was able to gain access to the entire Internet.</p>
<p>Immediately from links on their landing page it was apparent that Gogo permitted access to its own website, as well as the airline&#8217;s website and a few other third-party sites such as <a href="livingsocial.com">Living Social</a>, and <a href="http://eventful.com/">Eventful</a>. Attempting to access any other website resulted in a redirect to Gogo&#8217;s landing page. Gogo appears to accomplish this by responding with an HTTP redirect to any standard HTTP request, i.e., port 80, that is sent to a non-permitted IP address.</p>
<p>Two common techniques for bypassing pay-for-wireless providers are <a href="http://www.cs.uit.no/~daniels/PingTunnel/">TCP-over-ICMP</a> and <a href="http://analogbit.com/tcp-over-dns_howto">TCP-over-DNS</a>. In a nutshell, TCP is the protocol required to browse the web, ICMP is the protocol used by the command `ping` to determine if a host is available, and DNS is required to resolve domain names like <a href="http://www.google.com">www.google.com</a> to an IP address. When TCP is not completely available yet either ICMP or DNS is, then it is possible to encapsulate TCP connections over the other available protocol. Gogo blocked my ping attempts, hence TCP-over-ICMP was not possible. However, while Gogo doesn&#8217;t permit direct access to external DNS servers, Gogo&#8217;s DNS server recursively resolved the DNS queries I made. Therefore, Gogo appears to be susceptible to TCP-over-DNS. Despite not being able to verify this finding, I will simply state that Gogo can remedy this, if necessary, by only responding to white-listed DNS queries for non-authenticated users.</p>
<p>As a quick aside, I would like to mention I made an attempt to responsibly disclose this information to Gogo prior to posting this article [<a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2012/03/gogo_dm.png" target="_blank">1</a>, <a href="https://twitter.com/#!/Gogo/status/176504298967015424">2</a>]. I contacted one of their twitter representatives via email who informed me the right person would contact me. After a few days with no response, I sent a follow up email to the same twitter representative. While that representative has continued to tweet since my followup, I have received no replies. Thus, I have come to the conclusion that Gogo is uninterested. I proceed with the knowledge that this authentication bypass in no way compromises Gogo&#8217;s security; therefore, it is of negligible importance to Gogo&#8217;s existing customers. Finally, I proceed knowing very well that Gogo&#8217;s sysadmins can correct the underlying problem in a very brief period of time and I even present them with the solution.</p>
<p>♫<a href="http://www.youtube.com/watch?v=GI6CfKcMhjY&#038;t=1m37s">Now back to the good part</a>!♫</p>
<p>I use <a href="https://www.google.com/chrome">Google Chrome</a> as my primary browser and along with it I have installed a few extensions that depend on connections to various Google services. When Chrome is open and does not have a connection to the Internet, some of these extensions, such as the <a href="https://chrome.google.com/webstore/detail/apflmjolhbonpkbkooiamcnenbmbjcbf">Google Reader Notifier</a>, adjust their icon to indicate their disconnected status. As expected, the Google Reader Notifier extension indicated that I was not connected to the Internet. However, as I was browsing around Gogo&#8217;s landing page and permitted sites, I was shocked when the <a href="https://chrome.google.com/webstore/detail/kcnhkahnjcbndmmehfkdnkjomaanaooo">Google Voice</a> extension notified me of a new text message and shocked again when I successfully replied. I had mistakenly stumbled across a hole in Gogo&#8217;s access policies and decided to dig deeper.</p>
<p>As I previously mentioned, Gogo redirected to their landing page upon any standard HTTP request. However, the same was not true for HTTPS connections, which by default occur on TCP port 443. Thus, for some unknown reason, my computer was able to connect to <a href="http://www.google.com">www.google.com</a> via HTTPS. Immediately I tried other Google services, like <a href="http://mail.google.com">mail.google.com</a> for Gmail, and <a href="http://docs.google.com">docs.google.com</a> for Google docs; neither worked. Nevertheless, any Google service accessible via HTTPS and addressed under the <a href="http://www.google.com">www.google.com</a> domain worked flawlessly.</p>
<p>After poking around to find a list of Google services meeting these requirements, I had an epiphany. While I probably learned this information at some point in my past, I had a hunch that Google&#8217;s front-end web servers would likely provide the correct response to any Google web service. Hence, I opened up my /etc/hosts file on my OS X machine, and added the following line:</p>
<p><code>74.125.225.40 mail.google.com</code></p>
<p>Voila! Immediately, I was able to access Gmail. The IP address, 74.125.225.40, corresponds to the IP address my computer was successfully able to connect to in order to access services under the <a href="http://www.google.com">www.google.com</a> domain. By adding this manual entry to my hosts file, I informed my operating system to use the provided IP address when attempting to connect to mail.google.com. In order to additionally receive successful access to <a href="http://plus.google.com">Google+</a>, <a href="http://youtube.com">YouTube</a>, <a href="http://docs.google.com">Google Docs</a>, <a href="http://code.google.com">Google Code</a>, and Google&#8217;s chat interface, I updated the line to the following:</p>
<p><code>74.125.225.40 mail.google.com plus.google.com youtube.com docs.google.com code.google.com chatenabled.mail.google.com</code></p>
<p>What I previously described is how I was able to bypass Gogo&#8217;s Inflight Internet Authentication in order to access a number of Google services for free. What remains is how to utilize this information to access the entire Internet. The answer to this question lies with <a href="http://code.google.com/appengine/">Google AppEngine</a>.</p>
<p>Google AppEngine (GAE) is a cloud-based web application hosting service provided by Google. Anyone can run a GAE application on Google&#8217;s servers. As I previously described, Google&#8217;s front-end web servers respond to requests for any Google web service, including third-party GAE applications. The final piece of the puzzle is that GAE allows its applications to themselves make web requests. Therefore, a well written GAE application can operate as a proxy server. In fact, there are a number of available packages for running simple GAE proxy servers. <a href="http://www.labnol.org/internet/setup-proxy-server/12890/">Digital Inspiration</a> and <a href="http://mintywhite.com/software-reviews/security-software/set-proxy-google-app-engine/">Windows Guides</a> each provide tutorials for setting up such proxies. The Windows Guides tutorial even links to a working example at <a href="https://jttm-server-prox.appspot.com/">https://jttm-server-prox.appspot.com/</a>. A user of Gogo&#8217;s Inflight Internet need only add jttm-server-prox.appspot.com to their hosts file in order to utilize this proxy to access much of the Internet.</p>
<p>I have previously described how Gogo&#8217;s Inflight Internet authentication can be bypassed through the combination of a custom hosts file and a GAE proxy server. The remainder of this article will detail how Gogo can fix this problem.</p>
<p>The root question, is: why does Gogo allow non-authenticated access to some Google IPs? While my answer to this question is purely speculation, the solution I offer will absolutely solve the problem. I speculate that Gogo allows access to some Google IPs because of <a href="http://www.google.com/analytics/">Google Analytics</a> and <a href="https://www.google.com/adsense/">Google Adsense</a>, indicated in client scripts by the domains www.google-analytics.com and ad.doubleclick.net respectively. If correct, Gogo&#8217;s sysadmins simply white-listed a few too many IP addresses. Regardless, the point is moot because any Google front-end web server IP address, including those for Analytics and Adsense, will serve the reply for all Google web services, most notably GAE applications. Hence, by white-listing any single Google front-end web server IP address, Gogo is essentially providing access to the entire Internet. It follows, that the simplest solution to this bypass is for Gogo to completely disable direct access to Google IPs from non-authenticated users.</p>
<p>While the above solution absolutely works, it prevents Gogo from tracking users and serving ads using Google services. Of course, serving ads is pointless when non-authenticated users cannot visit the target site of the advertisement, so let&#8217;s forget about Google Adsense. Google Analytics on the other hand, is a useful tool for monitoring users&#8217; access to a website. Let&#8217;s now proceed under the assumption that it is essential for Gogo&#8217;s non-authenticated users to have access to whatever Google service Gogo intended to allow, and for simplicity assume it is the Google Analytics tracking service. The question now is: how can Gogo allow access to the Google Analytics tracking service without allowing access to all other Google services? This answer partially lies with <a href="http://en.wikipedia.org/wiki/Server_Name_Indication">Server Name Indication</a>.</p>
<p>Server Name Indication (SNI) is implemented on most modern web browsers and allows a web server with a single IP address to serve multiple TLS certificates. The proper certificate is returned in response to the hostname provided in the TLS client handshake. The use of SNI is why, despite using the same IP address for all the aforementioned services, Google is able to return the appropriate domain-specific TLS certificate. Therefore, Gogo can additionally white-list on the SNI-hostname in order to prevent the authentication bypass and still allow access to Google Analytics. However, things are not so simple, as Google&#8217;s servers do not depend on the presence of the SNI-hostname in the TLS client handshake.</p>
<p>In the absence of SNI, Google&#8217;s front-end web servers return the default TLS certificate for that particular server, yet, the server still responds with the requested content as indicated in the HTTP host header. Because the HTTP host header is encrypted, as well as the entire response, it is not possible to discern desired requests from undesired requests. One solution is to only allow such access to Google Analytics if the client supports SNI and the SNI-hostname is in the white-list. While this approach would work, it appears it would restrict access to Google Analytics for some browsers that are <a href="http://en.wikipedia.org/wiki/Server_Name_Indication#No_support">still commonly used</a>.</p>
<p>Regardless, I suspect that Google&#8217;s front-end web servers do not verify consistency between the SNI-hostname and the HTTP host header. Under that assumption, it would still be possible, in the presence of an SNI-hostname white-list, to bypass Gogo&#8217;s authentication with a custom browser (or local proxy server) that negotiates TLS handshakes using only the expected SNI-hostname yet still makes the desired Google web service request. While I don&#8217;t believe anything is readily accessible to make this process easy for 99.9% of Gogo&#8217;s potential customers, it only requires a single person&#8217;s determination to make it so. Thus, the only be-all-end-all solution to prevent this bypass is for Gogo to completely disable direct access to Google IPs from non-authenticated users.</p>
<p>There is, of course, one other possible solution: Gogo could <a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">man-in-the-middle</a> the desired Google web services in order to perform filtering on the HTTP host header. However, this approach could have unforeseen consequences. Therefore, I do not recommend it.</p>
<p>In conclusion, I have described how one can currently bypass Gogo&#8217;s Inflight Internet authentication to access much of the Internet using a custom host file and a Google AppEngine proxy. I have also described how Gogo can somewhat block this bypass by supplementing their IP white-list with both an SNI requirement and an SNI-hostname white-list. Finally, I speculated that even with the aforementioned solution, it would still be possible for a determined user to bypass their authentication. Thus, I stated the only real solution is for Gogo to not allow any direct access between non-authenticated users and Google web servers.</p>
<p>Happy &#8220;free&#8221; surfing, for now anyway <img src='http://www.bryceboe.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2012/03/12/bypassing-gogos-inflight-internet-authentication/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2012/03/12/bypassing-gogos-inflight-internet-authentication/</feedburner:origLink></item>
		<item>
		<title>My Major Area Exam Announcement</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/17U5E41-L3Y/</link>
		<comments>http://www.bryceboe.com/2012/03/06/my-major-area-exam-announcement/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 06:14:18 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[phd]]></category>
		<category><![CDATA[teaching]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=1015</guid>
		<description><![CDATA[Major Area Exam Bryce Boe March 12, 2012 2:00 PM HFH 1132 Committee: Diana Franklin (chair), Tim Sherwood, Kevin Almeroth Title: Automated Feedback and Assessment of Student Submitted Code Abstract: Increases in class sizes pose a problem for computer science instructors. With a larger number of students to educate, instructors are forced to choose between [...]]]></description>
				<content:encoded><![CDATA[<p>Major Area Exam<br />
Bryce Boe</p>
<p>March 12, 2012<br />
2:00 PM<br />
HFH 1132</p>
<p>Committee:<br />
Diana Franklin (chair), Tim Sherwood, Kevin Almeroth</p>
<p>Title: Automated Feedback and Assessment of Student Submitted Code</p>
<p>Abstract:<br />
Increases in class sizes pose a problem for computer science instructors. With a larger number of students to educate, instructors are forced to choose between assigning fewer assignments and devoting more of their time to satisfying the additional demands of larger class sizes. The first option, reducing the number of assignments, decreases the overall quality of a course, whereas the latter option, working more, scales only so far. Fortunately, a variety of tools exists which provides instructors with a third option. Automated feedback and assessment systems can provide significantly more detailed feedback to large numbers of students than instructors are capable of providing, and do so nearly instantaneously. The use of such systems allows instructors to continue to assign a similar number of comprehensive assignments despite growing class sizes, and also makes it possible for instructors to focus their time on students who require additional assistance with coursework.</p>
<p>In this talk I will provide a brief history of automated feedback and assessment systems, followed by an in-depth analysis of state-of-the-art automated feedback and assessment systems. Finally, I will provide an overview of additional research opportunities provided in other areas of computer science as a byproduct of using automated feedback and assessment systems.</p>
<p>Everyone is welcome to attend!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2012/03/06/my-major-area-exam-announcement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2012/03/06/my-major-area-exam-announcement/</feedburner:origLink></item>
		<item>
		<title>Implementation of a Process-Based Job Management System in C</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/UbV_lHv-1PM/</link>
		<comments>http://www.bryceboe.com/2012/02/23/implementation-of-a-process-based-job-management-system-in-c/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 07:03:54 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=998</guid>
		<description><![CDATA[A few days ago I wrote about a few differences between using C and python to handle a process-based job management system. My discussion covered performance, development time, dependencies, and portability. I ended with the conclusion that despite C being vastly superior in performance, the relative difference in performance between various job management systems is [...]]]></description>
				<content:encoded><![CDATA[<p>A few days ago I wrote about <a href="http://www.bryceboe.com/2012/02/20/process-based-job-management-in-c-and-python/" title="Process-Based Job Management in C and Python">a few differences between using C and python to handle a process-based job management system</a>. My discussion covered performance, development time, dependencies, and portability. I ended with the conclusion that despite C being vastly superior in performance, the relative difference in performance between various job management systems is irrelevant when considering the job processing time. Therefore, I recommended using python for such a task due to faster development times, built-in support for multiprocessing (no need for third-party libraries), and the portability one immediately gains by using python.</p>
<p>In spite of my continuing recommendation to use python for such a task, I was curious what a C solution might look like. Thus, I set out to write, and did write, a simple process-based job management system in C that offers similar functionality as python&#8217;s <a href="http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool">multiprocessing.Pool</a> class. Take note that writing this system required more time than the equivalent python code would have, however, the point is moot because python has the multiprocessing.Pool class. Furthermore, whoever wants to use this system must manually include it in their project, thus introducing a third-party dependency in their code. Finally, this code will not compile in the typical Windows development environment as it relies on <a href="http://en.wikipedia.org/wiki/POSIX">POSIX-based</a> system calls. Hence, for all the reasons I previously mentioned, this C implementation is quite inferior to python&#8217;s multiprocessing.Pool class.</p>
<p>The source that I reference throughout the remainder of this post can be <a href="https://gist.github.com/1894848">found and downloaded in entirety</a>. On a POSIX-based machine the code can be compiled via <code class="inline">gcc main.c job_management.c</code> and the test program can be run via <code class="inline">./a.out</code>.</p>
<p>The system, or library, is contained in two files: <strong>job_management.h</strong> and <strong>job_management.c</strong>. Anyone familiar with C or C++ development knows that <strong>job_management.h</strong> is a header file which contains the structures and function prototypes whereas <strong>job_management.c</strong> contains the implementation. The entire library functionality is exposed through three functions: <code class="inline">manager_init</code>, <code class="inline">manager_run_jobs</code>, and <code class="inline">manager_destruct</code>.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> manager_init<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> manager <span style="color: #339933;">*</span>manager<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> num_workers<span style="color: #339933;">,</span>
		  <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>input_callback<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		  <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>output_callback<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		  <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>work_function<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Aside from the pre-allocated <em>manager</em> structure that all the functions require as their first parameter, the <code class="inline">manager_init</code> function requires four other parameters: <em>num_workers</em>, <em>input_callback</em>, <em>output_callback</em>, and <em>work_function</em>. The <em>num_workers</em> parameter specifies an upper bound on how many worker processes to start. Each of the remaining parameters are function pointers to functions that must each have a single char pointer parameter and return no value. I will describe the purpose of these functions in the order that they execute when considering only a single job.</p>
<p>The <em>input_callback</em> function is called by the master process, once per job, in order to fetch the input for the job. The callback function stores the job input in the provided buffer before returning. The <em>work_function</em> function is the reason for the entire system as this function performs the job processing. In this function, the provided buffer serves both as job input and job output. On invocation, the buffer contains the result of a prior call to <em>input_callback</em> which has been sent over a pipe between the master process and worker process. On return, the buffer should contain the job output which will then be sent back to the master process. The <em>output_callback</em> function is called by the master process as each job is completed. In this case, the buffer contains the output of a completed job.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> manager_run_jobs<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> manager <span style="color: #339933;">*</span>manager<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> num_jobs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Once the manager has been properly set up, a number of jobs can be started via <code class="inline">manager_run_jobs</code> which takes one additional argument, <em>num_jobs</em>. Intuitively this parameter represents the number of jobs to process. This function contains the most complicated piece of the system as it is responsible for forking the processes, setting up the pipes between the master and workers, cleaning up the address space and file descriptor table for the workers, and properly using I/O multiplexing in order to both send job input and receive job output.</p>
<p>One additional complication that the <code class="inline">manger_run_jobs</code> function has to handle is <a href="http://www.bryceboe.com/2010/08/26/python-multiprocessing-and-keyboardinterrupt/" title="Python Multiprocessing and KeyboardInterrupt">the issue</a> that started this entire series of blog posts; that is, the want to gracefully exit the job management system when a keyboard interrupt (SIGINT), occurs. Gracefully exiting means any jobs that are running at the time of the keyboard interrupt will successfully complete prior to exiting, thus giving the master process the chance to save partial results. This function handles the desired behavior through the combination of a global <a href="http://en.wikipedia.org/wiki/Volatile_variable">volatile</a> value that&#8217;s periodically checked within this function&#8217;s primary loop, and a SIGINT handler function that updates the value. Worker processes are unaffected by SIGINT as they are set to ignore it.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> manager_destruct<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> manager <span style="color: #339933;">*</span>manager<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The last function, <code class="inline">manager_destruct</code>, conveniently frees the contents of the <em>manager</em> structure. It is important to note that this function is also called by each worker as part of its address space and file descriptor table clean up. For this reason, the <code class="inline">manager_destruct</code> function handles the closing of some <em>FILE</em> structures. Otherwise, this function is incredibly simple.</p>
<p>As previously mentioned, my job_management library is simple and thus is no where near as flexible as python&#8217;s multiprocessing.Pool class. Furthermore, my library has no support for data serialization as it relies on messages being no larger than <em>MAX_MESSAGE</em> bytes in size, and has a limitation that the message contents span only a single line. These restrictions were chosen for simplicity and are, by no means, a limitation of C. However, again, I must point out that object serialization is provided by default with python, and is built into the multiprocess.Pool class.</p>
<p>Below is an example program that demonstrates using my process-based job management system. Note that this code really isn&#8217;t that complicated, especially when compared to <a href="http://www.bryceboe.com/2012/02/14/python-multiprocessing-pool-and-keyboardinterrupt-revisited/" title="Python Multiprocessing Pool and KeyboardInterrupt Revisited">the python solution that gracefully handles the keyboard interrupt</a>. Of course, the python solution is without dependencies and much more portable. <img src='http://www.bryceboe.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Happy coding!</p>
<script src="http://gist.github.com/1894848.js?file=main.c"></script><noscript><pre><code class="language-c c">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &quot;job_manager.h&quot;

int job_num = 0;

/* This function is a worker function that does the work. On invocation, buffer
   contains a single line containing the input for the job. When complete,
   buffer should store the result of the job. The contents of the result must
   fit on a single line that ends with a single '\n'. */
void do_work(char *buffer) {
  int job = atoi(buffer);
  printf(&quot;%d started on job %d\n&quot;, getpid(), job);
  sleep(3 + getpid() % 3);
  snprintf(buffer, MAX_MESSAGE, &quot;%d Success\n&quot;, job);
}

/* The message to send to the worker must be stored in the provided buffer of
   size MAX_MESSAGE. The contents must fit on a single line that ends with a
   single '\n' */
void prepare_job(char *buffer) {
  snprintf(buffer, MAX_MESSAGE, &quot;%d\n&quot;, job_num++);
}

/* Process the single line result returned from the worker */
void process_result(char *buffer) {
  printf(&quot;%s&quot;, buffer);
}

int main(int argc, char *argv[]) {
  int i, num_jobs;
  struct manager manager;

  if (argc != 3) {
    printf(&quot;Usage: %s workers jobs\n&quot;, argv[0]);
    return 1;
  }
  num_jobs = atoi(argv[2]);

  manager_init(&amp;manager, atoi(argv[1]), prepare_job, process_result, do_work);
  i = manager_run_jobs(&amp;manager, num_jobs);
  manager_destruct(&amp;manager);
  printf(&quot;%d of %d jobs completed\n&quot;, i, num_jobs);
  return 0;
}</code></pre></noscript>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2012/02/23/implementation-of-a-process-based-job-management-system-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2012/02/23/implementation-of-a-process-based-job-management-system-in-c/</feedburner:origLink></item>
		<item>
		<title>Process-Based Job Management in C and Python</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/hxo6sISCvPw/</link>
		<comments>http://www.bryceboe.com/2012/02/20/process-based-job-management-in-c-and-python/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 23:56:41 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=944</guid>
		<description><![CDATA[I had an interesting discussion with my buddy Ali after he read my previous post, Python Multiprocessing Pool and KeyboardInterrupt Revisited. The discussion was around the question, &#8220;what are the benefits of using the python multiprocessing.Pool class over writing a simple process-based job management system in C?&#8221; We started with a discussion of performance. It’s [...]]]></description>
				<content:encoded><![CDATA[<p>I had an interesting discussion with my buddy Ali after he read my previous post, <a href="http://www.bryceboe.com/2012/02/14/python-multiprocessing-pool-and-keyboardinterrupt-revisited/">Python Multiprocessing Pool and KeyboardInterrupt Revisited</a>. The discussion was around the question, &#8220;what are the benefits of using the python <a href="http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool">multiprocessing.Pool</a> class over writing a simple process-based job management system in C?&#8221;</p>
<p>We started with a discussion of performance. It’s no secret that C will outperform python in any task; after all python is an interpreted language and the standard python implementation is written in C. However, Ali and my discussion was not focused on the performance of the jobs themselves, but rather on the performance of a job management system that could be gracefully interrupted. In such a system, where the majority of work is done in job processing, the question of the job management system&#8217;s performance is irrelevant; it makes little difference if C can launch all the workers thirty times faster when python still does it in well under a second. As an aside, it&#8217;s trivial to call a C program from python, or even to write a <a href="http://www.bryceboe.com/2010/09/14/properly-handling-the-keyboard-interrupt-exception-sigint-within-a-python-c-module/" title="Properly Handling the Keyboard Interrupt Exception (SIGINT) within a Python C Module">python C module</a> for fast job processing performance.</p>
<p>Once the irrelevance of the job management performance was agreed upon, Ali and I discussed development time, dependencies and portability. Having written both a significant amount of C and python code pertaining to <a href="http://cs.ucsb.edu/~bboe/p/cv#teaching">operating system concepts</a>, I know that anyone with equivalent experience can much more efficiently code a process-based job management system in python than in C. This holds true, even without the multiprocessing module and when using only the low level features provided by the <a href="http://docs.python.org/library/os.html">os package</a>. The two primary reasons for faster development time are dynamic types, and garbage collection. Additionally, python provides a lot more out-of-the-box functionality, e.g., string manipulation and basic data structures such as lists and dictionaries; all features that contribute to faster development time.</p>
<p>Of course, if one had all the needed libraries in C, then my only argument in favor of python is the lack of types and implicit memory management. The choice between C and python in this case is simply up to personal preference. However, having the required C libraries is a problem on its own. This is where my lack of real-world C experience appears as I’m not familiar with well-written C libraries that provide python-like string manipulation and basic data structures, nor am I familiar with a well written process-based job management library. Nevertheless, even if these libraries were easily available, they are additional dependencies that must be present in order to run any code utilizing them.</p>
<p>Managing dependencies can be a pain, especially in the absence of an automated process for obtaining them. For example, I wrote some code for a computer graphics class a few years ago that I recently wanted to compile. As I recall, it took me a few hours to find and install all the required OpenGL dependencies before I could compile my own code. Compare that to the 90%+ of python programs I’ve written which have no external dependencies. This vast amount of code <em>still</em> works out-of-the-box across multiple platforms.</p>
<p>Portability is my final argument in favor of python over C. While <a href="http://en.wikipedia.org/wiki/ANSI_C">ANSI-C</a> based libraries should work across multiple platforms, dealing with process management is a whole other can of worms as this <em>drastically</em> differs between operating systems. Again, my inexperience shows as I am not familiar with any process management libraries that are compatible with both Windows and <a href="http://en.wikipedia.org/wiki/POSIX">POSIX-based</a> systems. Moreover, I am not even sufficiently familiar with the Windows API to know its equivalent functions to <a href="http://pubs.opengroup.org/onlinepubs/009604599/functions/fork.html">fork</a>, <a href="http://pubs.opengroup.org/onlinepubs/009604499/functions/exec.html">exec</a>, <a href="http://pubs.opengroup.org/onlinepubs/009604599/functions/pipe.html">pipe</a> and <a href="http://pubs.opengroup.org/onlinepubs/007904975/functions/dup.html">dup</a> that are needed to write a process-based job management system for Windows. Nevertheless, with python, one needn’t worry about such things because the majority of the functionality in the os package is supported on both Windows and POSIX-based systems. Most importantly the multiprocessing module is supported on both, and thus <em>anyone</em> who installs python, independent of their operating system, can run the multiprocessing examples I previously provided [<a href="http://www.bryceboe.com/2010/08/26/python-multiprocessing-and-keyboardinterrupt/" title="Python Multiprocessing and KeyboardInterrupt">1</a>, <a href="http://www.bryceboe.com/2011/01/28/the-python-multiprocessing-queue-and-large-objects/" title="The Python Multiprocessing Queue and Large Objects">2</a>].</p>
<p>While Ali and I had a great discussion going, we still hadn’t gotten to the root of his question. Ali didn’t care about development time, nor portability. The problem was that he didn’t see any significant advantages to using the multiprocessing.Pool class when he could instead quickly write a process-based job management system in C utilizing fork to spawn processes and pipe to handle the <a href="http://en.wikipedia.org/wiki/Inter-process_communication">inter-process communication</a> (IPC). As it turns out, Ali wasn’t aware that the python multiprocessing.Pool class internally handles all the IPC. Without the built-in IPC support, Ali’s concerns would be valid as some other communication mechanism would need to be explicitly written to communicate between the master process and its workers. Fortunately, in python we get all that for free with both the multiprocessing.Pool and <a href="http://docs.python.org/library/multiprocessing.html#exchanging-objects-between-processes">multiprocessing.Queue</a> classes.</p>
<p>Personally, the choice of using python for such a task is a no-brainer because I can develop the system faster without the need for external dependencies and have confidence that it will work on any operating system that python runs on. Nevertheless, my curiosity peaked and I set out to write a <em>simple</em> process-based job management system in C. The system is complete, <del datetime="2012-02-24T07:02:59+00:00">though I&#8217;ve yet to write about it</del><ins datetime="2012-02-24T07:02:59+00:00"> and I&#8217;ve now written about it. Read the followup: <a href="http://www.bryceboe.com/2012/02/23/implementation-of-a-process-based-job-management-system-in-c/" title="Implementation of a Process-Based Job Management System in C">Implementation of a Process-Based Job Management System in C</a></ins></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2012/02/20/process-based-job-management-in-c-and-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2012/02/20/process-based-job-management-in-c-and-python/</feedburner:origLink></item>
		<item>
		<title>Python Multiprocessing Pool and KeyboardInterrupt Revisited</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/a-VJth4PdlY/</link>
		<comments>http://www.bryceboe.com/2012/02/14/python-multiprocessing-pool-and-keyboardinterrupt-revisited/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 21:54:28 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=916</guid>
		<description><![CDATA[Earlier today I was in the process of cleaning out some Chrome bookmarks when I came across a post by John M. Reese I bookmarked titled, Python: Using KeyboardInterrupt with a Multiprocessing Pool. I had bookmarked John&#8217;s post a number of months ago as it referenced my previous post, Python Multiprocessing and KeyboardInterrupt, however, not [...]]]></description>
				<content:encoded><![CDATA[<p>Earlier today I was in the process of cleaning out some Chrome bookmarks when I came across a post by John M. Reese I bookmarked titled, <a href="http://noswap.com/blog/python-multiprocessing-keyboardinterrupt/">Python: Using KeyboardInterrupt with a Multiprocessing Pool</a>. I had bookmarked John&#8217;s post a number of months ago as it referenced my previous post, <a href="http://www.bryceboe.com/2010/08/26/python-multiprocessing-and-keyboardinterrupt/">Python Multiprocessing and KeyboardInterrupt</a>, however, not until today had I been able to look at his findings.</p>
<p>John suggests that by having the worker processes ignore SIGINT, the signal that results in python&#8217;s KeyboardInterrupt, the entire problem can be solved. Astute readers will note that I actually used the same approach in my <a href="http://www.bryceboe.com/2010/08/26/python-multiprocessing-and-keyboardinterrupt/#georges">second update</a> to my aforementioned post, which suffered from the problem that intermediate results could not be processed, i.e., jobs that completed prior to the keyboard interrupt. While, John&#8217;s solution did educate me as to the existence of the initializer and initargs parameters to the <a href="http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool">multiprocessing.Pool</a> function, his solution in-fact does not work. The only reason it appears to work is due to the <code class="inline">time.sleep(10)</code> in his try block. In most code this <code class="inline">sleep</code> call would not exist, rather the code would immediately call <code class="inline">join()</code> on the pool object.</p>
<p>In the absence of the delay introduced by the <code class="inline">sleep</code> call, John&#8217;s code still suffers from the original problem which is the KeyboardInterrupt exception does not reach the main process until all of the jobs have completed. The proper solution to the problem would be to fix the multiprocessing library to allow the <code class="inline">join</code> function to be interrupted. Until then, my suggestion of rolling your own pool functionality is the best solution I am aware of.</p>
<p>Below is a verbatim copy of my original solution for your convenience:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> multiprocessing<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">os</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">signal</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">time</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">Queue</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> do_work<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Work Started: %d'</span> % <span style="color: #dc143c;">os</span>.<span style="color: black;">getpid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">'Success'</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> manual_function<span style="color: black;">&#40;</span>job_queue<span style="color: #66cc66;">,</span> result_queue<span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">signal</span>.<span style="color: #dc143c;">signal</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">signal</span>.<span style="color: black;">SIGINT</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">signal</span>.<span style="color: black;">SIG_IGN</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> job_queue.<span style="color: black;">empty</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            job <span style="color: #66cc66;">=</span> job_queue.<span style="color: black;">get</span><span style="color: black;">&#40;</span>block<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
            result_queue.<span style="color: black;">put</span><span style="color: black;">&#40;</span>do_work<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #dc143c;">Queue</span>.<span style="color: black;">Empty</span>:
            <span style="color: #ff7700;font-weight:bold;">pass</span>
        <span style="color: #808080; font-style: italic;">#except KeyboardInterrupt: pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    job_queue <span style="color: #66cc66;">=</span> multiprocessing.<span style="color: #dc143c;">Queue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    result_queue <span style="color: #66cc66;">=</span> multiprocessing.<span style="color: #dc143c;">Queue</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">6</span><span style="color: black;">&#41;</span>:
        job_queue.<span style="color: black;">put</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
&nbsp;
    workers <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>:
        tmp <span style="color: #66cc66;">=</span> multiprocessing.<span style="color: black;">Process</span><span style="color: black;">&#40;</span>target<span style="color: #66cc66;">=</span>manual_function<span style="color: #66cc66;">,</span>
                                      args<span style="color: #66cc66;">=</span><span style="color: black;">&#40;</span>job_queue<span style="color: #66cc66;">,</span> result_queue<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        tmp.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        workers.<span style="color: black;">append</span><span style="color: black;">&#40;</span>tmp<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> worker <span style="color: #ff7700;font-weight:bold;">in</span> workers:
            worker.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">KeyboardInterrupt</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'parent received ctrl-c'</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> worker <span style="color: #ff7700;font-weight:bold;">in</span> workers:
            worker.<span style="color: black;">terminate</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            worker.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> result_queue.<span style="color: black;">empty</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> result_queue.<span style="color: black;">get</span><span style="color: black;">&#40;</span>block<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2012/02/14/python-multiprocessing-pool-and-keyboardinterrupt-revisited/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2012/02/14/python-multiprocessing-pool-and-keyboardinterrupt-revisited/</feedburner:origLink></item>
		<item>
		<title>Tethering OS X Lion to Android</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/HfpUISV1Brs/</link>
		<comments>http://www.bryceboe.com/2011/10/20/tethering-os-x-lion-to-android/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 21:24:10 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=887</guid>
		<description><![CDATA[I&#8217;m currently in Chicago, having just attended the 18th ACM Conference on Computer and Communications Security, where Adam Doupé presented our paper, Fear the EAR: Discovering and Mitigating Execution After Redirect Vulnerabilities. As always, when I&#8217;m traveling, the problem of how to connect to the Internet arises. Fortunately, we were provided with Internet access via [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m currently in Chicago, having just attended the <a href="http://www.sigsac.org/ccs/CCS2011/">18th ACM Conference on Computer and Communications Security</a>, where <a href="http://adamdoupe.com/">Adam Doupé</a> presented our paper, <a href="http://cs.ucsb.edu/~bboe/public/pubs/fear-the-ear-ccs2011.pdf">Fear the EAR: Discovering and Mitigating Execution After Redirect Vulnerabilities</a>. As always, when I&#8217;m traveling, the problem of how to connect to the Internet arises. Fortunately, we were provided with Internet access via WiFi in our rooms throughout the duration of the conference, however, now that the conference is over we&#8217;ll have to pay for the access ourselves. Hotels, like many airports, charge absurd amounts for Internet access simply because they can. $8 a day for an <em>unreliable</em> and <em>slow</em> connection is typical and is <em>absurd</em> considering I&#8217;m already paying $30 a month for an unlimited data plan on my cell phone. Of course I can check my email, read <a href="http://reddit.com">reddit</a>, and maybe look up some places on <a href="http://yelp.com">yelp</a> using my Android phone, however, it is simply more efficient to use my laptop.</p>
<p>Naturally, the obvious solution is to tether your laptop to your phone and if you have an Android phone the process is incredibly simple. In fact, there are a number of pages on the Internet that tell you exactly how to do it. Primarily, there is an <a href="http://androidforums.com/droid-how-tips/18532-mac-os-x-droid-tethering-usb-wired.html">Android Forums post</a> from November, 2009 that recommends using an Android application, <a href="http://code.google.com/p/azilink/">Azilink</a>, in combination with an OS X application <a href="http://code.google.com/p/tunnelblick/">Tunnelblick</a>, and a <a href="http://pastie.org/701122">shell script</a> to configure the tether correctly. There is also a <a href="http://mornin.org/blog/howto-tether-android-phone-mac-os-x/">great blog post</a> from March of this year that is a bit more user friendly than the forum post in describing how to tether your OS X machine to your Android phone.</p>
<p>Despite the last guide being fairly recent, it unfortunately is slightly out of date due in part to OS X Lion. The older versions of Tunnelblick seemingly don&#8217;t work with OS X Lion, thus an update to a newer version of Tunnelblick is required. The newer version (currently 3.2beta32) of Tunnelblick breaks the shell script that the previous guide uses, thus I am writing this post simply to provide the Internet with an update to that shell script. Please note that everything else mentioned on the blog post currently works as described.</p>
<p>The fix to the shell script is actually really simple, just replace the line shown in the first block of code below, with the line shown in the second:<br />
<code>    sudo /Applications/Tunnelblick.app/Contents/Resources/openvpn --dev tun \</code><code>    sudo /Applications/Tunnelblick.app/Contents/Resources/openvpn/openvpn-2.2.1/openvpn --dev tun \</code></p>
<p>Finally for your convenience, I created a github gist with the updated shell script. Observant readers will notice that I updated some of the comments in the script. Happy tethering!</p>
<script src="http://gist.github.com/1302227.js"></script><noscript><pre><code class="language-shell shell">#!/bin/bash
#
# azilink for OS X Lion
# based on http://pastie.org/405289 but works with Tunnelblick only
# (no need to install a separate copy of OpenVPN2 from macports 
# or building from source by hand, thankfully)
# Requires: 
# - azilink running on android phone (http://code.google.com/p/azilink/)
#   (run the app and check the box to start the service).
# - adb on system path (comes with the Android SDK; 
#   add its tools folder to your PATH in ~/.profile or 
#   place or symlink the sdk's tools/adb file in e.g. usr/local/bin or somewhere else on the PATH)
# - Tunnelblick, a nice OS X packaging of OpenVPN (http://code.google.com/p/tunnelblick/)
#   Install Tunnelblick to Applications. Tested with Tunnelblick 3.2beta32 (build 2817)

init() {
    adb forward tcp:41927 tcp:41927
    sudo /Applications/Tunnelblick.app/Contents/Resources/openvpn/openvpn-2.2.1/openvpn --dev tun \
                  --script-security 2\
                  --remote 127.0.0.1 41927 \
                  --proto tcp-client \
                  --ifconfig 192.168.56.2 192.168.56.1 \
                  --route 0.0.0.0 128.0.0.0 \
                  --route 128.0.0.0 128.0.0.0 \
                  --keepalive 10 30 \
                  --up &quot;$0 up&quot; \
                  --down &quot;$0 down&quot;
}


up() {
    tun_dev=$1
    ns=192.168.56.1
    sudo /usr/sbin/scutil &lt;&lt; EOF
open
d.init
get State:/Network/Interface/$tun_dev/IPv4
d.add InterfaceName $tun_dev
set State:/Network/Service/openvpn-$tun_dev/IPv4

d.init
d.add ServerAddresses * $ns
set State:/Network/Service/openvpn-$tun_dev/DNS
quit
EOF
}


down() {
    tun_dev=$1
    sudo /usr/sbin/scutil &lt;&lt; EOF
open
remove State:/Network/Service/openvpn-$tun_dev/IPv4
remove State:/Network/Service/openvpn-$tun_dev/DNS
quit
EOF
}


case $1 in
    up  ) up $2 ;;  # openvpn will pass tun/tap dev as $2
    down) down $2 ;;
    *   ) init ;;
esac</code></pre></noscript>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2011/10/20/tethering-os-x-lion-to-android/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2011/10/20/tethering-os-x-lion-to-android/</feedburner:origLink></item>
		<item>
		<title>Moving Images in 3D Space with Pyglet</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/lwE2DnZm5e0/</link>
		<comments>http://www.bryceboe.com/2011/10/08/moving-images-in-3d-space-with-pyglet/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 23:04:16 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=858</guid>
		<description><![CDATA[Yesterday, October 7, 2011, the graduate students of UCSB&#8217;s Computer Science department, including myself, hosted the 6th annual Graduate Student Workshop on Computing (GSWC). The workshop is a great opportunity for other students, faculty, and industry professionals to get an overview of the work performed by our department. Part of organizing the workshop is obtaining [...]]]></description>
				<content:encoded><![CDATA[<p>Yesterday, October 7, 2011, the graduate students of UCSB&#8217;s Computer Science department, including myself, hosted the <a href="http://gswc.cs.ucsb.edu/2011/">6th annual Graduate Student Workshop on Computing (GSWC)</a>. The workshop is a great opportunity for other students, faculty, and industry professionals to get an overview of the work performed by our department. Part of organizing the workshop is obtaining gift or sponsorship money in order to pay for the facilities, food, proceedings, and all other costs associated with running a workshop.</p>
<p>In exchange for event sponsorship, we include each company&#8217;s logo on our website, in the conference proceedings, and in a visible display at the workshop itself. For many of the previous GSWCs, we created and printed up an expensive poster with the theme of the event as well as logos of all the corporate sponsors. While that worked well, it required a decent effort to design the poster, and, as I said before, was considerably expensive to print. Thus, when I was the chair of the GSWC last year, I decided to take a different approach to how we display the corporate logos during the workshop. Rather than using a static poster, I created an animated display that was projected on one of the room&#8217;s walls during the conference.</p>
<p>I occasionally provide consulting for a local Santa Barbara company, <a href="http://www.worldviz.com/">Worldviz</a> who makes a product, <a href="http://www.worldviz.com/products/vizard4/index.html">Vizard</a>, that allows one to quickly construct 3D environments in python. Using Vizard I was able to quickly create a 3D logo display in which the logos follow a circular path along the z-axis, as shown in the following photos. While this worked well, Vizard unfortunately only works on Windows and thus could not be run easily from my Mac laptop.</p>
<p><a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator0.png"><img src="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator0-150x150.png" alt="" title="animator0" width="150" height="150" class="alignnone size-thumbnail wp-image-860" /></a><a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator1.png"><img src="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator1-150x150.png" alt="" title="animator1" width="150" height="150" class="alignnone size-thumbnail wp-image-861" /></a><a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator2.png"><img src="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator2-150x150.png" alt="" title="animator2" width="150" height="150" class="alignnone size-thumbnail wp-image-862" /></a><a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator4.png"><img src="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator4-150x150.png" alt="" title="animator4" width="150" height="150" class="alignnone size-thumbnail wp-image-863" /></a></p>
<p>We wanted to use the same display for this year&#8217;s GSWC so I sought to rewrite the display in a cross platform and free manor. While I have some previous opengl experience in C, I really wanted to write the display in python so I looked at the various python opengl options. From the StackOverflow thread, <a href="http://stackoverflow.com/questions/242059/opengl-with-python">OpenGL with Python</a>, I quickly settled on <a href="http://pyglet.org/">pyglet</a>. Since I already knew the equation to move points around in a circular path, my only challenge was to figure out how to map a texture to a quad so that I could position the quad in 3D space. I quickly asked a StackOverflow question, <a href="http://stackoverflow.com/questions/7681899/moving-an-image-around-in-3d-space">Moving an image around in 3D space</a> in hopes that while I was in the process of figuring it out, someone would provide me with the solution. Unfortunately, <a href="http://en.wikipedia.org/wiki/Crowdsourcing">crowdsourcing</a> didn&#8217;t pay off, nevertheless, I eventually found the solution and wrote a simple cross platform logo animation program.</p>
<p>In order to run the following program, you will first need to install the required libraries (an exercise left to the reader), create a folder &#8220;imgs&#8221; and place whatever images you want in that folder and then run the following script (<a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/10/animator.py">download animator.py</a>). Note: If you want to run this script on 64-bit OS X you&#8217;ll need to run it via: <code>VERSIONER_PYTHON_PREFER_32_BIT=yes ./animator.py</code></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">math</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">os</span><span style="color: #66cc66;">,</span> pyglet<span style="color: #66cc66;">,</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">from</span> pyglet.<span style="color: #dc143c;">gl</span> <span style="color: #ff7700;font-weight:bold;">import</span> *
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> World<span style="color: black;">&#40;</span>pyglet.<span style="color: black;">window</span>.<span style="color: black;">Window</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> scale<span style="color: #66cc66;">=</span><span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> center_pos<span style="color: #66cc66;">=</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> -<span style="color: #ff4500;">15</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> speed<span style="color: #66cc66;">=</span><span style="color: #ff4500;">1.0</span><span style="color: #66cc66;">,</span>
                 *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>World<span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span>*args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">scale</span> <span style="color: #66cc66;">=</span> scale
        <span style="color: #008000;">self</span>.<span style="color: black;">center_pos</span> <span style="color: #66cc66;">=</span> center_pos
        <span style="color: #008000;">self</span>.<span style="color: black;">speed</span> <span style="color: #66cc66;">=</span> speed
        glClearColor<span style="color: black;">&#40;</span><span style="color: #ff4500;">1.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.0</span><span style="color: black;">&#41;</span>
        glEnable<span style="color: black;">&#40;</span>GL_DEPTH_TEST<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">textures</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>.<span style="color: black;">load_textures</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">clock</span> <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span>
        pyglet.<span style="color: black;">clock</span>.<span style="color: black;">schedule_interval</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">update</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span> / <span style="color: #ff4500;">60.0</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #66cc66;">@</span><span style="color: #008000;">staticmethod</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> load_textures<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        img_dir <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'imgs'</span>
        textures <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">isdir</span><span style="color: black;">&#40;</span>img_dir<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Could not find directory &quot;%s&quot; under &quot;%s&quot;'</span> % <span style="color: black;">&#40;</span>img_dir<span style="color: #66cc66;">,</span>
                                                                <span style="color: #dc143c;">os</span>.<span style="color: black;">getcwd</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> image <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">listdir</span><span style="color: black;">&#40;</span>img_dir<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                image <span style="color: #66cc66;">=</span> pyglet.<span style="color: black;">image</span>.<span style="color: black;">load</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>img_dir<span style="color: #66cc66;">,</span> image<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">except</span> pyglet.<span style="color: black;">image</span>.<span style="color: #dc143c;">codecs</span>.<span style="color: black;">dds</span>.<span style="color: black;">DDSException</span>:
                <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'&quot;%s&quot; is not a valid image file'</span> % image
                <span style="color: #ff7700;font-weight:bold;">continue</span>
            textures.<span style="color: black;">append</span><span style="color: black;">&#40;</span>image.<span style="color: black;">get_texture</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
            glEnable<span style="color: black;">&#40;</span>textures<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">target</span><span style="color: black;">&#41;</span>
            glBindTexture<span style="color: black;">&#40;</span>textures<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">target</span><span style="color: #66cc66;">,</span> textures<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: #008000;">id</span><span style="color: black;">&#41;</span>
            glTexImage2D<span style="color: black;">&#40;</span>GL_TEXTURE_2D<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> GL_RGB<span style="color: #66cc66;">,</span> image.<span style="color: black;">width</span><span style="color: #66cc66;">,</span> image.<span style="color: black;">height</span><span style="color: #66cc66;">,</span>
                         <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> GL_RGBA<span style="color: #66cc66;">,</span> GL_UNSIGNED_BYTE<span style="color: #66cc66;">,</span>
                         image.<span style="color: black;">get_image_data</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">get_data</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'RGBA'</span><span style="color: #66cc66;">,</span>
                                                         image.<span style="color: black;">width</span> * <span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>textures<span style="color: black;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff4500;">0</span>:
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Found no textures to load. Exiting'</span>
            <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> textures
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> update<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> _<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">on_draw</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">clock</span> +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">.01</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> on_draw<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        glClear<span style="color: black;">&#40;</span>GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT<span style="color: black;">&#41;</span>
        glLoadIdentity<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">draw_images</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> draw_images<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        angle_base <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">clock</span> * <span style="color: #008000;">self</span>.<span style="color: black;">speed</span> * <span style="color: #ff4500;">50</span><span style="color: black;">&#41;</span> % <span style="color: #ff4500;">360</span>
        angle_delta <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">360</span>. / <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">textures</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">for</span> i<span style="color: #66cc66;">,</span> texture <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">enumerate</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">textures</span><span style="color: black;">&#41;</span>:
            angle <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">math</span>.<span style="color: black;">radians</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>angle_base + i * angle_delta<span style="color: black;">&#41;</span> % <span style="color: #ff4500;">360</span><span style="color: black;">&#41;</span>
            dx <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">math</span>.<span style="color: black;">sin</span><span style="color: black;">&#40;</span>angle<span style="color: black;">&#41;</span> * <span style="color: #008000;">self</span>.<span style="color: black;">scale</span>
            dz <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">math</span>.<span style="color: black;">cos</span><span style="color: black;">&#40;</span>angle<span style="color: black;">&#41;</span> * <span style="color: #008000;">self</span>.<span style="color: black;">scale</span>
&nbsp;
            <span style="color: #ff7700;font-weight:bold;">if</span> texture.<span style="color: black;">width</span> <span style="color: #66cc66;">&gt;</span> texture.<span style="color: black;">height</span>:
                rect_w <span style="color: #66cc66;">=</span> texture.<span style="color: black;">width</span> / <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>texture.<span style="color: black;">height</span><span style="color: black;">&#41;</span>
                rect_h <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                rect_w <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span>
                rect_h <span style="color: #66cc66;">=</span> texture.<span style="color: black;">height</span> / <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>texture.<span style="color: black;">width</span><span style="color: black;">&#41;</span>
&nbsp;
            glPushMatrix<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            glTranslatef<span style="color: black;">&#40;</span>dx + <span style="color: #008000;">self</span>.<span style="color: black;">center_pos</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span>.<span style="color: black;">center_pos</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span>
                         dz + <span style="color: #008000;">self</span>.<span style="color: black;">center_pos</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            glBindTexture<span style="color: black;">&#40;</span>texture.<span style="color: black;">target</span><span style="color: #66cc66;">,</span> texture.<span style="color: #008000;">id</span><span style="color: black;">&#41;</span>
            glBegin<span style="color: black;">&#40;</span>GL_QUADS<span style="color: black;">&#41;</span>
            glTexCoord2f<span style="color: black;">&#40;</span><span style="color: #ff4500;">0.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.0</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span> glVertex3f<span style="color: black;">&#40;</span>-rect_w<span style="color: #66cc66;">,</span> -rect_h<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.0</span><span style="color: black;">&#41;</span>
            glTexCoord2f<span style="color: black;">&#40;</span><span style="color: #ff4500;">1.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.0</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span> glVertex3f<span style="color: black;">&#40;</span> rect_w<span style="color: #66cc66;">,</span> -rect_h<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.0</span><span style="color: black;">&#41;</span>
            glTexCoord2f<span style="color: black;">&#40;</span><span style="color: #ff4500;">1.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1.0</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span> glVertex3f<span style="color: black;">&#40;</span> rect_w<span style="color: #66cc66;">,</span>  rect_h<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.0</span><span style="color: black;">&#41;</span>
            glTexCoord2f<span style="color: black;">&#40;</span><span style="color: #ff4500;">0.0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1.0</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span> glVertex3f<span style="color: black;">&#40;</span>-rect_w<span style="color: #66cc66;">,</span>  rect_h<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.0</span><span style="color: black;">&#41;</span>
            glEnd<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            glPopMatrix<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> on_resize<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> width<span style="color: #66cc66;">,</span> height<span style="color: black;">&#41;</span>:
        glViewport<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0</span><span style="color: #66cc66;">,</span> width<span style="color: #66cc66;">,</span> height<span style="color: black;">&#41;</span>
        glMatrixMode<span style="color: black;">&#40;</span>GL_PROJECTION<span style="color: black;">&#41;</span>
        glLoadIdentity<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        gluPerspective<span style="color: black;">&#40;</span><span style="color: #ff4500;">65.0</span><span style="color: #66cc66;">,</span> width / <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>height<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">0.1</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1000.0</span><span style="color: black;">&#41;</span>
        glMatrixMode<span style="color: black;">&#40;</span>GL_MODELVIEW<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    window <span style="color: #66cc66;">=</span> World<span style="color: black;">&#40;</span>width<span style="color: #66cc66;">=</span><span style="color: #ff4500;">800</span><span style="color: #66cc66;">,</span> height<span style="color: #66cc66;">=</span><span style="color: #ff4500;">600</span><span style="color: black;">&#41;</span>
    pyglet.<span style="color: black;">app</span>.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2011/10/08/moving-images-in-3d-space-with-pyglet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2011/10/08/moving-images-in-3d-space-with-pyglet/</feedburner:origLink></item>
		<item>
		<title>Defcon 19 Quals Forensics 100 and Forensics 300 Solution</title>
		<link>http://feedproxy.google.com/~r/BryceBoe/~3/Ag-5e9V5PwQ/</link>
		<comments>http://www.bryceboe.com/2011/06/05/defcon-19-quals-forensics-100-and-forensics-300-solution/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 02:18:30 +0000</pubDate>
		<dc:creator>Bryce Boe</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.bryceboe.com/?p=821</guid>
		<description><![CDATA[For the third year, I competed with team Shellphish in the Defcon quals. We pulled through with some amazing points at the end to finish in 8th place. My successful contributions, however, were really only with respect to Forensics 100 and 300. My write up for the following are below: Forensics 100 The forensics 100 [...]]]></description>
				<content:encoded><![CDATA[<p>For the third year, I competed with team Shellphish in the Defcon quals. We pulled through with some amazing points at the end to finish in <a href="http://stalkr.net/defcon/graph.htm">8th place</a>. My successful contributions, however, were really only with respect to Forensics 100 and 300. My write up for the following are below:</p>
<p><strong>Forensics 100</strong><br />
The forensics 100 challenge indicated to find the key, and <a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/06/f100.png">provided a png file</a> that was 19025&#215;1 in resolution. Immediately our team thought we could simply change the resolution to <a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/06/f100_25_761.png">25&#215;761</a> and would be on to something. After working with the resulting image for sometime I finally thought about converting it to <a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/06/f100_761_25.png">761&#215;25</a>. That was our first break through when we read some text along the lines of &#8220;ILoveMeSomesheepysheepies&#8221; followed by binary that includes capital &#8216;O&#8217;s in place of some of the &#8217;0&#8242;s. After no success with different permutations of that message we incorporated an idea the other team members had about the blue offset pixels that occur at regular intervals. Our first attempt at wrapping the image at the blue pixel boundaries (every 450 pixels) <a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/06/f100_solution.png">resulted in success</a>! The key &#8220;thankYouSirPleasemayIhaveAnother&#8221; appeared and worked. The following is my simple python solution for Forensics 100:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span><span style="color: #66cc66;">,</span> Image
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    orig <span style="color: #66cc66;">=</span> Image.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'f100.png'</span><span style="color: black;">&#41;</span>
    img <span style="color: #66cc66;">=</span> Image.<span style="color: #dc143c;">new</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'RGBA'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">450</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">43</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    img.<span style="color: black;">putdata</span><span style="color: black;">&#40;</span>orig.<span style="color: black;">getdata</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    img.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span>main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><strong>Forensics 300</strong><br />
Forensics 300 was quite an interesting challenge. I don&#8217;t have the original file, nevertheless, one had to extract the initial file with a password to get a dmg containing a dump from an iphone. I came into the challenge a little late, after one of my teammates had gone through all the images, videos, and audio files looking for Waldo and &#8216;grep&#8217;ing for various relevant keywords. Further more, my teammates had previously used the <a href="http://petewarden.github.com/iPhoneTracker/">iPhoneTracker</a> on the consolidated.db file to see where the phone had been, however San Antonio didn&#8217;t prove to be very useful.</p>
<p>While the iPhoneTracker app seemed pretty cool, I wanted to programmatically see where the phone had been the most. Thus, after figuring out what was what with respect to the consolidated.db file I wrote a little python script to find the most visited places rounded to less precision to account for some variance. The top three results were the following where the first number represents the number of occurrences in that location, and the two numbers between the parenthesis represent the latitude and longitude respectfully.</p>
<ul>
<li>30 (&#8216;-77.846&#8242;, &#8217;166.677&#8242;)</li>
<li>18 (&#8217;0.000&#8242;, &#8217;0.000&#8242;)</li>
<li>10 (&#8217;36.106&#8242;, &#8216;-115.173&#8242;)</li>
</ul>
<p>When I did a <a href="http://maps.google.com/maps?f=q&#038;source=s_q&#038;hl=en&#038;geocode=&#038;q=-77.846+166.677&#038;sll=-77.578778,167.409668&#038;sspn=1.030596,5.218506&#038;ie=UTF8&#038;t=h&#038;z=15">google search for the coordinates -77.846 166.667</a> I knew immediately that it was no coincidence that I was centered in a small town in Antarctica. Unfortunately, Google maps doesn&#8217;t have a name for this location so I had to <a href="http://www.bing.com/maps/?v=2&#038;where1=-77.846%20166.677">revert to Bing</a> (for the first time ever) to figure out that this location is called Ross Island. From that point we simply attempted different &#8220;places&#8221; listed <a href="http://en.wikipedia.org/wiki/Ross_Island">Ross Island&#8217;s wikpiedia page</a> until &#8220;McMurdo Station&#8221; submitted successfully. Below is the script I used to find the coordinates from the <a href="http://www.bryceboe.com/wordpress/wp-content/uploads/2011/06/consolidated.db">consolodated.db input file</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #dc143c;">os</span>.<span style="color: black;">system</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'sqlite3 consolidated.db &quot;select Latitude, Longitude '</span>
              <span style="color: #483d8b;">'from CellLocation;&quot; &gt; tmp'</span><span style="color: black;">&#41;</span>
&nbsp;
    uniq <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> line <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'tmp'</span><span style="color: black;">&#41;</span>:
        pos <span style="color: #66cc66;">=</span> <span style="color: #008000;">tuple</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%.3f'</span> % <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> line.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'|'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span>:<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> pos <span style="color: #ff7700;font-weight:bold;">in</span> uniq:
            uniq<span style="color: black;">&#91;</span>pos<span style="color: black;">&#93;</span> +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            uniq<span style="color: black;">&#91;</span>pos<span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> pos<span style="color: #66cc66;">,</span> count <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>uniq.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> key<span style="color: #66cc66;">=</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x:x<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> count<span style="color: #66cc66;">,</span> pos
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">'__main__'</span>:
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span>main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>You can find links to solutions to other Defcon 19 Quals challenges at the following locations: <a href="http://rogunix.com/defconquals19.html">Rogunix</a>, <a href="http://t.negativefoo.org/post/6235620215/dc19-ctf-quals-writeups">negative foo</a>, <a href="http://www.vnsecurity.net/2011/05/defcon-19-ctf-quals-writeups-collection/">VNSecurity site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bryceboe.com/2011/06/05/defcon-19-quals-forensics-100-and-forensics-300-solution/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.bryceboe.com/2011/06/05/defcon-19-quals-forensics-100-and-forensics-300-solution/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.602 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-05-17 04:31:52 --><!-- Compression = gzip -->
