Tuesday, March 30, 2010

Is Linux finally dead?

I really like Linux. You have to understand. When I started in IT, I'd spent a fair amount of time learning to program PCs. I could tell you from memory which was the mouse interrupt (12? wasn't it?) and how PC's allocated hard drive files. When the sat me down at my desk my first day on the job, it was in front of a brown screen wise terminal jacked into an HP Unix server. It wasn't so much a learning curve as a learning cliff. But I managed.

Over the years, I switched from HP UX to Solaris and learned how to do low-level file IO in C and how Unix/Linux/Posix does inodes. Good times. :D

At home, I've almost always run a Linux PC . I love the flexibility in XWindows. I geek out on running different desktop managers. I spent days (days!) changing my splash screen and getting fluxbox correctly configured.

I almost abandoned Linux a few years ago, but Ubuntu brought me back. What an awesome build.

So I got a really nice laptop a few months ago -- quad core, 6gb, 1/2 TB hard drive (with an open bay) and a really kickin' ATI graphics card. In many ways, it's the PC I'd always promised I'd get someday.
It came with Windows and I actually waiting for the latest rev of Ubuntu (Karmic) to set it up for dual boot.

But.... it kinda ... sucks. The audio card works great, unless you plug in the headset, then it plays sound through the headset and the speakers both. The graphics look ok, but the vendor's graphic drivers don't work. They cause the PC to do all kinds of crazy things (like the wifi card just drops when I use the vendor's drivers). I can read CD's but can't seem to burn DVD's -- and the lightscribe feature is totally unavailable because the manufacturer won't support Linux. My phone plugs in but Linux can't read it. Same with my camera.

I've read a lot online that Karmic is buggy. I can live with that. I mean, just between you and me, let's face it, Vista sucked. You upgrade and move on.

But the software for desktop Linux is disappearing. And what's left isn't working very well. Virtual Box (which is a really great product, by the way), has constant graphics issues with the new revisions of Linux. And it's crashed hard on me a few times. Rhythm box crashes if I change the volume twice (I can do it once). Google *finally* added support for Chrome, but it clearly wasn't at the top of their list.

And now I see this:

Basically NVidia is dropping open source support. That means (in effect) Linux wont' be able to really support NVidia cards anymore. As mentioned, my ATI doesn't work either. So that leaves Linux in a pretty bad place.

Add to that the fact that now Sony is dropping the option to (easily) install Linux on a PS3, and you start to see a trend.
Just about all the computer game makers have dropped their Linux support. There was a time when you could get the latest game ported to Linux, and available online or sometimes even at the local computer store. But those days are long gone.

Dell still sells Linux PCs (I think?). But last I looked they had one (count 'em ONE) latitude laptop with Linux and the not-so-stunning , bottom of the line Intel graphics card. And (I think?) Dell is about the only major manufacturer still offering Linux at all.

Does it matter? Well, here's my guess. In 5 years, no one will really own a PC -- I mean, the non-geeks (you'll have to pry my HP laptop out of my cold, dead hands, brotha!) . Everyone will have Netbooks for their day-to-day stuff, and PS3's/Wii's for their games and movies. In some ways, it's a step backward, really, since these will all use proprietary operating systems. That said, in many ways, proprietary OS's make sense. In a very theoretical sense, the one-size-fits-all PC is really a bit much. Windows has gotten pretty bloated as they've tried to put things in there that no one actually uses. Linux has too. The model of a thin client, with a hardware-tight proprietary OS makes a lot of sense, especially given the number of vendors now in the market.

The death of desktop Linux has been predicted a million times and I hate to be the million and first. But I have to say that things are looking dimmer. Sure, there will always be some government office in Botswana or something that uses it. And sure, there will always be hardcore geeks who play world of warcraft through wine.
But I look for desktop Linux to take step back out of the mainstream. Not sure if that's a good thing or not. Maybe it's where it belongs. Going mainstream has its price, too.

--kevin

Tuesday, March 16, 2010

encrypted data store

For a while, I've been struggling with how to persist database connection strings. Some of them have user accounts and passwords, so I don't want them in plain text in the config file. I don't really want them hard coded either. I have played with encryption mechanisms on the config files but can't find anything I like. Using Microsoft's default framework, either the encrytpion is tied to the user id --- so when you move from a dev account to a production one, you can't decrypt --- or it's tied to the machine, which affords the same issue. If you manually encrypt, then you’re just displacing the issue, since you need to find a way to store an encryption key or the like.

So, here’s my solution. I’ve set up an encrypted database repository to store database connection strings. The connection string to this repository is in a plain text config file, but since it is SqlServer, it uses user auth to connect – so, no passwords needed. Since it’s an encrypted table, anyone looking to decrypt needs access to the database, the table, the cert and the symmetric key. Without all those privs, you get nothing. If additional security is needed, you can add certificate enforcement on the connection itself.

Here’s how to set up the basics.

First, you’d need to create a table. I’ll ignore the DDL for this. I used a “database name” for the key. For the value, you’d want something like this:

ALTER TABLE DataConnectionValues

ADD ConnectionString varbinary(255);

GO

It should be a big enough column, of course. I picked 255, since it has to account for an encrypted string, which would be longer than the non-encrypted one. And I picked binary since the encryption may use non-standard characters.

Ok. Next we’ll need a master symmetric key, if one doesn’t exist

IF NOT EXISTS

(SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)

CREATE MASTER KEY ENCRYPTION BY

PASSWORD = ‘someCleverPassword’

GO

The inner select and existence check are clearly not needed, but I added them anyway.

Now a certificate:

CREATE CERTIFICATE DBConnection

WITH SUBJECT = 'Encryption for database connection strings';

GO

Next, a symmetric key using the cert

CREATE SYMMETRIC KEY DBConnection_01

WITH ALGORITHM = AES_256

ENCRYPTION BY CERTIFICATE DBConnection;

GO

I used AES 256, but SQL Server supports other encryption types.

That’s pretty much it for the set up.

Now you can insert a row into the table, then do an update to add the encrypted value.

To update a value, first open the key:

OPEN SYMMETRIC KEY DBConnection_01

DECRYPTION BY CERTIFICATE DBConnection;

Then do an update, using the EncryptByKey function (it takes a reference to the key just created above):

UPDATE DataConnectionValues

SET ConnectionString = EncryptByKey(Key_GUID('DBConnection_01'), 1234);

GO

The EncryptByKey will encrypt using the key, while the DecryptByKey function will decrypt, of course.

I’d recommend wrapping these in a set of functions or stored procedures so that the developers don’t have to mess with keys and certs. In addition, that means that the user accounts only need execute privs on the procedures, not select privs on the table.

The coolish thing is that the users will get nothing if their accounts don’t have the right privs.

To get that, you need connection and select privs on the table (or execute on the stored procedures), privs on the key and the cert.

You can add these cert and key privs by:

GRANT REFERENCES ON SYMMETRIC KEY::[DBConnection_01] TO [someUserId]

GRANT CONTROL ON CERTIFICATE::DBConnection TO [someUserId]

If you really want to get cool, you can add connection encryption to the initial connection string to get the database values. This is probably a good idea since you’ll be passing passwords across the wire. Doing that does two things: First, it encrypts the connection, second, it secures it via the certificate. Not only does this make it harder to hack the values, it adds an additional layer of authentication, since now, the user not only has to have the correct user credentials, but also has to have the correct certificate installed.

From the developer perspective, this is as simple as changing the initial connection string to something like:

Data Source=someServer;Initial Catalog=myEncryptedData;Integrated Security=SSPI;Encrypt=true

That last part sets the encryption to true, and secures the connection. To do this, you’ll need to set up a server certificate on the connecting server and also on the database server.

I’m out of space to discuss that here, but Google knows everything.


Next time I'd like to blog about how to wrapper this into a data connections library and use an object factory to really abstract the complexity of connecting to databases.



--kevin