B-Con
FoxyProxy, Firefox 3.5, and DNS Leaking
• By Brad Conte, November 13, 2009
• Post Categories: Computers & Tech, Security
[Update: Jan. 24, 2010] The DNS leaking problem described in this article applied to FoxyProxy v2.14. On Jan. 12, FoxyProxy v2.17 fixed the problem.


FoxyProxy is a popular Firefox extension that enables users to, setup, easily manage, and quickly switch between multiple proxy configurations. One of the most common uses of a proxy server is for security/privacy. By establishing an encrypted connection (usually via SSH) with a proxy server on a trusted network, you can have your web traffic go through an encrypted “pipe” to that server and have that server send and receive web requests on your behalf, relaying data to and from you only through that pipe. By doing this you eliminate the risk that someone on your current network could see your HTTP traffic. Maybe you don’t trust other clients on the network, maybe you don’t trust the gateway, it doesn’t matter — your HTTP(S) traffic is encrypted and shielded from prying eyes. (Readers unfamiliar with the concept of using HTTP proxies through SSH tunnels are encouraged to research the matter, there are many well-written tutorials available.)

There are many other popular uses of proxy servers, but the application of encrypted web traffic is of concern in this case for the following reason: A key problem that arises when using web proxy servers is the issue of handling DNS requests. DNS does not go through the HTTP protocol, so even if HTTP is being forwarded to a proxy the DNS requests may not be. If DNS requests are sent out over the network like normal then eavesdroppers can still read them. So although the actual traffic may be encrypted, the DNS queries behave normally and may cause the same problems that using an encrypted tunnel was designed to avoid in the first place. A situation in which HTTP traffic is encrypted but DNS is not is referred to as “DNS leaking”. When using a proxy for the benefit of security or privacy, DNS leaking may be just as bad as non-encrypted traffic.

Solving the DNS leaking problem is simple. One type of proxy, SOCKS5, can forward DNS requests as well as HTTP(S) data. A user simply needs to tell their browser to use the SOCKS5 proxy for both HTTP(S) and DNS and then both will be routed through the encrypted stream, allowing the user to surf the web with greatly strengthened security and privacy.

However, Firefox users who use FoxyProxy at the moment will encounter a problem when using DNS forwarding to a SOCKS5 proxy. When using FoxyProxy, DNS leaking occurs even when it is configured not to, which has made many users very upset. Initially many people thought the problem was with Firefox 3.5, but others confirmed it was only present with FoxyProxy installed. Unfortunately, however, not everyone is convinced that this is FoxyProxy-related behavior and I have not found anyone who has presented a solution yet. I plan to do both.

This is the basic setup for my tests:

  • I set up an SSH server.
  • I established an SSH connection and used the built-in SOCKS5 functionality of the SSH server daemon:
    $ ssh username@myserver -D localhost:8080
    (For the non-SSH inclined: This command forwarded all traffic my client sends to itself on port 8080 through the SSH connection to the SSH server, which then acts as a SOCKS5 proxy and sends the data on to the destination.)
  • I used Wireshark to monitor all packets, specifically DNS requests, sent or received my network’s interface. Note that DNS requests tunneled over the SSH connection to the SOCKS5 proxy are not visible to the packet sniffer.
  • I monitored my Firefox configuration in about:config. (All network proxy-related settings are under the filter network.proxy.)
  • I used Firefox v3.5.5 and FoxyProxy v2.14.

Using this I was able to monitor all DNS requests while I experimented with Firefox and FoxyProxy using a SOCKS5 proxy. I did a base test with no proxy configuration, a test using Firefox’s included proxy management, and a test using Foxyproxy for proxy management.

Using no proxy
Starting with a default configuration (SSH SOCKS connection established but no proxy settings configured to use it) I visited several websites such as google.com, yahoo.com, and schneier.com. This was the simple base test.

I checked showmyip.com to get my IP address.

The relevant about:config settings:
network.proxy.socks “” network.proxy.socks_port 0 network.proxy.socks_remote_dns false network.proxy.type 0
Via Wireshark I watched as the websites generated normal DNS requests over the standard network.

Using Firefox to configure proxy settings
I restarted Firefox to avoid any cached DNS entries. Then, without FoxyProxy installed, I setup my SOCKS5 proxy. (Note that FoxyProxy replaces the standard Firefox proxy editor, so it is impossible to not use FoxyProxy when it is installed.)

Under Firefox’s Preferences/Tools (depending on your operating system) I went to the “Advanced” tab, “Network” sub-tab, and opened “Settings”. I chose “Manual proxy configuration” and entered “localhost” for the SOCKS Host and “8080″ for the port.

Unfortunately, Firefox v3.5 does not support a GUI method of enabling DNS SOCKS5 proxying, so I had to manually go to about:config and enable it by setting network.proxy.socks_remote_dns to “true”.

I checked showmyip.com to ensure that my IP address displayed as coming from the server and not my client. It did show as coming from the server, so Firefox was using the proxy.

The final about:config settings were:
network.proxy.socks localhost network.proxy.socks_port 8080 network.proxy.socks_remote_dns true network.proxy.type 1
I visited the same websites. Via Wireshark, I did not see any DNS requests sent over the standard network. Firefox channeled both the HTTP and DNS data through the SSH tunnel perfectly.

Using FoxyProxy to configure proxy settings
I reset all the about:config settings back to their defaults. Then I installed FoxyProxy Standard v2.14. I went to FoxyProxy’s options and, under the “Proxies” tab, created a new proxy entry whch I named “SSH SOCKS5″. I set it to connect to “localhost” on port 8080. As well, I check-marked the “SOCKS proxy?” box and selected “SOCKS v5″. I went to the “Global Options” tab and checked the box “Use SOCKS proxy for DNS lookups”. To let this take effect, I had to restart Firefox.

When Firefox had restarted, I went to the Tools > FoxyProxy menu and selected to “Use proxy SSH SOCKS5 for all URLS”. I checked showmyip.com to ensure that my IP address displayed as coming from the server and not my client. It did show as coming from the server, so Firefox was using the proxy.

I checked about:config:
network.proxy.socks “” network.proxy.socks_port 0 network.proxy.socks_remote_dns false network.proxy.type 0
The configuration was the same as the default, so apparently FoxyProxy does not adjust about:config to do its work.

Watching the DNS requests via Wireshark, I watched as all the website visits generated DNS requests over the normal network. Complete and thorough DNS leaking. And I would like to emphasize that I had selected “Use SOCKS proxy for DNS lookups”, which is FoxyProxy’s option to address the DNS leaking issue.

Fixing DNS leaking
There was no question about it, FoxyProxy caused the DNS leaking in my test. I wanted to solve the problem so I fiddled with about:config.

In about:config I manually set network.proxy.type to 1. I verified my IP address was from the server via showmyip.com.

The new about:config:
network.proxy.socks network.proxy.socks_port 0 network.proxy.socks_remote_dns false network.proxy.type 1
I watched for DNS requests again via Wireshark. I saw none. It seemed that just manually setting network.proxy.type to 1 fixed the FoxyProxy DNS leaking problem.

I also tried other about:config settings, such as manually changing network.proxy.socks_remote_dns to “true”, but that didn’t work. The above was the only change in about:config that I found that fixed the problem.

Summary
I repeated the results above three times in different orders on different computers on both Linux and Windows to ensure I made no configuration mistakes and to ensure that the behavior was consistent and cross-platform. All the tests yielded the same results. Here is the final summary:

  • Firefox v3.5 does not suffer from DNS leaking by itself.
  • DNS leaking occurs when FoxyProxy is managing the proxies.
  • FoxyProxy does not suffer from DNS leaking when network.proxy.type is manually set to 1.

It is obvious that FoxyProxy does not adjust about:config in order to configure proxy settings, but I do not know why. Many Firefox extensions adjust about:config in order to accomplish their goals and I know of no reason they should not. It’s possible that FoxyProxy has not had a need to do so before, but in light of this serious problem that may need to change. The quickest/simplest solution for FoxyProxy may to set network.proxy.type to 1 if the currently enabled proxy is SOCKS5 and if the global options for FoxyProxy (or the about:config for Firefox) are set to enable DNS forwarding.

However, although this seems to indicate that FoxyProxy has made a mistake, I don’t know that FoxyProxy is the party at fault. Clearly FoxyProxy does not have to alter about:config in order to change the other proxy settings, so why must network.proxy.type be set in about:config in order for DNS forwarding to work? Note that network.proxy.type isn’t related to DNS forwarding, it just specifies which type of proxy is enabled. For all I know someone implemented a hack in Firefox that checks about:config when it shouldn’t. Of course, I don’t know that and I don’t know if this is expected behavior from Firefox or not. It could be that FoxyProxy isn’t setting whatever hidden configuration for DNS forwarding that exists on the same plane as the other invisible proxy settings it uses. Or maybe FoxyProxy is relying on an unreliable hack in order to avoid changing about:config. I don’t know about any of that. What I do know is that Firefox by itself does not have this DNS leaking problem, FoxyProxy does, and a simple solution exists.

Again, I am certainly not the first person to note this problem, but a) I have seen many people blame Firefox for this bug, and b) I have not yet seen anyone else mention the solution that I noted above.

I leave it to someone with more time and knowledge about these software projects to determine which project should have which bug report filed. This needs to be fixed permanently.

Three Tips for the Linux Terminal
• By Brad Conte, January 11, 2009
• Post Categories: Computers & Tech
The power of Linux lies in the tools it uses. If you spend a lot of time in a terminal, you likely value anything that makes using it smoother. Here are a few tips to help make the terminal experience as smooth as possible. These tips are all shell-independent.

  • Change directories with the directory stack
    The Bash shell (as well as others, like Zsh) have a built-in “back” feature for navigating directories. The built-in “pushd” command will put your current working path at the top of a shell-maintained stack and allow you to change to another directory. To go back to the saved path you can use “popd”.

    Example:
    user@host : /some/long/path/you/don’t/want/to/retype$ pushd /some/other/path/ /some/long/path/you/don’t/want/to/retype user@host : /some/other/path/$ [do stuff] user@host : /some/other/path/$ popd /some/big/long/directory/you/don’t/want/to/retype user@host : /some/long/path/you/don’t/want/to/retype$
    Since “pushd” stores the directories in a stack, you can push multiple directories onto the stack and later pop them off in the reverse order you pushed them. It’s basically the standard “cd” only with a “back” feature. Speaking of which, the command “$ cd -” will always take you back to the previous directory you were in.

  • Interact with the X clipboard
    Before I discovered “xclip”, one of the most annoying things about being in a terminal was my lack of access to the X clipboard. Most shells (all the ones I’ve come across) have a simple means of pasting text into the terminal, but not all have an elegant means of getting text out of the terminal. Yes, highlight-and-middle-click is often an option, but it’s a) not always feasible, and b) not always convenient. Remember, this is the terminal, you don’t necessarily want to be using your mouse. “xclip” removes the annoyance of using the X clipboard.

    xclip can read and store to the clipboard from the standard input. As well, it can output the current contents of the clipboard. Since xclip can manipulate multiple clipboard buffers, the argument “-selection c” must be used to select the standard X clipboard. The “-i” and “-o” arguments tell xclip whether you are inputting or outputting clipboard contents, respectively.

    Example:
    $ pwd /some/long/path/you/don’t/want/to/retype $ ls /some/path | xclip -selection c -i
    You may now paste (standard Ctrl-v, or right-click -> paste) the directory listing where ever you choose. Another example:
    xclip -selection c -o | cat >> /some/file
    This will concatenate the contents of the clipboard to “/some/file”.

    If you only use yourself using xclip to manage the X clipboard, you might want to consider aliasing “xclip” to “xclip -selection c” to make it simpler to type. Or you could take it one step further and alias “xcopy” to “xclip -selection c -i” and “xpaste” to “xclip -selection c -o”, or something similar.

  • Use “head” and “tail” more powerfully
    You probably know how to use “head” to extract the first N lines from a file and “tail” to extract the last N lines of a file. While this is useful, it’s often just as useful to extract the complement of those selections, namely, everything except the first N lines or everything except the last N lines.

    Thankfully, “head” and “tail” are powerful enough to accommodate those needs. “head” allows you to extract either a finite quantity of text from the top or everything but a finite quantity of text from the bottom, and “tail” allows you to extract a finite quantity of text from the bottom or everything but a finite quantity of text from the top.

    • head -n N — by default outputs the first N lines. Using -N outputs all but the last N lines.

    • tail -n N — by default outputs the last N lines. Using +N outputs lines starting on the Nth.

    Example:
    /tmp $ cat example 1 2 3 4 5 /tmp $ head -n 2 example 1 2 /tmp $ tail -n 2 example 4 5 /tmp $ head -n -2 example 1 2 3 /tmp $ tail -n +3 example 3 4 5
    Note that tail’s complement mode requires you to specify the first line number to include in the output. Thus if you want all but the top N lines, actually specify N+1.

LoginMSG
• By Brad Conte, November 25, 2008
• Post Categories: My Projects
About
I wrote LoginMSG to address a very simple convenience that I was without in my day-to-day life in Linux, namely, a simple way to leave myself a one-time message for the next time I logged in.

Keeping to-do lists is one thing, but quick “first thing tomorrow” reminders are another. After writing my fair share of such reminders, I got tired of going through post-it notes and decided to write a quick script that would allow me to automatically display myself a message the next time I logged in.

Thus LoginMSG was born. LoginMSG is a simple shell script (less than 50 lines long) that stores a text message and displays it. You can add a message, append to the existing message, remove the message, and view the existing message. When you view the message, a simple, no-frills xmessage box is displayed center-screen with your message, allowing you to read it and then remove it or keep it.



Download
LoginMSG v.1Jan 6, 2009

Usage
LoginMSG v.1 – Display yourself a message (the next time X starts) usage: loginmsg [ options ] –add MSG : Create a message with contents MSG, or append MSG to the existing message contents. Message contents are stored in ~/.loginmsg. –show : Display the message. –remove : Remove any existing message.


Place the script somewhere in your $PATH. Add (or append) a message from a terminal using “loginmsg –add”. To display any existing messages when you login, have your desktop environment run “loginmsg –show” when you log in. LoginMSG does not have a feature to make itself automatically start when a user logs in — you will have to see to that manually. There are many ways to do this. For example, in Gnome you could add it to the “Session” list in System -> Preferences -> Session. In Openbox, you could add it to ~/.config/openbox/autostart.sh. Reference the help pages for your specific desktop environment.

ArchLinux AUR Contributions
• By Brad Conte, September 27, 2008
• Post Categories: My Projects
I’m a user of ArchLinux, a lightweight and flexible Linux distribution that tries to Keep It Simple.

There are thousands of packages officially maintained in Arch’s package repositories. However, to ensure the robustness and completeness of available packages, a supplementary user-administrated repository exists, where users can create and maintain their own packages. This is called the Arch User Repository. The AUR allows users to add lesser-known packages that are not widely used enough to warrant maintenance time from an official developer, create spin-off packages of packages in the official repositories, contribute their own scripts, etc.

I’ve made a few contributions to the AUR. To see them, I refer you to:
My AUR profile
My AUR List of Packages

Bash Path Hashing
• By Brad Conte, September 5, 2008
• Post Categories: Computers & Tech
Bash is a Unix shell of many features. One of those features, which is both useful and potentially annoying, is the path hash table.

The environment variable we are probably most familiar with is PATH — it contains all the paths that should be searched when we specify an executable to run. Bash starts with the first path specified in PATH and looks to see if there is an executable present, if there is not it checks the second directory, and so on until it either finds an executable with the specified name or it runs out of paths to search.

The path of an executable practically never changes. “ls” is always in the same place, as is “cat”, and every other executable you might have. Thus, to save time, the first time Bash executes an executable it saves the path it finds the executable in, this way Bash can avoid searching for the executable again. The first time you execute “ls”, Bash has to search for it. The second through bajillionth times you execute it, Bash will just look up the full path from the table — much more efficient. It is important to note that every instance of bash maintains its own path hash table — thus if you have multiple terminals open they will not share path tables.

However, if the actual desired path of an executable changes, problems can arise. By default, Bash will not look for an executable again. If an executable changes paths, Bash will not find it. If an executable is duplicated to a new path, Bash will execute the original executable even if the new one is in a path of higher priority (namely, listed first in PATH). As can be imagined, this can cause quite a headache in these rare scenarios if one is unfamiliar with Bash path hashing. If you create a script, execute it, then edit it and copy it somewhere else (say from your personal “bin” to a global “bin”), the old version will still execute. If you simply move an executable between paths, bash will not find the new executable despite the fact that it seemingly should. Observe the following example, in which I create “myscript” in my home bin, run it, copy it to a global bin, run “myscript” again, and execute the one in my home bin again.

Example of Bash storing the full path of a script and not recognizing a new one.
(This image can suffice stand-alone — feel free to redistribute it.)

Thankfully, however, the hash table is easily manipulated — by the builtin shell command “hash” no less. There are four switches that are likely of the most interest to you:
  • “-d [name]” will delete a specific entry from the table
  • “-r” will remove all entries from the table
  • “-t [name]” will list the save path for the given executable name
  • “-l” will list all existing executable -> path entries in the table
Using this tool you can view existing hashes and remove old stale ones as you see fit. To solve an out-of-date path hash problem, simple removing it will suffice. The next time the command is run the path hash will be re-updated. For more details, I refer you to the following key excerpts from the Bash man page:
If the name is neither a shell function nor a builtin, and contains no slashes, bash searches each element of the PATH for a directory con- taining an executable file by that name. Bash uses a hash table to remember the full pathnames of executable files (see hash under SHELL BUILTIN COMMANDS below). A full search of the directories in PATH is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell prints an error message and returns an exit status of 127. [...] hash [-lr] [-p filename] [-dt] [name] For each name, the full file name of the command is determined by searching the directories in $PATH and remembered. If the -p option is supplied, no path search is performed, and filename is used as the full file name of the command. The -r option causes the shell to forget all remembered locations. The -d option causes the shell to forget the remembered location of each name. If the -t option is supplied, the full pathname to which each name corresponds is printed. If multiple name arguments are supplied with -t, the name is printed before the hashed full pathname. The -l option causes output to be displayed in a for- mat that may be reused as input. If no arguments are given, or if only -l is supplied, information about remembered commands is printed. The return status is true unless a name is not found or an invalid option is supplied.

How to Review a Linux Distribution
• By Brad Conte, July 16, 2008
• Post Categories: Computers & Tech
The GNU/Linux project has begot the most versatile operating system ever. It’s free, open source and designed to be modified and built upon by its users. The heart of the Linux philosophy is the concept of choice. Linux is about providing its users with the freedom to choose what they want to do and how they want to do it. Because both Linux and the software developed for it is so versatile, there exist hundreds of Linux distributions, each one being nothing more than a different collection of software and configurations running on top of the Linux kernel.

Because of the number of Linux distributions and the degree to which their styles/configurations can vary, a given user usually has the ability to choose a distribution closely suited to their specific needs. To aid the ever-prevalent distro-seeker, many Linux users have sought to provide written reviews of various Linux distros. Unfortunately, many reviews fall short. With the increasing population of Linux users, and the increasing number of Linux distributions, there has been a notable increase in unhelpful reviews.

Which leads to the point of this article, namely, how to review a Linux distro. The idea of reviewing a Linux distro is to inform the reader as to how the specific Linux distro in question is different from the other Linux distros. To do this, a reviewer must provide an analysis of the software and configurations that set the disto in question apart from other distros, putting solid emphasis on the big differences, less emphasis on the minor differences, and no attention to the things that are inherent in all Linux distributions. (If you are writing to inform the writer about Linux, you should do that instead, rather than pretend you are reviewing any specific distro.) This basic principle holds for almost any review of any product. For example, movie reviews tell you why one movie, a four-star action flick, is different than another movie, a two-star romantic comedy. The movie reviewer doesn’t spend time explaining the concepts of cut-scenes and character development, it merely explains the aspects of a movie that make it unique.

This article is aimed at the potential Linux distro review writer. It is split into two main sections: things one should review, and things one should not review. Most of the points have sample topics for that point, some of the points and sample topics are more advanced/technical, some are less so. No good review must cover every point and sample topic in this article, this is just a broad list of good ideas. Suit your information for the knowledge level of your target audience.

Here’s a list of things that make for a good review. This is not an exhaustive list, but it covers a lot of ground.
  • Philosophy
    Every Linux distro has a philosophy, namely, a statement of purpose and a set of guidelines for development that support that purpose. “Linux for human beings,” “KISS,” “Free, robust, stable,” “Design for control,” are some philosophies that describe various distros. Anyone using a distro with one of those philosophies would instantly recognize it.

    This topic is not optional, you must state the distro’s philosophy and exemplify it throughout your review. Consequentially, it is probably the best place to start your distro review, as what you write thereafter should exemplify the philosophy. Remember, your goal is to show how the distro is unique, and it is the philosophy that dictates why the distro unique. All criticisms or negative points against the distro should be held in light of the distro’s philosophy. Is the distro complicated? That might be worth mentioning, but if the distro strives to put user control first and simplicity is of no concern then complexity is not a short-coming of the distro but rather a side-effect of its philosophy. Rather than criticizing a distro for being too complex, instead note that it is designed for experts. Many reviews fail to evaluate a distro for what it is and criticize a distro for lacking things it does not strive to have.

    As boring as it may seem, a quick history of the foundations of the distro might prove very informative. Understanding why a distro was created in the first place can say a lot about what its like today and where it might be tomorrow.

    Sample topics:
    • Who is the distro’s intended audience? The newbie, the guru, the average home user, the developer, the server administrator?
    • Does the distro tend to value stability or bleeding edge software? (See later points.)
    • Is the distro designed for users who like to control everything?
    • What is the history of the development of the distro? Why was it created?
    • How robust is a base from-disk install of the distro? (See later points.)
  • The parent distro
    If the distro in question is itself based on another distro (many are) you should mention the parent distro and how this spin-off/child distro differs from its parent. Some parent-child relationships are distant, some are close. Some spin-off distros maintain their own package repositories and make their own configuration decisions, some are nothing more than the parent distro with a different default window manager and a few extra pre-installed packages. Telling the reader what the parent distro is and how closely the child is related to it is extremely informative for those either familiar with the parent or who will seek to become familiar with the parent.
  • The package manager
    The package manager is the heart of a Linux distro. It is how the user most intimately adds to and subtracts from his system. The package manager is arguably the most important and unique component of a distro. Even though most package managers offer the same rudimentary functions, you should review the package manager. And the word “review” does not imply that you should confirm that there are indeed commands for installing and removing packages. You need to provide enough information that it’s clear how the package manager feels to the user. Explain what sets the package manager apart from other package managers. Different distributions make it easier/harder to eliminate orphaned packages or check dependency information, and many have different ideas of what security precautions to take.

    Sample topics:
    • Does the package manager have a GUI?
    • How easy is it to upgrade all the packages in the system?
    • Does it provide clear output informing the user what its doing?
    • What level of security is offered? Package authenticity verification? SSL downloads?
    • Does it ever require that the user perform manual tasks to complete a package installation/integration into the system? (Ie, removing certain configuration files or backups.)
    • How is the package database stored? How easily human-readable is it? How easily backup-able is it?
    • How many tools are a part of the package manager? How many are necessary for day-to-day use?
    • How easy is it to perform a system upgrade?
  • Support/Documentation
    The level of support and/or documentation available for a distro will likely be one of the most significant influences in a user’s experience with a distro.

    The interactive support offered by a forum (and the archived support offered by its search function) can be priceless as a user gets started with a distro and has questions as they encounter Linux phenomena they are not familiar with. A wiki can help the user through the install and/or basic system setup, setup common software, configure it the way they want, and fix common bugs. The absence of a wiki can mean many hours of Googling for decentralized information and exasperation, leading to unfixed problems and a poorer user experience. A documentation tree (somewhat rare outside of behemoth distros) can help a user dig deeply into the distro and modify/fix it if they are so inclined.

    Sample topics:
    • Does the distro have an official forum? How large is it?
    • Does the distro have a wiki? How expansive is it? Does it cover the configuration of sudo? What are some of the more obscure articles it has?
    • Does the distro have developer-written/contributed documentation?
  • The Packages
    While the package manager controls the addition/removal of packages to/from the system, it would be foolish to overlook reviewing the packages themselves. The packages will be composed of compressed archives, arraigned with file hierarchy and package metadata that handles dependency checking, integrity verification, and the like.

    It is arguable that the layout of the filesystem be included in this topic. Many distros have their own ideas about how the filesystem should be laid out. If the distro has any peculiarities or quirks to how it uses the filesystem tree, its usually related to the compilation destination of packages.

    Sample topics:
    • What type of packaging standard does the system use? How easy is it for a user to create their own packages? (Some users like to assemble their own software and use the package manager to mange their installation. See point on compiling from source below.)
    • Is package downgrading supported?
    • How quickly are packages updated when their official upstream versions are updated? (Don’t be to picky here: Are we talking about weeks or months?)
    • Continuing from the Philosophy point and the above sample topic, does the distro lean towards being bleeding edge or being stable? (This has been mentioned twice. Hint.)
    • Do the developers do extensive modification of the original packages (security patches, extra functionality), or are they provided vanilla as-is? (For example, Debian developers tend to modify packages as they see fit, Arch Linux developers only apply very common patches occasionally.)
    • How are the packages compiled by default? (For example, with or without debug information?)
    • How is Gnome/KDE split up? How many packages compose a full Gnome/KDE suit? (For example: Is Kolour Paint an individual package, or only available as part of the larger KDE Graphics package?)
    • Are there any filesystem layout quirks, additions, or reservations? (For example, is /usr/local ever used by packages or is it reserved for the user? Is Firefox installed into /var?)
  • Support for compiling from source
    The package manager’s job is (usually) only to manage pre-compiled packages. But some users like to manually compile some packages from source, such as to apply custom patches to a program or to get speed by optimizing the program for their specific machine. Many users don’t compile much (if any) from source, but the Linux philosophy is deeply rooted in the distribution and manual compilation of source code, and there are many who like/need to do so. How an operating system lets the user compile/managed compiled programs is important to how the operating system works. Those who rely on it will find their experience very dependent on how manual compilation is handled.

    If there exist any distro-specific methods for handling the compilation of both supported (packages in the repositories) and/or un-supported (packages not in the repositories) software, it should definitely be included in a review. If the distro has any form of a ports-like system, a review without mention of it is by default incomplete.

    And do not ever, ever waste space explaining that you can do “./configure && make && make install”, that you can use “checkinstall”, or that you can use the “install” program itself — every distro has those, they aren’t worth mentioning in the slightest.

    Sample topics:
    • Do there exist any specific tools for the system that aid the user in compiling programs from source?
    • How are users supposed to recompile the kernel? Is initramfs or initrd used?
    • If a user does manually compile a program/package, how easily can it be managed by the package manager? (This has been mentioned twice. Hint.)
    • How is the presence of different kernel versions handled?
    • Is there risk of having the manually-compiled program conflict with the packages managed by the package manager, or is there a way to keep manually installed non-package programs separate?
  • Release system
    Distros have different styles of updating the end-users installed distro to be the most current version. Some distros have a new, fully-updated version released every 6 months. Some just release all package upgrades on-the-fly and have no concept of different versions. The way the distro handles version releases is significant to the end-user, as usually full version upgrades mean that the developers reserve the right to move stuff around and/or reconfigure things in a noticeable way if they want to, and push those changes through in the next major release. It also means that developers reserve the right to stop providing package upgrades for a given version, resulting in obligatory periodic upgrades.

    Sample topics:
    • What factors decide the version releases (if there are any)?
    • How big are the changes between releases?
    • How often are the releases?
    • How long is there support for old releases?
    • Does evidence seem to suggest that performing a version upgrade is smooth, or is the user better off performing a clean install of the new version?
  • Startup style
    Summarizing how a distro manages startup scripts/daemons is easy: All you have to do is say whether the distro uses System V or BSD-style init scripts. Users unfamiliar with these concepts can look them up.

    How the operating system uses run-levels is a more complex subject, yet a more interesting on. Fewer users will care about this level of detail but more advanced users might be able to intuit more about the nature of a distro from it.
  • Robustness of a default install
    Distros vary in what software they provide for a from-disk installation. Some have more, some have less. Some have roughly equal quantities but the theme of the offered software is completely different.

    After you install the distro, how much work must be done to get the system up and running with a graphical desktop and a decent collection of tools? What kind of packages are installed, and what aren’t?

    Sample topics:
    • Is a default display manager installed or offered? (Which one?)
    • Does the distro rely heavily on sources from the servers, or can you obtain multiple CD/DVDs for a more robust from-disk install?
    • Does the default install include tools for compiling? (GCC, make, etc.)
    • Does the default install offer Apache for install?
    • What are some of the most specific/obscure programs install/offered by the installer? (For example, if a distro provides Compiz and OpenOffice.org straight from disk, that implies the sort of other packages that are installed.)
The above topics cover a lot of ground. Obviously not every detail need be included in a good review, but many of these points are very critical to how the distro works and failure to address a significant number of them will result in an incomplete review of the distro. If there seem to be too many points to address, remember that you’re writing a technical review, not a grand work of fiction. Wordiness can usually be eliminated. If you know what you’re talking about and put some thought into what you write, you can cram a lot of information into three sentences.

One key to remember is that that not all of the information may seem important to you, the author of the review, but it is what separates one distribution from another. Obviously the information has to be appropriate for the audience you are writing for; that is a decision faced by every technical writer.

If you feel unable to address many of these topics in your review then you probably have no business reviewing the distro and are not as familiar with it as you should be. Many people want to pop in a CD, install the distro, play with it for 40 minutes, and then write a review about it. Unless you did your research beforehand and you made very good use of those 40 minutes, you’re not qualified to offer a review. Spend your time learning more about the distro rather than writing about what you do know.

Now a list of things you should not review.
  • Plug-n-play drivers
    Do not ever review a distro by saying “I plugged my external wireless card X and it did(n’t) work”. This is the lamest review you can provide, and is my pet peeve to boot. First of all, and apparently this will come as a shock to some, almost all distros use the same drivers. Support for hardware is pretty much universal, the same drivers that manage your hardware in one distro probably manage it in most other distros, and this only becomes more true over time. Comparing hardware support between distros is basically pointless. It’s even more pointless when your analysis consists of just one generic external wireless card. If it didn’t work, odds are you didn’t set something up correctly.

    Second, the comparison you can make between distros is in how they manage drivers. Some distros have special programs to help the user manage and install drivers. Some distros have lots of automatic scripts set up to help ensure the user never has to manually touch their xorg.conf file, some distros demand the user get involved with the xorg.conf file.

    Driver management is a valid comparison point, but generic “I tried wireless device X and PCI device Y” tests are basically worthless. “Here’s how easy/hard it is to install Nvidia’s video driver (module version or userland version, take your pick), here’s a short summary of what is expected of you to do so, and here’s what was done automatically by tools”, by contrast, is very informative information.

    Note that it is obviously acceptable to review the quantity of drivers provided by a distro if they seem to have a noticeable shortage/abundance of them, but most distros will have about the same drivers. Don’t mention driver quantity unless its very noticeable.
  • Five minute quirks
    At various times, some distros have what you might call “five minute quirks”, namely, one or two little problems that often need to be ironed out of a fresh install of the system and are easily solvable by a user with Linux skills that the distro is oriented towards. Sometimes an environment variable needs to be set, sometimes a file needs to be configured, etc. These are bugs not unique to anyone’s specific install of the distro, but rather a very large (if not the entire) user base. One of the developers mis-configured something before release, or some default setting doesn’t work with the majority of hardware, or something like that.

    Do not write about these little five minute hiccups in your review. They do not count, they only last five minutes and will likely be fixed in one of the upcoming releases anyway. (See the next point.) Usually the distro’s forum and/or wiki has an easily accessible guide to tell you how to fix the quirks and after a day of usage, the user will not remember it. At absolute most you should say that “minor quirks exist” and say where/how the site addresses these issues. This could be part of your review of the distro’s documentation. Any quirks you fix within five minutes of attempting to do so should not be mentioned. Their fix in the next release will out-date your review.

    What’s more, do not write about the stability of a distro based on its five-minute hiccups. Nothing says “I didn’t do any actual research about this distro” like a stability evaluation based on the initial five-minute quirks the distro had as of some arbitrary date.
  • Unrelated/temporary bugs
    Do not write about temporary bugs. If the bug is the type that will be fixed within four months, don’t use it as basis for your evaluation of the distro’s stability. This point bears repeating: Whatever you do, do not base your assessment of a distro’s stability on little quirks that will be gone in a couple months. If your readers wanted to read an inane bug listing, they’d browse bugzilla.org.

    On that note, do not assess the distro, in any way, based on bugs that are not specific to the distro itself. If the developers of a software package X make a mistake, don’t blame the developers of the Linux distro in question, it’s outside of their control, not their fault, and not their responsibility. It’s irrelevant to your review, so ignore it. If distro X has a bug but distro Y does not, it is possibly that distro Y did not push the new version of the software and thus does not have the buggy version — you can use this to exemplify how “bleeding edge” the distro is. Or its possible that distro Y manually patched the software — you can use this to exemplify how the developers do(n’t) manually patch packages.

    You can obviously cite the presence of bugs in your analysis of the stability operating system, but don’t focus on petty bugs. Instead, focus on the release/testing cycle of packages, the speed of security fixes, and frequency of distro-specific bugs. If this means that you actually have to spend some time using a distro and learning about it before you evaluate its stability, cry me a river. If you aren’t willing to do that, don’t comment on it’s stability because you don’t know anything useful about it.
  • Artwork
    No one cares what the default desktop color theme of the distro is. Or the default desktop wallpaper. Or whatever. This is my other distro-review pet peeve. As shocking as this may sound, every desktop environment and window manager in the entire universe, throughout every civilization, all of time, and every dimension, can have its color theme changed. If a user doesn’t like the default wallpaper, they will change it. If they don’t like the default Gnome color theme, they will change it. Defaults are irrelevant.

    Don’t mention the quantity of community artwork, in the sense of backgrounds and color themes. This is directly proportional to the number of users the distro has and is thus redundant information. And, realistically, nobody cares about it, because most of them will choose whatever distro-neutral artwork they prefer anyway. Users routinely become attached to a certain color theme and will take it with them from distro to distro.
  • Installation Process
    This is not a terribly important point, but I’m not a fan of reviewing the installation process of a distro. Most installers, even text-based ones, guide the user through the installation very clearly. Sure a text interface may look a bit daunting to some, but if one just reads the instructions, one can usually just click-through (or, tab-enter-through) the installation with relative ease.

    This item might warrant a quick mention, perhaps tying into the distro’s philosophy (ie, in analyzing whether the distro is oriented towards casual or power users), but unless the installation process is exceptionally complicated or buggy don’t devote much space to it. It’s a one-time experience by the user, and a determined user won’t change their opinion on whether to install it based on the installation graphics.
Remember, your goal, as a reviewer, is simple: Review things from the perspective of the average user you are writing for. Don’t go into pain-staking detail unless you’re aiming to provide an in-depth guide, minor details/quirks are often best left for their own special article and are of interest to few readers. Don’t waste time on things that were (likely) very unique to your experience, because almost no one else cares.

Even though this article was somewhat long, your distro review doesn’t have to be. (If it is very long, it’s probably more of a guide than a review. Keep manuals as manuals, and reviews as reviews.) If you have an actual depth of information to convey, you can say a lot by using well-crafted sentences.

Simple Elegance – Openbox Theme
• By Brad Conte, July 9, 2008
• Post Categories: My Projects
I’ve designed a theme for the Openbox window manager based on the principle of simplicity and clarity.

I designed the theme because, shortly after my transition to Openbox, I was unable to find a dark theme that was (very) simple, had corners, and didn’t change the colors between active and inactive windows drastically. So I set out to design my own. I originally started by modifying the standard “Syscrash” theme included by default in Openbox, but over time it became unrecognizable and I’ve seen fit to publish it. My theme still uses the four icons from Syscrash, however, because I’m no graphics artist.

I call my theme “simple” because it uses only three colors and has corners. I call it “elegant” because it blends the colors in simple, consistent, and distinct ways. It’s easy on the eyes, but it’s smooth and not boring. Simple, yet elegant.

There are two variations of the theme, differentiated by their primary color. Both have a gray secondary color with blue accenting. Both are hosted at box-look.org.

The black version can be found here.
The dark gray version can be found here.


The Practicality of Port Knocking
• By Brad Conte, May 29, 2008
• Post Categories: Security
Port knocking is one of those server security topics that seems to come up every now and then, and when it does it always sparks a bit of debate over matters of practicality.

The idea behind port knocking is simple: The administrator of a server sets up a server with an Internet-accessible service. The administrator then closes all the ports on the server, including the ports that the service uses, and starts a daemon that monitors all incoming packets to the server. The daemon then opens the port corresponding to the service when and only when the daemon receives a series of packets on a specific set of ports in the correct order. The packets can be any type — TCP SYNs, TCP ACKs, UDPs, whatever — but they must be sent to the server on the correct ports and in the correct order to cause the daemon to open a service’s port. Thus a port remains closed until someone “knocks” on the correct ports to cause the daemon to temporarily open it.

(Example: If the required sequence is TCP ACK packets on ports 333, 4444, and 55555, then the sequence of ACKs “27, 333, 4444, 55555, 42″ would open the port, whereas the sequence “333, 27, 4444, 55555, 42″ would not. I would tend to use TCP ACK packages, because they look the most boring to someone sniffing a network — more below.)

Thus port knocking adds the security equivalent of another “password” to a service, because a client has to successfully knock on a server’s ports in the correct order in order to open a port for business. Given 2^16 possible ports, about 4 possible protocols, and (usually) about 4 necessary correct port guesses, standard port knocking comes out to the equivalent of a ((2^16 * 4) ^ 4) = 2^72 bit key. This isn’t too shabby a number, in terms of key size, especially if port knocking is just an extra layer of security for a service.

Thus begins the debate on the security practicality of using port knocking.

The main advantage of port knocking is that it conceals the very existence of a service until the port knock sequence is complete. An attacker cannot attack a service he cannot find, and until he finds out how to properly knock, every port on the host will appear closed to him. Thus port knocking is very helpful in situations where a server administrator wishes to conceal the very existence of a service. Service concealment was the primary motivation behind the development of port knocking.

Another advantage of port knocking is that it allows a port, when it is opened, to only be open for connection from a specific IP address. The port knocking daemon monitors all incoming packets and when it detects the correct “knock” it can not only open up a port but can open a port that accepts packets from the knocking IP only. Thus a WAN-side service can be told to accept connections only from certain IPs, but those IPs can be decided in real time.

Unfortunately, however, port knocking is a very fragile security policy. Since the knocking packets must always be sent in the clear it has the equivalent security of a password sent in cleartext. Anyone sniffing your network on either the client or server (or anyone who can trick the client into sending the knock sequence to a spoofed server, ie via DNS poisoning) end can tell what “knock” is used and replay the packets, effectively negating the security of port knocking. The good news is that unless an attacker is actively looking for a port knock sequence, the knock will look like normal boring network traffic. But if a sniffer is on the lookout for a knock sequence — especially if they know which server it is destined to — it’s impossible to slip the knock past him.

Also, because port knocking requires the equivalent of a symmetric key problem, port knocking does not scale well to services that must handle many individual connections. The pork knocking “key” must be distributed securely to everyone who needs access to the server’s service. Any cryptographer and/or security auditor will tell you that the symmetric key distribution infrastructure for this sort of thing is both annoying and brittle — the larger the infrastructure to be maintained, the larger the hassle and the larger the potential for single point failure.

Obviously, scalability does not matter to the individual wishing to SSH into his home computer, but it is of major concern to anyone operating a server with more than four or five users, especially if users must be added, revoked, and have their “knocking keys” rotated. This is a classic (annoying) symmetric key distribution problem.

Port knocking is also impractical for popular/busy servers because the popularity of a server contradicts the very goal of port knocking: to conceal the very existence of a service on a server. If an attacker is aware of the nature of his target and knows (or at least has an idea of) what services the server has, he will not be satisfied if his port scan turns up empty. If he expects certain services to exist on the server, and if he is in any way persistent, he will investigate the server until he finds the services he knows exist, thus he will investigate the potential use of port knocking sooner or later. This does not result in instantaneous defeat of course, but the port knock is only a secure as a password sent in cleartext, which is a bad security measure to have to fall back on. The exact situation will dictate how easy the knock will be to sniff.

This quick assessment should make it obvious that the only practical use for port knocking is on small servers. Realistically, the service itself should be secure enough in both configuration and implementation to not require the additional security of port knocking — it is an Internet service, after all — but port knocking does add yet another level of plausible security, and the paranoid never underestimate defense in depth.

All things considered, port knocking is not too useful, despite being a fun idea. The only place I’ve actually observed it in use was by people at DefCon looking for any way to add any level of security to their home computers. But, obviously, those are the “I will because I can” types. Plus, when you’re at DefCon you use anything to secure your home server that you can get. But outside of the experimental world, port knocking is only an interesting notion, it never sees wide-scale usage for a reason.

Note that Port knocking is not the same thing as Single Packet Authentication. Port knocking was the initial attempt to gain security by service invisibility. SPA is the more secure successor to port knocking, developed to address key problems in port knocking.

PCManFM Patch – Confirm Delete
• By Brad Conte, May 17, 2008
• Post Categories: My Projects
Update 6-30-08 (PCManFM v4.5):
As of v4.5, PCManFM started to add an integrated feature to disable delete confirmation, fullfilling the goal of this patch. (The upcoming official feature appears to disable confirmation when a trash can is used.) This new feature does not yet fully work but the code is similar to the patch. Since the author has not seen fit to activate the feature and is clearly working on it, I do no anticipate releasing patches to work with any version beyond v4.3.

About
The patched preferences menu This patch adds the option to enable/disable delete confirmation in PCManFM, a popular, light-weight, tabbed file browser. Default behavior in PCManFM is to always prompt the user for confirmation when deleting a file (the classic “Are you sure?” prompt), a feature some find inconvenient. This patch adds an option to the Preferences menu that allows the user to select whether or not they wish to be prompted on deletion.

To the right is what the Preferences menu looks like after the patch. (The dark colors are due to my GTK theme, they have nothing to do with the patch.)


Download
Patch version: v2 (June 26, 2008)
Last tested against: PCManFM v0.4.3
Download

Applying the Patch
Applying the patch is simple. First download and extract the PCManFM code. Then apply the patch to the source. Either:

…from the parent directory with:
$ ls pcman-0.4.1.1 confirm_delete.patch $ patch -p0 < confirm_delete.patch
…or from the actual source directory with
$ ls AUTHORS config.guess libtool COPYING config.h ltmain.sh ChangeLog config.h.in missing INSTALL config.log mkinstalldirs Makefile config.status pcmanfm.desktop Makefile.am config.sub pcmanfm.desktop.in Makefile.in configure pcmanfm.png NEWS configure.in please_read_README_carefully_before_packaging README confirm_delete.patch po TODO data src aclocal.m4 depcomp stamp-h1 autogen.sh install-sh $ patch -p1 < confirm_delete.patch
You can then compile PCManFM with the standard:
$ ./configure $ make $ make install

Technical Notes
Patching was pretty minimal, save for one file: pcmanfm-{$version}/data/ui/prefdlg.glade . In the original source, practically the entire XML UI design file is devoid of whitespace, including newlines (for optimization), which makes a nimble patch for it impossible, thus this entire file must be redistributed. This file holds the entire visual layout for the Preferences menu, thus the patched prefdlg.glade file will have to be updated whenever the official PCManFM package updates the Preferences menu layout (something unlikely to happen).

Aside from that issue, since the editing was very simple and inline with the basic structure of the program itself, I see no reason why it shouldn’t work for on many PCManFM releases to come. (If things change, I’ll update the patch, though.)

Automatic Installation
Some OSs lend themselves to compiling from source very easily. If you use such an OS (Arch Linux, Gentoo, FreeBSD, etc) you may wish to write a script to apply the patch and rebuild the package. For Arch Linux, move the patch to your /var/abs/local/pcmanfm directory and add the patch to the PKGBUILD via:
$ cd /var/abs/local/pcmanfm $ sed -i “s_cd\ \$startdir/src/pcmanfm-\$pkgver_cd\ \$startdir/src/pcmanfm\ -\$pkgver\npatch\ -p1<../../confirm\_delete.patch_g" PKGBUILD
I’m unfamiliar with Gentoo’s ebuild format, but I’m sure that modifying an ebuild would be similar.

My Sweatshirt
• By Brad Conte, February 26, 2008
• Post Categories: Miscellaneous
In just four days of wearing my new favorite sweatshirt on campus for the first time I got four separate complements on it. Three people asked me where they could buy it. Since then I’ve received dozens of compliments, mostly from strangers who, although they don’t know me, know an elegant math expression when they see it.

Unfortunately, this sweatshirt is not explicitly for sale anywhere. I had it custom made because I couldn’t find anything like it.

My Euler's Identity Sweatshirt


Summary, for those interested in getting a similar one
I love my sweatshirt, I’d sell it on a store like CafePress if I could find one that has black sweatshirts. Since I can’t, the next best thing is to provide the instructions to get one.

The image: You can get the image I used for the screen-printing here. However, the company I used for the screen-printing required you to upload an inverted version of the image (at least as of the last time I used their services), which you can download here. If one doesn’t work try the other.

The company: The company I used to screen-print the image is Blue Cotton. I chose the Hanes Pullover sweatshirt (Printing -> Sweats -> Hooded Sweatshirt -> F170 Hanes Pullover Hood), but they do offer other sweatshirts. The Hanes sweatshirt has the advantage of having the lowest polyester content (90% cotton) of any of their sweatshirts, which is a good thing for a screen print and has the side benefit of being very comfortable.

The image sizing: For my sweatshirt, an extra-large, I chose to make the image 9.5 inches wide (be sure you lock the width/height ratio when scaling the image on the sweatshirt) and centered it 2 inches below the collar (you’ll have to eyeball this measurement). It took a long time for me to decide on those dimensions, but I finally did and I think they’re perfect, which is saying something. You might want to scale the width for sweatshirts of different sizes, my rough guess would be to subtract/add .75 to 1 inches per size smaller/larger.

So all you have to do is go to the website, select your sweatshirt, upload the image, set the width/placement, and order it.

The background of the sweatshirt
I’m a math major, and I like elegance. Euler’s Identity is my favorite mathematical expression: it’s a simple expression of universal truth via constants. It’s fascinating how the five most fundamental constants of math are all uniteable in a single, simple expression.

In addition to math, I like t-shirts. I tend to treat t-shirts as billboards for things that I like — you won’t find a blank shirt in my drawer. As need had it, in winter of ‘07/’08 I found myself in need of a new sweatshirt. Like the rest of my upper-body apparel, I wanted it to say something interesting. I wanted the sweatshirt to be “nice-ish” so that I could wear it to “nice-ish” events, so I didn’t want a busy/complicated design. it had to be simple, yet elegant. Settling on a simple expression of Euler’s Identity was easy. My second stipulation was that the sweatshirt had to be black.

I started my search at the obvious place for a weird request like that: CafePress. I found a couple of sweatshirts with Euler’s Identity, but a) They had obnoxious brand logos, and b) Cafepress doesn’t sell black sweatshirts. After an extensive search of the Internet, it became obvious that no one offered anything like what I was looking for (shocking, considering the obvious demand). So I decided to have the shirt custom screen-printed.

The design of the sweatshirt
Thus I was faced with two tasks. The first task was creating the image I wanted to be screened onto the sweatshirt. The second task was finding someone to screen-print the image. Neither task turned out to be as simple as it might seem.

Creating the image was difficult because the only decoration for the black sweatshirt was going to be the bold, white text of Euler’s Identity. Thus the styling of the text was very important. In order to truly do the equation justice, and make the sweatshirt look as simply elegant as possible, the font had to be perfect. Not fancy, but not boring. Just slightly elegant.

Getting the image screen-printed turned out to be difficult because there were two major conditions for the screen-printing: I had to be able to have a transparent background, and I was not going to order in bulk. Most custom screening companies violated the former of these two requirements, and the few that allowed background colors required bulk orders. In addition, some companies didn’t offer sweatshirts in black.

The final solution
Finally, however, a solution was reached. I designed the image using the “i” and “pi” symbols generated by a Linux-based LaTeX front-end called eqe. I generated the rest of the equation using characters from the Tahoma font in the Linux-based image editor KolourPaint. I needed a very large size image to achieve a sufficient DPI, which was recommended to be at least 90. Both programs allowed me to create the images at a large size with excellent quality, but not a size quite large enough. So I used Gimp to expand the size and I used its anti-aliasing feature to keep the font’s smooth despite being enlarged. The result is shown here. (This is a scaled-down version of the image, for bandwidth reasons. Click the image to download the full-size image, the one you would use for actual screen-printing.)

Euler's Identity
View the inverted version.


I also found a company, called Blue Cotton that allows one to screen-print an image, choose a color to make transparent, and doesn’t require a bulk order. (Choose Printing -> Sweats -> Hooded Sweatshirt -> F170 Hanes Pullover Hood.) Thrilled to have a working image and a working company, all I had to do was manually place the image on the sweatshirt. I spent (no joke) probably 3 hours total moving the image around on the shirt, higher, lower, bigger, smaller, trying to get it just the right size and at just the right height. Finally I decided on a 9.5 inch width at 2 inches below the collar, which I am pleased to say is the perfect size/placement (for an XL).

Close-up picture of the screen-printed text on the sweatshirt.


Also, kudos go out to my girlfriend for her extreme patience with me. The sweatshirt was a Christmas present from her to me. Being a nit-picky perfectionist, it was decided that I had actually best do the bulk of the designing. I didn’t even finish the design until the end of January. Giving it to me was an excellent idea, and it’s one of my all-time favorite articles of clothing.

Newer Posts »