Monthly Archives: August 2009

C++ Internal Classes

C++, like Java, allows you to have internal classes. You can implement them by simply including the class in the .cpp file and not in the header file. Yep, its that simple. If you try this you will probably realise that you cant include the class as a data member. This is because when you try to include it in the class the internal class hasn’t been declared yet. That’s easy to fix, you can prototype a class by simply adding class ClassName;. Why am I telling you this? Because its an interesting design pattern, and that inner class is called a “Cheshire Class”.

The Cheshire Class is a hidden internal class. This doesn’t immediately sound useful, until you think about how C++ handles private variables. When you add a private variable to a class, even though it is not visible to the calling application, it still affects the structure of the class and hence all the code that links against it will need to be recompiled. The Cheshire class prevents this by keeping all your private variables in a private internal class. See this Example:

outerclass.h

#ifndef OUTERCLASS_H_
#define OUTERCLASS_H_

class InnerClass;

class OuterClass {
private:
  InnerClass *internal;
public:
  OuterClass();
  virtual ~OuterClass();
};

#endif /* OUTERCLASS_H_ */

outerclass.cpp

class InnerClass {
public:
  int privateVariable;
};
OuterClass::OuterClass() {
  internal.privateVariable = 0;
}

OuterClass::~OuterClass() {

}

Now instead of adding new private data to the outer class, you add it to the inner class. This way your header stays the exact same, the data structure never changes.

Note that this does take up more space, and takes a little longer to resolve because it has to jump via and extra pointer but sometimes it is worth it for that nicer solution.
Random Thought: Which is more valuable, bread or gold? Why? Which is more useful?

Songs in Code

I had assignments to do this weekend, so I’ve ripped the best from #songsincode twitter. Enjoy!

antallan: substring(“the tiger”,6,1)

elephanti: try { me.add(shirt) } catch (TooSexyException e) {}

elephanti: if (you.near() || you.far() || you.getLocation() != null) { myHeart.setGoOn(true); }

codepo8: if(dogs.location==’out’){instigator.enquire()/*repeat if needed*/}

elephanti: sweetDreams = SweetDreamsFactory.getInstance().generate(these));

jorgelamb: GET /whatImLookingFor HTTP/1.1 -> HTTP/1.1 404 Not Found

mediadonis: HTTP/1.1 417 Expectation Failed | Location: http://getsatisfaction.com

geekyjohn: function checkColour(colour) { if (colour==’black’ || colour==’white’) { doesntMatter=true; } }

dudester: if ( strcmp(living, “without you”) == 0) strcpy(i, “can’t live”)

akselsays: if (touch==ground) and (me==on_the_hunt) and (me==after_you): smell_like_i_sound(lost_in_a_crowd=true) me = HUNGRY(wolf=true)

Spiiikey: while(self.location <> yourdoor.location) walk(miles(500)); falldown();

nigelwatson: if ( car.colour == ‘#FF0000‘ && car.size == ‘big’ ) { me.ride.like.add(car); }

jblyberg if (!$you->can_dance || !$you->will_dance) { $me->friend($you) = FALSE; }

yahelc: If(you.happy()&&you.knowit()) you.clap(hands);

kirilnyc: [“they call me %s” % n for n in (‘girl’,’Stacey’,’her’,’Jane’) if n != my_name]

benuphoenix: if content_of_whispered_words$ == “wisdom” then let it$=”be” ;

Random Thought: Twitter: Making your blogging just that little bit easier.

Pet Projects

One thing I’ve observed of people around me who are extremely passionate about computers is that they all have pet projects. For some its their work on an open source project, some maintain distribution packages, others run useful websites and some even attempt to found companies. I’ve had a few pet projects through my years.

Early in my high school education I discovered Microsoft Visual Basic 6.0. This was my original programming language and where I learnt the basis of my programming skills. Using Visual Basic I wrote many programs, some useful some utterly useless. I remember writing a chat program, a scrabble optimiser, a remote PC control application and several games. Unfortunately an over zealous system administrator saw many executables in my home directory and decided I had been infected by a virus and wiped the whole directory. Unfortunately as much as I protested and complained the files were never restored and they are all lost forever.

As I was completing my high school years I ran a web game with two fellow classmates of mine. We spend most of the second half of the year designing it and I spent my exam period implementing it. We managed to keep it running for a year until we ran out of funds (we were all studying) to support it. The game had several limitations and some major design flaws. I’ve entertained thoughts of setting it up once again many times, but ultimately without my two partners (one of who I’ve lost touch with) it would never work. In addition all copies of the original source code have been lost.

Now we come to my favourite project of all. WeatherMon was written for my Dad. He had bought a weather station that had a PC link and this enabled me to get the data into our server. Not only is WeatherMon‘s source code still available it is still running to this day. It was also my first foray into AJAX and XML. WeatherMon does not reload the page at all, and all data transferred is either images or XML. I’ve got a write up all about it here.

Finally, it began as a school assignment but I took it way too far. Originally I had implemented it as a web service, which I then extended to a website, then I made the XHTML so that it could easily be themed and finally I implemented several themes. You can read about converter here.

I think pet projects are what differentiates the passionate from the crowd. Anybody can write programs, and anybody can go to work and do it there. It takes the right person to want to toil outside hours on something that isn’t earning them any money. I think the best thing you can do to further your abilities and your career is to start a pet project. It doesn’t have to be thankless, or useless but that doesn’t mean it can’t be. Its easy, submit a patch to an open source project, become a maintainer for a project lacking development, fork a project, start a website or even start your own open source project.

Random Thought: How tasty is the definitive Open Sauce?

Microsoft Word Banned

Judge Leonard Davis, a judge for the U.S. District Court for the Eastern District of Texas, has ordered an injunction requiring that Microsoft stop selling Microsoft Word to the U.S. by the 12th of October. Less importantly he also fined them $240 million. What company could bring Microsoft’s office suite to its knees? They’re a “Collaborative XML Content Company” called i4i. They applied for the patent in question in 1994 and it was granted in 1998. The version of Word claimed to be in breach of the patent are Word 2003 and Word 2007.Microsoft Word Logo

Many people have been commenting on how its nice to see Microsoft taking a dose of its own medicine, but I disagree. Sure seeing Microsoft get hit with a massive fine and an explosive ultimatum is pleasing the subject matter isn’t. Patents were originally made to help the small guy, to aid innovation and so that inventors could reveal their inventions without fear of having their idea stolen from them and used to make money. Increasingly though patents are becoming the weapons of large corporations to battle with. Large companies are now applying for millions upon millions of patent in order to sue later when another company will unavoidably infringe on them.

The problem has gotten to the point where even looking through patents before you make something can make you more vulnerable to legal action. What is worse though is that it is showing no signs of slowing down. Even companies that have publicly opposed software patents are being forced to build their own patent portfolios so they can defend themselves.

I am not alone in my view here. Public opinion is beginning to turn. From colleagues, fellow bloggers, The EFF, major news outlets and even large companies most everyone is beginning to see the flaws in the system.

Random Thought: If Firefox was going to set the web alight, what is Google Chrome trying to do?

SSH Agent Forwarding

So you use keys to SSH between your hosts, and you either have separate keys for each machine you use, or worse you have the same key on each machine. Lets go over why each of those are bad, and lets see how SSH Agent forwarding will help with those issues and make things easier for you in general.

So the key part of why a SSH agent and SSH agent forwarding forwarding is so useful is due to the way keys can be attacked. If I wanted to get your SSH private key I could find some flaw in the system that would give me that /home/you/.ssh/id_rsa file you have. Of course a malicious user with root access to the system could just go in and grab it. You can prevent this kind of attack by setting a passphrase on the key. Of course the root user could replace SSH with a special version designed to get your passphrase, steal the key out of memory or setup a keylogger. This means effectively that your private key is not safe on any system where a person you don’t trust has root access, or has other users and exploitable vulnerabilities.

Single Private Key on Multiple Machines

In this example you’re trusting the security of every single machine you have your private key on. Should it get compromised then you have to revoke you public key from every host, and regenerate private keys to place on every host. Every time you put your private key on a machine you increase the chances that it could be compromised.

Multiple Private Keys On Multiple Machines

So we’re getting a little closer to a good solution. In this instance we don’t have to generate our key and roll it out to all hosts in event of a compromise. You can also have segregate groups, on set of keys for work, another for home and so on. Your keys can still be compromised easily though, and once compromised they can be used until you revoke them manually.

SSH Agent Forwarding

There is a way to keep your key safe from compromise. Now I’ll have to explain how SSH authenticates you using your key. When your authenticating with SSH keys your key isn’t sent, the server sends you some random data and challenges your client to encrypt it with your private key. It then verifies the encrypted data by decrypting it with the public key and checking if it matches the data originally sent. Now the way most people would SSH from the second host to another third host is to utilise a private key on the second host to connect to the third host. Unfortunately this method means that you have to store a key (that is open for compromise) on the second host. SSH agent forwarding tells the SSH client on the second server to send the challenge data through to the SSH client (or ssh agent) on the first host. The agent encrypts the data and sends it via the SSH session to the third client.

The beauty of this method is that the second host never sees a private key, and the challenge data is useless to try and connect to a different host. Even if the second host is compromised there isn’t a private key there to compromise. It should be noted that if the second host is compromised it can still request the agent identify for a different host, or the session to the third host can be taken over. Both these are temporary though and unless the malicious user installs their key (something easy to notice) they cannot get back in.

Diagram detailing how an SSH connection is authenticated using agent forwarding.

Diagram detailing how an SSH connection is authenticated using agent forwarding.

If you want to know more about how this works, there is a wonderful tech tip at http://unixwiz.net/techtips/ssh-agent-forwarding.html.

But how?

SSH agent forwarding is even easier than copying keys all over the place. The first step is to generate keys for all the machines you log on to directly. You need to be sure these machines are secure and that your keys will stay safe, though this is sometimes not possible. You then add the generated public key to the authorized hosts file of all the machines you will connect to from this one, including ones that take two or more steps to get to. Finally you edit your ~/.ssh/ssh_config file to tell SSH to forward your agent through those hosts. Include the intermediate hosts in this list, but not the endpoints. You could also use SSHmenu to add the arguments automatically to those SSH commands. The following disables forwarding to all hosts, and explicitly enables it to fred, and aaron.missgner.com.

Host fred
  ForwardAgent yes

Host aaron.missgner.com
  ForwardAgent yes

Host *
  ForwardAgent no

Random thought: Linux has Plug ‘n Pray too, you plug the device in and pray the drivers aren’t proprietary.