17 Jan 2012

Sometimes, the best projects come out of the dumbest disputes.

I was in my room, and my former roommate Clockfort and Russ got talking about old chat protocols that we used to use. Clockfort suddenly remembered his old ICQ number, and we went around adding each other on all of our old chat networks.

I took this joke a little far, however. I started making all kinds of new accounts. I went through every protocol supported by pidgin, and signed up for accounts. At the time, pidgin listed QQ as a supported protocol.

I signed up for a QQ account, and tried to connect with pidgin. Unfortunately, it just didn’t work. I found out that the builtin QQ plugin didn’t support the latest QQ protocol. I fount a plugin called libqq-pidgin that did exactly what I needed. So I installed it, and added my one Chinese friend to my buddy list.

Later that night, I wanted to talk to her at work. I booted up Adium, and added my QQ account. Unfortunately, it didn’t work, because like pidgin, Adium is built on top of libpurple, and libpurple dropped official support for QQ. My solution was to write my own QQ plugin for Adium.

The end result is AdiumQQ. It supports basic features right now, like chat and such. It does not support file transfers or captchas just yet. Those features are coming.

Today, I’m posting about it in my blog because it just got accepted in Adium Xtras. I’m really proud, since this is my first open source program I’ve written that people are finding useful.

Thanks to the libqq-pidgin team for making a nice base for me to build my plugin off of!

I will of course announce any new release information on my blog.

27 Dec 2011

I was kind of an idiot in my last post. I wrote a ruby script to symlink my gems’ executables to /usr/local/bin. Well that’s dumb. There’s a much better way to accomplish the same goal, with some healthier side effects! It’s called rvm (or Ruby Version Manager)!

rvm allows you to manage multiple versions of ruby that are installed to a location in your home directory. You can select a version of ruby to use for current session with rvm use 1.9.2 That command will use ruby-1.9.2, provided you installed it with rvm. To install: rvm install 1.9.2 When you have a version of ruby selected, gems will install into the directory that houses that version of ruby, and won’t pollute your system install of ruby.

App::perlbrew (installable through cpan) does exactly the same thing, albeit with Perl! I heartily recommend both if you do development with either ruby or Perl.

15 Jun 2011

Hey, so I bought a Macbook Air a month ago, and I’ve grown to absolutely adore it. It basically comes down to that I have an OS that I don’t need to fix constantly, while also having access to all of the utilities I’m used to using on my Linux/UNIX environments.

I use Homebrew to manage my software, because it seems to be the best package management solution for OS X. I haven’t really tried any others, but I have no inclination to after using Homebrew for the past few months.

Oh and I also learned Ruby. And I kind of like it so far.

Regardless, this post isn’t about my Ruby experience thus far. It’s just documenting a minor annoyance. When I install gems using ruby1.9 from Homebrew, the gems don’t make a symlink in /usr/local, and the internet tells me the right thing to do is to make it myself.

Well fuck that.

Here’s a brief ruby program that will insert these links for you! I’m not claiming to be a Ruby expert, or even competent, so run this at your own risk. It can get a little destructive, and makes some assumptions.

#!/usr/bin/env ruby

require 'RubyGems'

installed_gems = []
prefix = '/usr/local/bin/'
ruby = '/usr/local/Cellar/ruby'

Gem::Specification::all_names().reverse.each do |gem|
  (name, version) = ['', '']
  gem.match(/([\w\-]+)\-([\w\.]+)/) do |m|
    name = m.captures[0]
    version = m.captures[1]
  end

  Gem::Specification.new do |s|
    s.name = name
    s.version = version

    installed_gems.push(s)

  end

  installed_gems.delete_if do |i|
    name == i.name and Gem::Version.new(version) > Gem::Version.new(i.version)
  end
end


installed_gems.each do |gem|
  if File.directory? gem.bin_dir  then
    Dir.entries(gem.bin_dir).each do |file|
     fullpath = gem.bin_dir + '/' + file
     newpath = prefix + file

     if not File.directory? fullpath  then
       if File.symlink? newpath then
         if File.readlink(newpath).match %r{/usr/local/Cellar/ruby} then
           puts "Linking #{fullpath} to #{newpath}..."
           File.unlink newpath
           File.symlink fullpath, newpath
         end
       end
     end
    end
  end
end

Hope that helps.

14 Jun 2011

Have you ever been to a hotel, or an airport, that served wireless? And the after you connected, you get redirected to a page where you pay money, or make an account? Those are called captive portals. Setting up your own is really easy!

The old de facto FOSS software for captive portals was Chillispot. However, this software is old, and broken, and doesn’t really work anymore. So, I used its drop in replacement, CoovaChilli. CoovaChilli is totally compatible with Chillispot, so if you’ve used Chillispot before, you can use your old configuration with CoovaChilli without any modification.

CoovaChilli handles serving DHCP to your clients, as well as setting up routing for you. Your server acts as a router for traffic for auth’d clients. CoovaChilli creates a tun device that it tunnels traffic through, kind of like a VPN. Since it serves DHCP, you can configure it to give your clients DNS servers, proxy information, etc. CoovaChilli will also load up a whole bunch of firewall rules that will restrict what resources clients can access on your network.

First step, set up a simple FreeRadius configuration. I left mine pretty with the Debian defaults, and just created some accounts for testing. This system isn’t in production, so I don’t care about tuning my radius setup. And FreeRadius isn’t the point of this entry.

Once, you have FreeRadius going, download, compile and install CoovaChilli. CoovaChilli doesn’t have Debian or Ubuntu packages that work very well…and building packages from the source doesn’t work perfectly either, so just ./configure, make and make install. Don’t worry, there’s a make deinstall in case you want to remove it cleanly.

After building it, copy /etc/chilli/defaults to /etc/chilli/config and start editing. Some things you’ll want to change:

  • HS_DNS1 and HS_DNS2: the DNS servers given to your hosts
  • HS_RADSECRET: the secret required to talk to your Radius server
  • HS_UAMSECRET: the secret required to talk to your hotspot
  • HS_UAMSERVER: URL to the login page
  • HS_POSTAUTH_PROXY: we’ll talk about this later

You’ll also probably want to set your interfaces. Your WAN interface needs to be set through your OS, but your LAN interface requires absolutely no configuration through your OS - CoovaChilli will do it when it comes up.

It’s also important to run this: sysctl net.ipv4.ip_forward=yes

That will enable IP forwarding on your system.

The other values can be left with their default values. We’re not going to set up a custom login page because we really don’t care. The default is fine for us. You’re going to need to install haserl to use it.

Well cool, we now have a captive portal! Run the init script, and bam. You now have a captive portal.

Tomorrow, we’ll talk about going beyond basic configuration, and content modification using Squid3 and GreasySpoon.

11 May 2011

I had this question the other day when I was writing my Exherbo packager the other day. I never found a good, conclusive answer through Google or Identi.ca/Twitter, so I tried something fairly obvious, and it worked!

When doing unit tests for an interactive program, oftentimes the need comes up to fake STDIN, and provide some test interactions. In Perl, this is actually rather trivial.

A note on filehandles in Perl

In Perl, we often see this syntax for opening files:

open(HANDLE, 'path');
print while (<foo>);
close(HANDLE);

This is bad style for a number of reasons (not checking to see if open was successful, not using lexical filehandles, not using 3 param open()…), but regardless, there is a thing or two worth noting here that’s relevant to the rest of the discussion.

When you open a filehandle in this manner, you aren’t getting a scalar, an array, or even a hash back. You’re getting a global typeglob. What the hell does that even mean?

Perl has three separate symbol tables for storing variables, one for each type. Typeglobs are a way to access all three, and are denoted by the asterisk sigil. Hopefully that’ll clear up possible questions about the syntax below.

Another note about Perl, but this time about scope

Most newcomers to Perl understand lexical scope and global scope, but get confused about ‘local’ or dynamic scope.

Dynamic scope is pretty hackish, but also very useful. Dynamic variables (declared with the ‘local’ keyword) are lexical, however their scope also includes the bodies of any functions that get called within the lexical scope.

This simple example code should highlight what I mean.

#!/usr/bin/env perl

use strict;
use warnings;
use 5.010;

our $foo = "foo!";

sub foofunc {
    say $foo;
}

foofunc();

{
    local $foo = "bar!";
    foofunc();
}

foofunc();

foofunc is expecting global $foo, however localizing (giving it dynamic scope) in that block allow us to change the value of the global the function sees. Dynamic scope ends in the same place lexical scope would end.

Enough build-up

Now that you understand these two key concepts, it should be fairly easy to see how we’re going to fake STDIN. Here’s the code:

{
    open(FH, '<', 't/input.1') or die $!;
    local *STDIN;
    *STDIN = *FH;
    Exherbo::Packager::init_config('t/config.yml');
    close(FH);
}

Here, we open a new filehandle (lexical filehandles will not work here), and then give STDIN dynamic scope and set its value to our filehandle. It’s a simple enough hack, but it works satisfactorily.

If this is the absolute wrong way to go about it, I’d love to know. This is just what I came up with when I couldn’t find what I thought to be a reasonable solution with Google.

25 Apr 2011

Dancer is the hottest new Perl PSGI-compatible web framework. You might be thinking, Perl web development? Doesn’t that use CGI? Isn’t CGI balls slow? Well…you’re wrong. Most things you think you know about Perl are probably wrong.

Let’s start out with debunking the myth of CGI. CGI is slow, but there are a number of Perl-compatible alternatives.

The most well-know, and best supported alternative is FastCGI. Don’t hate on FastCGI because it has CGI in the name, it avoids the big pitfall of CGI (loading a new interpreter every time a new page is called) by having a FastCGI server load your interpreter, and then responding to requests sent to the FastCGI server from the web server.

This is gives us a clear performance improvement (not having to load a new interpreter every time you load up a web page), as well as a security benefit (total isolation from the web server user/process).

The other well-known alternative to CGI is mod_perl. mod_perl is Apache, specific, and it’s also pretty old and janky. I’m not going to talk about it, mainly because I have never used it. It’s poorly documented, and there exist better alternatives anyway. Let’s move on.

Ahh, PSGI. We love PSGI. PSGI is fast, and is under ridiculously rigorous development. PSGI applications get a hashref that provides all of the necessary information about the environment: request method, uri, variables, protocol info, etc. It then returns an arrayref of a status code, HTTP headers and the document body.

Most of the time, you’ll be using a framework, so you’ll never have to care about interacting with the internals of PSGI directly.

Astute readers are probably thinking, “Hey, if PSGI is perl, then what does that run on, and how does it interact with my web server?” Well, good reader, it runs on any of the above-mentioned frameworks and more! There’s an Apache mod for it, it works with CGI, FastCGI, and mod_perl, and you have have to deal with any of that shit!

Plack is the reference implementation of the PSGI middleware. It sits between your webserver and Perl application serving up the PSGI environment for you, while translating the arrayref you return into meaningful data for the web server.

Hopefully, this clears up some confusion about Perl and web dev, along with PSGI and its role in Perl web dev. This post also goes out to @seanmcgary, the ignorant shit who inspired this post (and by ignorant shit I mean pretty cool guy who is very knowledgeable about PHP and Javascript, but knows nothing of the Perl world).

15 Apr 2011

So I mentioned in a previous post that I was writing a scoring engine for CRTs, the hacking competition I’m holding for CSH. Well obviously I’m writing it in Perl, because I know Perl best, and it seems like the perfect sort of language for this task.

Actually, what drew me to writing the scoring engine in Perl is the sheer power of POE. But that’s totally a topic for another post.

When I started work on the scoring engine, for some reason I got the notion into my head of making it cross platform. I don’t know why the hell I’d ever do that, since all I tend to use are UNIX-based machines, but whatever, fuckit, that’s what I decided to do.

The first (and so far only) real hurdle I hit when writing cross-platform code is dealing with configuration file paths appropriately across different OSes. However, I found an interesting article on reddit that solved this addressed this exact problem…in Python.

I figured there would be a Perl tool because why the hell not, and guess what? I was so blessed to find File::System.

File::System is a fabulous perl module that allows programmers to abstract the real filesystem away behind a virtual filesystem. You can arbitrarily set the root to whatever directory you want, or with File::System::Layered, merge bunches of directories into your root.

Thanks to this perl module, it’s trivial to set up OS-specific configuration locations without dealing with tons of bullshit in your code. Let me share some of my scoring engine code with you to show you how it’s done.

package Scoring::Engine::Backend;

use strict;
use warnings;
use 5.012;

require Exporter;
our @ISA = qw/Exporter/;
our @EXPORT_OK = qw/fs/;

sub fs {
    state $fs;

    if ($Test::Scoring::Engine::test) {
        require Scoring::Engine::Backend::Test;

        $fs = $Scoring::Engine::Backend::Test::fs;
        return $fs;
    }

    given ($^O) {
        when ("MSWin32") {
            require Scoring::Engine::Backend::Windows;

            $fs = $Scoring::Engine::Backend::Windows::fs;
        }

        when ("linux") {
            require Scoring::Engine::Backend::Linux;

            $fs = $Scoring::Engine::Backend::Linux::fs;
        }

        when ("darwin") {
            require Scoring::Engine::Backend::Mac;

            $fs = $Scoring::Engine::Backend::Mac::fs;
        }
    }

    return $fs;
}

This right here is the bulk of the code. This uses some modern Perl constructs, so if any of this looks unfamiliar or even scary to you, I suggest you go pick up chromatic’s excellent Modern Perl book. You have some catching up to do. :)

Moving right along here, it’s fairly obvious what this code does. We export a simple function called fs, which pulls your OS from the $^O variable and switches over it. Based on that, I load whatever OS specific module I need, and that gives me a File::System::Object to work with.

Here’s what the OS specific modules look like:

package Scoring::Engine::Backend::Mac;

use strict;
use warnings;
use 5.012;

use File::System;

our $fs = File::System->new('Real',
    root => "$ENV{'HOME'}/.scoringengine/");
1;

The first argument I pass into the File::System constructor denotes what type of File::System::Object I get back. In this case, I want the simple File::System::Real, since I only need to map one real directory to my virtual filesystem root.

After doing that, use is simple:

use Scoring::Engine::Backend qw/fs/;
use YAML::Any qw/Load/;
use constant DNS_CONFIG = '/dns.yml';

my $fs = fs;
my $fh = $fs->lookup(DNS_CONFIG)->open("r");
local $/;
my $teams = Load(<$fh>);
close($fh);

Calling File::System::Obect::lookup finds me the actual file that I want, and gives me a File::System::Object back that I can call the open function on. open works just the way it normally does, giving me a plain old filehandle to manipulate.

After that, everything is peaches.

Now, in all of my code that needs to access the filesystem, I have absolutely no need to worry about translating paths or anything like that. It’s as easy as getting my File::System::Object and accessing files with that.

Another benefit is unit testing. If you scroll back up to my first code post, you’ll totally notice that there’s a check to see if a test module is loaded.

This is for ease of testing. In my unit test code (you are writing unit tests, right?), I can easily just load that module before I load Scoring::Engine, and I don’t have to do any other trickery to have my code look for my cooked test configuration files in my unit test directory.

File::System is pretty hot, and I really hope people have embraced it as the de-facto way to deal with filesystem access.

11 Apr 2011

I’ve reworked my blog quite a bit. I transferred my some of my old Wordpress posts to a new blogging engine – jekyll.

Jekyll is pretty fantastic, in that it generates static sites from posts done in markdown, and templates made with the Liquid templating engine. It’s gaining popularity thanks to being the technology that runs github pages.

I heard about it from Ryan Clough a few years ago (before it was cool), and then my friend Russel Harmon encouraged me to start using it for my own blog. Since I accidentally took down my wordpress site sometime ago, I decided to give it a go. I also decided to roll out nginx instead of Apache since my servers are too old to really handle Apache effectively.

So far, I definitely like it. I love writing my blog in vim (the best text editor) and doing version control with git. I still need to set up git hooks to auto-publish when I commit.

I write all of the entries on my OpenBSD dev server, charmeleon, and then push the generated HTML to my web server, so I don’t need to bother setting up the jekyll tools on my web server or anything like that.

nginx is fast. It’s really fast, and it’s trivial to configure (for static sites, anyway). I’m going to keep using it, and possibly try and use it when I set up my personal Diaspora node.

09 Apr 2011

A week ago, I participated in a competition at RIT called ISTS, the Internet Security Talent Search. This competition challenges students in the area to form teams to defend and maintain a small network, while attacking other teams’ network. And lemme tell you, this was a fucking blast. I did it last year, but now that I’m significantly more competent, I had so much more fun.

The competition works something like this: there are 14 teams that all have identical setups of mixed Windows, Linux and FreeBSD machines. Three of the five machines host network services that need to have maximum uptime, and the other two machines are clients that can be used for attacking. Teams get points for every minute of uptime each service has, as well as for attacking machines of other teams.

During the competition, teams are given challenges to complete called business injects, which can range from adding services, to adding features to existing services, to attacking other teams. It really runs the gamut.

However, while we’re busy doing our thing, the red team, made up of graduates, security consultants, etc. are indiscriminately attacking everyone. Since every team has identical machines with identical configurations, we all know the security vulns that other teams have as soon as we discover them ourselves, so really the red team is kind of at a disadvantage.

For the CSH team (Team OPCOMM), I was mail bitch (because apparently no one wants to deal with postfix), and FreeBSD wizard. I maintained the postfix and dovecot installation on a teammates machine, while also maintaining FTP and DNS on my own. Unsurprisingly, my box was the only one box on the team that didn’t get pwned during the competition. And I’m not saying that it’s unsurprising because I’m pompous or anything, I’m saying it because I was maintaining the FreeBSD box. I mean really, next to all that Windows and Linux-y shit, FreeBSD is a fucking tank.

Now, since I’m talking about ISTS, you’re probably wondering why this post is titled CRTS. Well, through talking to people on CSH after the competition, I found that many people were interested in the idea of the competition, but they didn’t think they had enough skill to compete.

So I decided to hold an event just like ISTS for CSH.

I’m calling it the Computer Science House Root Type Person Talent Search, or CSH RTP Talent Search, or CRTS. It’s definitely focused at people who have little to no systems administration experience, but still challenging enough such that people who know what they’re doingwill still have fun.

Prior, there will be a fuckton of seminars given about topics people will need to be familiar with, starting with basic UNIX skills ranging all the way up to intermediate hacking techniques.

It’s going to be a great weekend, and I’ve already gotten a lot of interest from people on CSH. I’ve planned some fun vulns for teams to discover, and I’m writing a bitchin’ Perl scoring engine using POE and Dancer. All of the code is on github, and I’ll make sure to list the different setups in detail after the competition.

06 Jul 2010

I’ve been working on my Perl library for Formspring.me, and I’ve run into a pretty egregious issue. Apparently they aren’t following the OAuth spec correctly, and aren’t returning a oauth_callback_confirmed parameter. The problem for me lies in that the wonderful Perl OAuth library, Net::OAuth requires that the OAuth response return this parameter, and errors if it’s not present. I’ve emailed api@formspring.me about it, but they have yet to answer my email.

[1] http://tools.ietf.org/html/rfc5849#section-2.1