Fotinakis.com Blog


Google I/O 2008 Pageview Limit Exceeded

June 12, 2008


Ok ... now this is just funny. Quick disclaimer: I love Google. And not just in some nebulous, fanboy way. Through my work with Utah State University I've been able to meet and work with some of the brilliant engineers who work there and I greatly respect the work they are doing for the open web. I also went to Google I/O 2008 and had an incredible time at the conference. I've been waiting for the videos to be posted online so that I could create some posts and link to the actual session videos. They just came up! At least, for a moment.

I just got an email saying "Thanks for joining us at Google I/O" and a link to the videos of all the sessions, hosted on a Google Sites page. I was able to view a couple of the videos, and then...

Google IO pwnd

Google exceeded their own page limit. Awesome.
I'm sure they'll get it fixed soon, but the irony is unbeatable.

Apple Mail and Gmail IMAP: “Invalid Credentials” Fix

June 1, 2008


For anyone else out there trying to set up Apple Mail to check their Gmail account and getting an "Invalid credentials" error:

You may need to unlock CAPTCHA for your Gmail account:
https://www.google.com/accounts/UnlockCaptcha

Just go to that page, fill out your information and everything should work. I'm not sure if there are larger ramifications of doing this, but I suspect it's not much of an issue. Any ideas on the security implications? Reading around on Google Groups and the Apple Forums it also seems like this issue may also affect the iPhone as well. I hope this helps if you're having that issue.

uNUI - Building a Multi-touch Table

April 6, 2008


My newest project: breaking interface boundaries. A couple of my friends at work and I have decided to build a multi-touch table based on the technique of frustrated total internal reflection (FTIR). This can be described by a diagram easier than words, so here we go:


Graphic from Tim Roth's Multi-touch Dev Blog

This design for multi-touch interfaces has been popularized by Jeff Han, a researcher from NYU. Infrared LEDs are placed around two sides of a sheet of acrylic, causing the IR light to be reflected within it. Then, when a finger or object touches it, the light is "frustrated" and refracts off of the object and out of the acrylic. An IR camera below the screen then sees this as a blob of IR light which can be interpreted by a computer for recognition of gestures, touches, and movement.

This is a very exciting and fun project with which to be involved. The potential is amazing—multi-touch interfaces are the next paradigm in computing and will replace standard keyboard and mouse input in the relatively near future. My friends and I decided to document our progress as we build our devices and software, so we created the uNUI Group site as an extension of the NUI Group community. Check out the Resources page for links, blogs and videos about what we and the community are doing—we'd also love to hear your feedback.

Python XML-RPC Client with Cookie Handling and SSL

March 9, 2008


The following is an adaptation of Vaibhav Bhatia's cookie-handling XML-RPC client (text source) with a few changes to implement SSL for HTTPS transport in place of the basic HTTP transport.

This was done specifically for use with CherryPy sessions so that the XML-RPC client (the server proxy object) could be stored in a session variable, giving each user an individual client and thus allowing webservice permissions to be handled on a per-user basis (without having to authenticate and determine permissions on every webservice method invocation). To do this, make sure that you're storing CherryPy sessions in memory, not in a file, and then create the proxy object (sorry for the gigantic class name):

cherrypy.session['proxy'] = \
	xmlrpclib.ServerProxy(url, transport=CookieAuthXMLRPCSafeTransport())

xmlrpcclient.py

import os
import base64
import xmlrpclib
import urllib2
import cookielib
 
class CookieAuthXMLRPCSafeTransport(xmlrpclib.SafeTransport):
    """ xmlrpclib.Transport that sends HTTPS Authentication"""
 
    user_agent = '*py*'
    credentials = ()
    cookiefile = 'cookies.lwp'
 
    def send_basic_auth(self, connection):
        """Include HTTPS Authentication data in a header"""
 
        auth = base64.encodestring("%s:%s"%self.credentials).strip()
        auth = 'Basic %s' %(auth,)
        connection.putheader('Authorization',auth)
 
    def send_cookie_auth(self, connection):
        """Include Cookie Authentication data in a header"""
 
        cj = cookielib.LWPCookieJar()
        cj.load(self.cookiefile)
 
        for cookie in cj:
            if cookie.name == 'session_id':
                uuidstr = cookie.value
            connection.putheader("Cookie",cookie.name+'='+cookie.value)
 
    ## override the send_host hook to also send authentication info
    def send_host(self, connection, host):
        xmlrpclib.SafeTransport.send_host(self, connection, host)
        if os.path.exists(self.cookiefile):
            self.send_cookie_auth(connection)
        elif self.credentials != ():
            self.send_basic_auth(connection)
 
    def request(self, host, handler, request_body, verbose=0):
        # dummy request class for extracting cookies
        class CookieRequest(urllib2.Request):
            pass
 
        # dummy response class for extracting cookies
        class CookieResponse:
            def __init__(self, headers):
                self.headers = headers
            def info(self):
                return self.headers 
 
        crequest = CookieRequest('https://'+host+'/')
 
        # issue XML-RPC request
        h = self.make_connection(host)
        if verbose:
            h.set_debuglevel(1)
 
        self.send_request(h, handler, request_body)
        self.send_host(h, host)
        self.send_user_agent(h)
 
        # creating a cookie jar for my cookies
        cj = cookielib.LWPCookieJar()
 
        self.send_content(h, request_body)
 
        errcode, errmsg, headers = h.getreply()
 
        cresponse = CookieResponse(headers)
        cj.extract_cookies(cresponse, crequest)
 
        if len(cj) > 0 and self.cookiefile != None:
            cj.save(self.cookiefile)
 
        if errcode != 200:
            raise xmlrpclib.ProtocolError(
                host + handler,
                errcode, errmsg,
                headers
                )
 
        self.verbose = verbose
 
        return self.parse_response(h.getfile())

Secure Screen Sharing in OS X Leopard Through SSH Tunneling

February 13, 2008


Here's a quick tutorial on how to secure the Screen Sharing application in Leopard by tunneling your connection through an encrypted SSH channel.

The new Screen Sharing application is basically just glorified VNC, but it does come with some nice features (dual-screen view, for example). However, just turning on the service will open up a couple of ports that may expose your system to exploitation.

WaterRoof MenuFirst, we'll want to lock down your firewall. Leopard comes with two firewalls: ipfw (ipfirewall—the underlying Unix firewall) and an application layer firewall (the one that pops up sometimes and asks if you want to allow an application to accept incoming connections). You can manage the application layer firewall through System Preferences > Security > Firewall, but in order to block some ports we'll need to set up some rules through ipfw. In order to do this, you can either learn the shell syntax (which isn't terribly complicated) or use a GUI app to interface with it. I chose to use WaterRoof—a frontend open-source GUI for ipfw.

Once you have downloaded WaterRoof, run the application and click on Static Rules. Click the + icon to add a new rule, and use the following information:

Protocol: IP
Rule Action: Deny
Source: not me
Port or range: (leave blank)
Destination address, subnet, or network: me
Port or range: 5900
In, Out, or In/Out: Select the In radio button

This will block port 5900, the default VNC listening port that is opened when you start Screen Sharing. Also, you'll want to block port 88 unless you are using Kerberos for authentication (I believe this is also opened by Screen Sharing and a couple of other apps). Add a new rule and use the same above parameters, but use incoming port 88 instead of 5900.

You should now have two new rules in your table:

deny ip from not me to me dst-port 5900 in
deny ip from not me to me dst-port 88 in

Click Tools > Rules Configuration > Save to startup configuration. Then, click Tools > Startup Script > Install Startup Script. This will make these new rules persist when you restart (otherwise, the system will reset to defaults on the next restart).

Open up Terminal and edit your /etc/sshd_config file with your favorite editor. In order to enable port forwarding add this line to the end of the file:

GatewayPorts yes

Now, open System Preferences > Sharing and enable the Screen Sharing and Remote Login services.

On your other Mac...

Now, from your client computer, open up Terminal and run the following (for reasoning, see the LifeHacker article Add More Functionality to Leopard's Screen Sharing):

defaults write com.apple.ScreenSharing ShowBonjourBrowser_Debug 1

and (to enable quality control settings)...

defaults write com.apple.ScreenSharing \
'NSToolbar Configuration ControlToolbar' -dict-add 'TB Item Identifiers' \
'(Scale,Control,Share,Curtain,Capture,FullScreen,GetClipboard,SendClipboard,Quality)'

Finally...

Now, any time you want to securely connect to your Mac, all you have to do is type the following in Terminal:

ssh username@ip_address_or_hostname -L 5900:localhost:5900

Leopard Screen Sharing Application WindowThe -L flag is the key to all this—it enables local port forwarding and specifies that anything that happens on the specified local port will be forwarded to the given remote host and port (see the man page for more info). The format of the -L option is port:host:hostport so the first 5900 is your local client port, the next option is the host to which to forward, and the third is the remote port. It's slightly confusing at first, but this localhost isn't the client you're connecting from, it is the remote computer to which you are connecting—it means that when the remote host gets forwarded data, it won't pass it on to some other host.

Now, leave that terminal window open and open up /System/Library/CoreServices/Screen Sharing.app (you can drag it to your dock).

In the connect field, type localhost:0 (don't forget the :0). The last part is important because it means to connect to display zero, which translates to port 5900 in VNC land and, for some reason, Leopard will tell you that "You cannot share your own computer" if you type in just localhost (though, you actually can by enabling Screen Sharing and typing that same host, it just creates an pseudo-infinite loop of VNC windows).

Once you type in your username and password, you're done! You can now control your computer remotely through Leopard's Screen Sharing app over a tunneled SSH connection. Here's an example of the Screen Sharing interface (notice the nice dual-monitor support):

Leopard Screen Sharing

Also, because Screen Sharing uses VNC as its base protocol you can interface with your Mac from any Linux, Mac, or Windows VNC client by port forwarding in the same way (on Windows, you'll have to use an SSH client like PuTTY) and connecting to localhost port 5900 with any standard VNC client.

Dirty business: Network Solutions domain registration

January 20, 2008


When a company employs questionable tactics in its business practices, it is many times appropriate to chagrin it publicly in order to make others aware. In that vein, I would simply like to spread the news that Network Solutions (a company who used to be the only registrar of .com's and other domains) has begun a very questionable tactic of automatically registering any domain that is searched for on its site.

TechCrunch's Michael Arrington writes, "So far they’ve registered over 72,000 domain names based on user searches. ... This isn’t costing the company anything, either. Registrars are permitted to register domains for five days without paying any fees to the domain name registry." After the five day period, they likely delete the domain in order to not pay for its actual registration. This five-day leniency was meant to allow registrars to efficiently deal with credit card fraud, but "the fact that Network Solution is using the grace period to stop users from going to competitors is well outside of the original reasons for the rule."

Though domain tasting is not in any way new, this seems to be a twist on the already abused grace period—one that I hope doesn't become commonplace and isn't copied by other registrars.

For more information, see the article on Domain Name News or the TechCrunch article.

Networking Via Carrier Pigeon

December 31, 2007


Let me just trace where this is coming from for you: while laughing again at an XKCD comic, I was led to Google the name "Eric S. Raymond" (the references to Richard Stallman and Linus Torvalds I got, but I didn't know much about ESR), which then led me to his home page and then to the Jargon file (a classic collection of terms and information on hacker culture) and to the Meaning of Hack section.

This story is probably well-known to many seasoned hackers, but it gave me a good laugh:

1990's addition to the hallowed tradition of April Fool RFCs was RFC 1149, A Standard for the Transmission of IP Datagrams on Avian Carriers. This sketched a method for transmitting IP packets via carrier pigeons.

Eleven years later, on 28 April 2001, the Bergen Linux User's Group successfully demonstrated CPIP (Carrier Pigeon IP) between two Linux machines running on opposite sides of a small mountain in Bergen, Norway. Their network stack used printers to hex-dump packets onto paper, pigeons to transport the paper, and OCR software to read the dumps at the other end and feed them to the receiving machine's network layer.

Here is the actual log of the ping command they successfully executed. Note the exceptional packet times.

Script started on Sat Apr 28 11:24:09 2001
vegard@gyversalen:~$ /sbin/ifconfig tun0
tun0      Link encap:Point-to-Point Protocol
          inet addr:10.0.3.2  P-t-P:10.0.3.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:150  Metric:1
          RX packets:1 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0
          RX bytes:88 (88.0 b)  TX bytes:168 (168.0 b)

vegard@gyversalen:~$ ping -i 450 10.0.3.1
PING 10.0.3.1 (10.0.3.1): 56 data bytes
64 bytes from 10.0.3.1: icmp_seq=0 ttl=255 time=6165731.1 ms
64 bytes from 10.0.3.1: icmp_seq=4 ttl=255 time=3211900.8 ms
64 bytes from 10.0.3.1: icmp_seq=2 ttl=255 time=5124922.8 ms
64 bytes from 10.0.3.1: icmp_seq=1 ttl=255 time=6388671.9 ms

— 10.0.3.1 ping statistics —
9 packets transmitted, 4 packets received, 55% packet loss
round-trip min/avg/max = 3211900.8/5222806.6/6388671.9 ms
vegard@gyversalen:~$ exit

Script done on Sat Apr 28 14:14:28 2001

A web page documenting the event, with pictures, is at http://www.blug.linux.no/rfc1149/. In the finest Internet tradition, all software involved was open-source; the custom parts are available for download from the site.

While all acknowledged the magnitude of this achievement, some debate ensued over whether BLUG's implementation was properly conformant to the RFC. It seems they had not used the duct tape specified in 1149 to attach messages to pigeon legs, but instead employed other methods less objectionable to the pigeons. The debate was properly resolved when it was pointed out that the duct-tape specification was not prefixed by a MUST, and was thus a recommendation rather than a requirement.

My Canvas

December 30, 2007


Welcome to my little corner of the web. I'm currently majoring in computer science and minoring in music at Utah State University while working for the Programming and Design Team in USU's Department of Information Technology. Most of the time work seems to be full-time and school is the side job, but reality sometimes reminds me that this is not exactly the case. Don't get me wrong though—school is important and has taught me much, but working on the PAD team has taught me more about computers and even about life than I have ever learned in a classroom. It's exciting to be integrated into a team that deals with projects from every facet of a University and hence from innumerable facets of technology.

Hopefully, I'll share a piece of this here that you may stumble across while perusing the interwebs and it might serve a good purpose for you. That's the ideal situation though—there's much potential for it turning into me rambling about topics that may only interest a few people. But, to those few, welcome! ;)