Follow Slashdot blog updates by subscribing to our blog RSS feed

 



Forgot your password?
typodupeerror
×
Security

Journal Journal: Fallacies & Falsities of Security

"Securing systems or programs is basically about closing the holes and weaknesses that let hackers in." Rather, security is about correctly modeling in software and hardware the trust relationships that people have regarding their computing resources and data. It is about making computer systems behave in the way that their operators want and trust them to behave, with respect to such things as authorized use and availability. It isn't about patches; it's about correctness.

"A firewall is essential to keeping a network secure by rejecting attacks." A firewall is nothing more or less than a network bridge or router that selectively drops packets. It does not "block attacks" or "forbid unauthorized access" -- it drops packets. Sometimes this is a useful thing to do on a network segment in order to provide assurance as to what sorts of activity won't come in over that segment. This can be useful in modeling trust: if you block port 23 with a firewall, you can guarantee that nobody outside can send port-23 packets through that segment. That's not the same as saying that nobody outside can do unencrypted login to any machine inside ...

"If a program crashes, that only means it's unreliable, not that it's insecure." In fact, many forms of attack against programs are first discovered as ways to make the program crash with a piece of malformed input. If your FTP server dumps core when I send it an excessively long username, that's probably because it's overflowing a buffer. Breaking in is just a matter of overflowing that same buffer with the right data.

"All software has bugs, and bugs lead to holes -- so from a security perspective it doesn't really matter what software I use, since I'll need to patch it anyway." The fact of the matter is that some software projects release programs that are consistently more reliable than others. Some projects release software that is easier to patch than others. Some projects release software that is better documented, and its behavior better understood, so that you can more set it up with more accurate trust relationships. In short, some software is more correct than other software, and you can reduce the amount of time you spend fixing broken software by choosing software that is less broken. Anyone who tells you that all software is buggy is a cynic; anyone who tells you that all software is equally buggy is trying to sell you IIS.

Security

Journal Journal: Firewallin'

My workplace -- an internationally reputed research institution with about 1500 employees and 2500 Internet-connected computers (and a /16 network prefix) -- now has a firewall. Finally.

Oh, we had a firewall of sorts before. What we had was a default-allow packet filter, which we populated manually with rules blocking access from addresses which had portscanned us, and to machines we had discovered were insecure. See, a few years back, the head sysadmin at the time had asked to install a firewall -- but some of the scientists were concerned that such a thing would get in the way of innovative uses of the network. But he managed to get not a firewall, but a "filter" -- an early Netscreen firewall appliance configured in this default-allow mode.

Maintaining this system was very labor-intensive. Our intrusion detection system (IDS) was based on Snort and email -- meaning that every ten minutes, it would email us a chunk of logs. When we could, we'd keep the live logs in an xterm in the corner of the screen -- and put in firewall blocks against any remote node that portscanned, probed, or tried to Nimda us. Besides being a lot of work, this was also error-prone: we often found that we had accidentally blocked some legitimate traffic, since an automated set of FTP jobs can look a lot like a scan or a DoS.

And so it went for a few years. Then, last year, my boss (who is remarkably un-PHB-like for a guy who likes Windows XP) convinced the scientists' IT oversight group that we needed a real, default-deny firewall. The project was dumped in my lap as medium-range: not so time-critical that I should quit doing Linux systems support to implement it, but also in need of long-range planning and consensus gathering before we went forward with it. (He's trying to turn me into a manager. Really, he is.)

(I should note: Our IT department is very slow moving. We are not the sort of department that can push out a complete transformation of institutional computer use in a day -- or even a week. We like to think we are conscientious, methodical, and modestly refrain from shoving technologies on an unprepared user base, but the fact of the matter is that we are slow. The week I started working here, two and a half years ago, we started talking about replacing the aging and unreliable mail servers. We started building the new mail system a year later, and finished migrating users to it a year after that.)

Before we could put up a default-deny firewall, we had to establish clearly what services needed to be allowed through it. In our institution, anyone on staff can request an IP address and add a new computer to the network -- with whatever OS and services they want to run. It's not our job to tell them no -- it's our job to make their stuff work the way they want it. So I needed to extend this philosophy to the realm of firewall access rules. The result was a database-driven Web application which let people request firewall openings, and let us approve their requests and translate them into firewall rules understandable by our spiffy new Netscreen-500 firewall.

We gave our users a month to register their existing services. On this past Monday night, the network administrator and I switched our Internet link over to filter through the new firewall.

It's actually gone rather well. We had a few glitches -- our dial-up server is outside the firewall, but the RADIUS server it authenticates against is inside; we'd forgotten to give it a pass rule, and didn't notice until the next morning when we got the user complaints. A few people failed to register their services, or didn't realize that accepting raw X11 sessions from Norway involves allowing certain ports through the firewall.

And now I and the other network security team members find ourselves in a very different job. Instead of watching IDS logs like hawks, and scrambling to block the latest source of attacks, we're now building up information about what our previously inscrutable user base actually wants to expose on the network. With the new firewall, we now know for certain that no incoming SYN is going to a system whose operator doesn't want an incoming SYN. We have a valid list of exposed services, so we can run vulnerability scanners like Nessus with impunity.

And the worst complaint from the users? One paranoid is griping that we don't block pings.

GNU is Not Unix

Journal Journal: Words to Grow On Part III: Electric Boogaloo

bound variable n. A person who sometimes enjoys being tied up, and sometimes doesn't.

free radical n. 1. A GNU partisan. 2. An anti-war protestor not yet noticed by the Office of Homeland Security.

gnaked adj. The state of a commercial Unix system prior to the installation of useful pieces of free software.

peace officer n. A person employed to commit violence against peace activists.

pr0t n. A listening TCP socket harboring an insecure or buggy network service; the target of a pr0tscan.

processed imitation relational database flavored product n. mySQL or Microsoft Access, e.g.

realloc n. A piece of security infrastructure that actually works. Opposite of a fakeloc.

Satan's-ass pattern n. A commonly used design pattern in object-oriented programming, in which a class represents a hodge-podge of functionality and data storage uglier than Satan's ass.

shoujo-nai n. Of anime, contaning no lesbian content.

Zen erotica n. The sound of one hand diddling.

GNU is Not Unix

Journal Journal: The part of the GPL that flamers didn't read

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

That's from section 0 of the GPL. Every person who has ever written that "the GPL restricts the use of GPLed software," or that the GPL is comparable to an end-user license agreement (EULA), thereby evidences having not read, or not understood, the GPL.

(This is not a defense of the GPL against critics who favor the BSD-style licenses on grounds that they are "more free" than the GPL. That is another argument for another time. It is specifically a defense of the GPL against those who consider it morally or legally equivalent to a Microsoft-style EULA.)

License to Use, with Copying Forbidden vs. License to Copy, with Usage Unrestricted

Take another look: "The act of running the Program is not restricted." For nonprogrammers, this is the chief practical distinction between the GPL and an EULA. An EULA asserts control over whether and how you may run the covered software, whereas the GPL explicitly denies such control. An EULA asserts that the copyright owner may revoke your right to use software you've legally obtained, whereas the GPL recognizes that copyright only affords the owner the right to control your copying of the software.

If you are a programmer or distributor, of course, the distinctions between the GPL and an EULA are much more distinct. EULAs such as Microsoft's don't just exercise copyright, i.e. forbid you from making copies. They typically order you to refrain from analyzing or learning about the covered software -- for instance, disassembling or tracing it -- even though these are user rights that copyright does not restrict. That is to say, EULAs claim to leverage copyright to gain control over actions which copyright doesn't itself cover. In contrast, the GPL permits you to do things which copyright normally disallows, viz. making copies and derivative works, albeit only under certain terms.

Terminable Subscriptions vs. Interminable Permission

As proprietary-software houses move increasingly towards subscription-based software licensure, we may see a new distinction for end users. Subscription software relies on the idea that I can sell you a piece of software with a time limit on your right to use it. Thus, the software may become unavailable for your use for any of several reasons, even though you have a copy in your possession. Since GPL provides no restrictions upon use of software -- only upon copying -- none of these can apply to its covered software:

  • Publisher withdraws software from licensure to promote another, more profitable product;
  • Publisher is forced to withdraw software due to lawsuit or regulation;
  • Publisher tactically withdraws software from your particular market in order to harm a specific competitor;
  • Publisher issues license renewals only under restrictive terms which exclude your uses -- for instance, by forbidding use in ways which compete with publisher in new markets;
  • Publisher goes out of business, and thereby becomes unable to issue license renewals.

It is fully possible that the author of a piece of GPLed software could be restricted from distributing it by a lawsuit or regulation. It is not nearly so likely that such restriction would deprive existing users of the right to use the software. Even the authoritarian DMCA does not forbid one from using a piece of infringing software -- only from distributing it.

Naturally, many programs both proprietary and free are used to store data in particular formats. Word processors and databases come to mind. Under subscription licensing, users end up paying for the privilege of accessing their own creations.

Innovating Freedom vs. Innovating New Kinds of Unfreedom

Aside from subscription-based licensure, EULA-covered software has of recent come to stand for the innovation of whole new categories of unfreedom. As time goes on, we may reasonably expect that this trend will continue.

For instance, a copy of proprietary software may by default be transferred, like any other piece of property: if you purchase one copy of a proprietary program, you may install it on your computer or give it to your mother to install on hers, but not both. If you want to give it to your mother, you have to erase it from your own system first. Older proprietary copyright notices were particularly fond of the phrase "This software is like a book," meaning that one purchased copy could only be used in one instance at a time. EULA-covered software, however, has come up with new restrictions to forbid this and other acts to which software users are accustomed.

It is the avowed purpose of the GPL to innovate a new category of freedom: a software commons to which all may contribute, but from which nobody may restrict others, with enforcement provided solely by the terms of copyright law. It is the self-evident purpose of EULAs to innovate new categories of restriction: to go beyond the statutory restrictions of copyright, engineering whatever restrictions upon users may be maximally profitable.

One may fairly argue that the GPL does not provide for maximal freedom for programmers, as do the BSD critics mentioned above. However, this is a far and faint cry from the parroted claim that the GPL is morally, legally, or indeed practically equivalent to an EULA.

Apache

Journal Journal: Developing a Web app with mod_python and PostgreSQL

Over the past few months I have been developing a Web interface to allow host operators at my workplace to request the opening of ports on the firewall. Requests are stored in a relational database; authorized personnel can mark them approved, or download new firewall configuration files based on the approved requests.

It's not really that complex of a project, but I am very glad that I chose the tools that I did to create it: specifically, the Apache Web server, the Python language, and the PostgreSQL database backend. All three have proven exceedingly pleasant and flexible to work with, and showcase one of the practical strengths of open-source software: these products from different organizations and with widely divergent data models and philosophies integrate seamlessly to allow me to get my work done.

Apache and mod_python

Apache provides a powerful yet fast Web front-end, and supports authentication against my workplace LDAP directory, meaning that my own code does not have to think about authentication at all -- all I do is read a username from the Apache request object. The mod_python interpreter (an Apache module that embeds Python into Apache, with dramatically lower overhead and better integration than CGI offers) seamlessly interfaces my Python application logic to the Apache front-end.

Python itself is fun to work with, flexible, and exceptionally easy to debug. There are three different modules for connecting Python to my database backend, each optimized for a different sort of task. All conform to the same API, though, so I can switch from one to another with minimal code changes. The fact that Python (unlike Perl or PHP) hosts an interactive interpreter allows me to test chunks of my code quickly -- and Python's accurate and informative error messages make my own foul-ups easy to find and quick to fix.

I will admit that Python is not the fastest interpreter around. Speed isn't one of my chief requirements, though, and the tradeoff between programmer time and CPU time becomes easier to make on fast systems. (Terrible, I know.) If I were to set out aggressively optimizing this system now, the first thing I would do would be to push various bits of processing into PL/pgSQL rather than Python, so as to cut down on the amount of time spent converting data formats. (I must admit, though, I haven't profiled it.)

Though I come from a Perl background, and though processing of entered text was a major part of this project, I never missed Perl's regular-expression processing in writing my Python application code. I didn't even use Python's regex capabilities: I found myself designing data formats (mostly in dynamic HTML forms) which would require minimal parsing easily accomplished with basic string operations.

PostgreSQL

I don't have a great deal of background in the world of relational databases, but I knew that I needed a stronger database back-end than Berkeley DB or GNU DBM for this task. Specifically, I needed to ensure that no front-end application session could violate specific data integrity rules for the stored host information, and that erroneous sessions could be rolled back cleanly.

These requirements led me to SQL databases, and soon to PostgreSQL. I'd heard of its more popular counterpart mySQL, of course -- but what I'd heard was from database experts pointing out its wrong behavior, limitations, and its advocates' lies and misstatements with respect to its capabilities. I also knew of several Web sites, such as E2, which in the past had serious database corruption problems with mySQL. These put a bad taste in my mouth regarding the more popular system, and I turned to its less well-known, but evidently more professionally designed, competitor.

PostgreSQL was as pleasant to work with as the other tools I've mentioned. I installed it on a Debian GNU/Linux system, which did the install with no problems. (I'd thought about building it from source, but decided against it on maintainability grounds -- I like to assume that I'm not going to be the last person to work on my project, and so I want to ensure that it is as uncomplicated to upgrade or otherwise maintain as is practical.)

I got some help from a database specialist in defining my tables and data integrity rules. By ensuring in the DBMS that no data could be entered that would violate these rules, I cut out what could have been a major source of ongoing bugs in my application code -- and of user errors. Twice during testing, data integrity exceptions alerted me to errors in my code or logic -- if I'd failed to define foreign key constraints (or used a DBMS that didn't implement them), those errors might have gone into production and allowed malformed data entry. I don't write very buggy code, but I don't believe anyone who says they don't make errors -- so I have great difficulty believing those who say they don't need data integrity checks in the DBMS.

In conclusion ...

I would strongly recommend that anyone developing database-driven Web applications look into these technologies. For me, they have helped make what looked at the start like a complicated project into something relatively painless. More importantly, their solid performance and reliability has given me the confidence that the application I have written will continue to perform reliably and correctly.

Slashdot.org

Journal Journal: How to Make Yourself Look Stupid

This is not a list of ways to be stupid. It is not about foolish or immature people trolling, flaming mindlessly, or pandering to one another's prejudices. It is a list of ways that moderately informed people frequently make themselves look as if they just stepped off the clue boat with an empty cart. Its format is to present the general form of a kind of stupidity, and to illustrate it with examples from matters both online and offline. And for the first:

Mistake negative experience for bias. This is a great way to look like a Rondroid: when someone disagrees with you, or criticizes something you participate in, presume that they are motivated solely by prejudice. When someone says they've had bad experiences with a product, a company, or a group of people, with which you are affiliated, dismiss what they have to say as "biased."

The term "Rondroid" comes from the name of L. Ron Hubbard, founder of the Church of Scientology. In the late '90s, a group of online Scientologists took to defending their church's criminal practices by accusing its critics (largely ex-members) of "bigotry". (When that failed, the Scientologists started using denial-of-service attacks and barratrous lawsuits.)

When a person has had consistently unpleasant experiences with a piece of software (one you use and admire!) and calls it "buggy" or "historically insecure", you do neither yourself nor the truth any favor to call him prejudiced. He is not -- he is the very opposite: "postjudiced", as it were; having made up his mind on the basis of experience. If you cannot accept the fact of another's experience, then you should examine your own biases.

Underestimate the importance of individual free choice. By doing this, you look like a Soviet planner. You presume that you, in your wisdom, know exactly how many people should produce toilet paper and how many should grow turnips. By sending all your people to produce toilet paper, you doom them to starvation; by sending them all to grow turnips, you doom them to wiping their asses with dried turnip leaves. Only when people are able to choose in the market which of these necessary trades to follow (by following the money -- when one resource is short, its price goes up) can a dynamic balance be achieved. Excessive planning produces cyclical shortages.

Truth be told, like many economic truths this applies outside the formal (money-driven) marketplace as much as within it. For instance, some have criticized the open-source populace for producing multiple programs to fill a niche -- or for failing to sign on en masse to a single favorite project. "If only everyone would quit making random weird stuff and work on Mozilla, since it is more important!" It is a glad fact that the people who whine thus have no power to make it so, for it is out of today's random weird stuff than the next success comes.

Assume that a perfect consensus exists, then criticize its "members" for inconsistency. This is how to look like a creationist. The method of stupidity here is to create a false stereotype of a diverse group -- making it out to be of one mind and belief -- and then to attack it as "hypocritical" for its internal disagreements, or for failing to live up to your stereotype of it. "How can you Slashdot people buy Lord of the Rings DVDs? I thought you all said DVDs were evil!" This particularly asinine form of strawman argument involves attacking person A for disagreeing with person B -- but only because you assumed that they would agree.

Creationists -- those who deny biological evolution for religious reasons -- often point to minor disagreements among biologists as evidence that evolution is "in dispute" or "under fire" within the scientific community. They claim, for instance, that since gradualists (such as Dawkins) and punctuated-equilibrists (such as Gould) cannot agree on the details of evolution, that the whole science must be impossibly flawed. No such thing is the case. Evolutionary biologists do not study whether evolution happens (a settled matter) but rather the particulars of how it happens (a matter still being discovered). To presume that a perfect consensus should exist, then sounding the alarm at "inconsistency", is to attack a straw man.

Security

Journal Journal: Security is like the Tao. 1

You cannot make a stream run quietly by dumping more boulders into it. You cannot make a computer system secure by running more software on it.

The antivirus model, the software firewall model, and to a certain extent the NIDS model, are all built on the precept that running more software can make your system more secure, provided that it is the right software. If only you buy the right product -- install the right virus definitions file -- do the right upgrade, your system will be secure. Meanwhile, systems keep getting cracked and worms keep spreading.

"I eat lots of diet food, but I'm still fat." "I install all these security programs, but I still get cracked."

The insecurity of Windows default installs is not due to their well-known failure to install sufficient security features. It is due to their quiet installation of an excess of insecure features.

If you are in a position to need antivirus software, your problem is not viruses. If you are in a position to need a rootkit detector, your problem is not rootkits.

"Best practices" cannot improve "worst design".

When you receive virus spam in your email, do not blame the idiot who clicks on attachments. Do not blame the asshole who writes viruses. Neither of them put the feature to execute active content in the idiot's email program.

GNU is Not Unix

Journal Journal: Words To Grow On, Part Deux 1

(See the first Words To Grow On.)

bulget n. Any budget without bound.

chadvert n. One of those subscription cards that falls out of magazines you've already subscribed to; also known as a blow-in. A subscription card whose very corner is bound into the magazine's spine may be termed a hanging chadvert.

commie for you, not for me n. A Marxist economics professor with a second home, a sports car, and a small child dressed in Baby Gap; who won't shut up about his mutual funds.

analoquy n. Talking out one's ass.

funk adj. The state of a Mac OS X system populated with Debian software. See fink. A fully funk Macintosh combines all the user interface madness of KDE and GNOME with all the user interface madness of Steve Jobs.

keyboard scenic route n. A keyboard shortcut that isn't. GUI programs which place utterly unrelated functions on the same basic key -- but with different modifiers -- may be said to take the keyboard scenic route. The more keys and modifiers you must tour to find the function you're looking for, the more scenic the route. This is particularly egregious on the Macintosh, where it violates Apple Human Interface Guidelines. One Mac example is Thorsten Lemke's GraphicConverter, an otherwise excellent program.

list incomprehension n. The use of nested Python list comprehensions, ideally combined with lots of % operators and "".join()s. Combines the readability of Lisp with the readability of C, all in a friendly Python syntax.

turnon n. The quantum particle of sexual arousal. In an excited state, a turnon decays to a hardon or a pounceon; otherwise, to two blue balls and a dammitrino.

unsubspam n. Any postal mail warning of the imminent termination of a trade-magazine subscription. "If you don't tell us today how much purchasing authority you have in your company, we will stop sending you ZD PCInfo-WorldWeek! Really!" To date, no unsubspammer has ever followed up on this promise.

ziff n. The mating cry of the trade-rag columnist; compare yiff.

Encryption

Journal Journal: Easy Puzzles

1. There exists at least one pair of words in the English language which are both reversals of one another (as "rat" and "tar") and rot13 of one another (as "she" and "fur").

Write a program to find such pairs. You may use as input a file of English words, one word per line -- that is, /usr/share/dict/words from a Linux or BSD system.

GNU is Not Unix

Journal Journal: Words To Grow On 1

alcoprog n. Any program written while drunk.

anal resentive adj. Of a person, characterized by envy of another's easygoing or flexible nature.

antisoftware n. Software written so as to restrict or harm its user, rather than to empower or assist him or her. The proper function of software is to work for its user: a word processor enables the editing of documents; a database enables the structured storage of facts; a chat or email system enables communication.

Classes of programs which restrict or harm the user -- in other words, to do the opposite of what is expected from software -- include Digital Rights Denial, spyware, Trojan horses, and "license managers". Much antisoftware can be identified by the user being compelled to run it, or held in ignorance of its running -- s/he would not run it by informed willing choice.

contrabland n. Bootleg recordings of "easy listening" music.

crack pipe n. Any network segment used chiefly for the delivery of attacks and/or DDoS packets. Also, the foremost shell tool used in rootkits, as:

./pr0tscan.pl | ./chk_vuln | xargs ./crack_host

immanagerial adj. Of an organizational superior or supervisor, immaterial. An immanagerial person is one who has managerial authority, but does no actual managing either positive (being a Good Boss) or negative (being a PHB).

improperty n. (Of old, synonymous with impropriety.) Property which isn't: that which is legally obtained not by trade or labor, but by enclosure or government monopoly. Examples of improperty include "taxes" on blank CD media collected by music cartels, airspace seized from property owners by factory operators for use in waste disposal, and most if not all forms of thought monopoly (q.v.)

nucular adj. Misunderstood, in the manner of the effects of a weapon or the risk of a power plant. The former tend to be underestimated, the latter overestimated.

obsoloot adj. Not new enough to have counted towards the speaker's current quarterly sales figures. "Buy a new operating system from me! Your old one's obsoloot!" Also obsoloser: one who complains about not having the latest kit.

planguage n. Any of the popular scripting languages, such as Perl, Python, PHP, or Pruby.

scientoloquy n. Any jargon whose terms are extensively and verbosely defined, yet entirely meaningless or nonoperational. "He buttonholed me for half an hour with scientoloquy about 'XML post-relational databases'."

secret source n. The opposite of "open source". To be preferred over "closed source" because it points out that a chief purpose of withholding source code is to withhold ugly secrets from one's customers.

Ugly secrets in the past have included antisoftware elements, design flaws, intentional backdoors, and acts of sabotage against competing products. Analogy to "secret sauce" is intended -- holding the source secret mystifies it, as if it were something besides plain ketchup and mayonnaise.

security by wtf 1z th4t b0x0r? A security tactic which involves running the same possibly-insecure software everyone else has, but on an obscure or less-popular architecture. The ready availability of exploits and rootkits coded for Linux/x86 and Solaris/SPARC does not lead to the availability of similar attack tools for Linux for PowerPC or ARM.

stubculture n. A group or affiliation standing in for a subculture. Like a stub procedure, a stubculture is empty of actual function. It is to be replaced with an actual subculture as soon as one becomes available.

suximetry n. The science implemented by devices such as the Sucks-Rules-O-Meter.

terrorist terrorist n. One who inflicts upon others the fear of terrorists; e.g. Tom Ridge.

thought monopoly n. A government-granted monopoly over the development and use of a set of thoughts. Examples include patents, as well as those aspects of copyright which restrict the development of derivative creative works. (The restriction of plagiarism is not thought monopoly, but rather fraud prevention. Restriction of verbatim duplication is arguably also not thought monopoly, as copying is not creative.) Trademark law creates thought monopolies only insofar as it is used to censor public thinking about the trademarked brand (e.g. parody and criticism), and not insofar as it is used to prevent fraud.

yibe excl. An expression of shockless dismay; contrast yipe.

Zork management n. A maze of twisty little meetings, all alike.

It's funny.  Laugh.

Journal Journal: Test 1 2 3 ... is this thing on?

Lobster Wing

You got a lobster and you got all your base
Lobster hot or not but don't you kiss face
Base are made of Slashdot
Lobster made of 1337!

You got a Mahir and you got a habit
If a Mahir horny, he yiff a cabbit
Cabbit is a furry
Mahir is a Turk!

Don't put a lobster on the Net
He'll use all your dumb fad to get hits
He'll DoS your favorite site
Then he'll bite your eye!

Lobster - sticks to - Web fad! (yararararar!)
Lobster - sticks to - Web fad! (yararararar!)
Lobster - sticks to - Web fad! (yahamsterdancer!)
Lobster - sticks to - Web fad! (yararararar!)

Left - clue - north
Rightcluesouth!

Slashdot Top Deals

For God's sake, stop researching for a while and begin to think!

Working...