Thursday, September 28, 2006
Time to Recharge
Toothbrush? Check. No, I don't really have a Civil War reproduction toothbrush, but that's kinda cool isn't it?
Change of Clothes? Check.
Diet Pepsi? Check.
New Neil Gaiman book? Check.
New Tom Waits CD? No. That won't be released until November. Oh, well.
Stop thinking about work? Check. (Thus no link to work.)
Great. Looks like everything's in order. I'm outta here until next week.
It feels a little strange to leave without having today's Marmaduke explanation, but I'll find some way to deal with it.
Wednesday, September 27, 2006
So not much blog posting. Oops. So much for personal goals . . .
Yes, I'll get back to my security primer. Give me a week or so.
Current state of the Drew: Crunchy.
In the last few weeks I think I've pretty much found every way I can (short of checking in my own damned fixes into the source tree (which I might start doing if those guys can't get their shit together)) to piss off my devs. Mostly, I'm just looking for ways to better manage our project. I want us all to be open and accountable. Is that so wrong? Well . . . maybe. I admit that I tend to forget that there are egos involved. I just look at an engineering problem as a problem with known parameters and find a way to solve it.
So here I am. *sigh* At the very least, I know that Taceo 1.7 will suck less than the previous release (And what the crap is a DCenter? Is that what passes for the new cool? I'm so outta touch.) In fact, it will suck so much less that I would encourage you, my few (one?) readers (reader?), to try it out. In about two weeks or so. I'll let you know.
For right now, I'm mostly considering my plans for changing process at ESS and my wonderful 3 day weekend in Ashland, OR for the Shakespeare Festival. I really need that break. And more time with that W woman. *sigh* (reprise)
Also on the up-side, I'm really looking forward to the new SDET lead who accepted our offer. I need to share my work stress. Um . . . duties. I hope he really knows he's in for startup-land. It's a wild ride compared to Microsoft. Not so many superstars here. Hell, it makes *me* seem like some kind of superstar, but I'm not.
Actually there are many upsides. I'm just feeling a bit burnt and crunchy, so I'm probably coming off more negatively than I should. Apologies.
(P.S. Why does Blogger's spell-checker suck so much? Is it because people expect so little of Google that they can keep shipping total crap?)
(P.P.S. How many days does it take Google to realize that Blogger's certificate is expired? Is it more or fewer days than the number that it takes for me to figure out how the hell to send their tech support a mail to tell them that there's a problem and how to fix it? *grumble* Answer: less. It took a few days. In those few days I didn't know how to let Google know there was a problem. I tried. Multiple times. Customer service these days . . . Then again, I guess everything from Google is always in Beta, so it's not a problem.)
(P.P.P.S. Whenever Google decides to 1. get serious about security and 2. get serious about customer sat, please someone let me know. I hear it's a great place to work. If you don't care about those things.)
Saturday, September 23, 2006
Bug Meanings: Priority and Severity
Depending on the time we're at in the ship cycle, some of those bugs might not be severe enough or high-pri enough to fix. Ok. We all ship with bugs. That's standard practice.
The hard part is defining those cutoff choke points and what they mean in sev and pri numbers.
If I were really smart, I'd propose an algorithm and then also a follow-up graph of some sort that would explain how software works through its lifecycle. I'm not so smart. I don't know how to do it. Every piece of software is different. It seems that as software engineers we're lacking here. Someone should be able to define these things and tie them to milestones in the product. If we were *real* engineers . . .
Expect a "part two" to this post in the next couple of weeks as I digest and expel ideas.
Thursday, September 21, 2006
DRM Is Evil!
Check out this interesting anti-DRM blog:
I'll get back to DRM probably sometime next week. I'll explain my insider's view of what it offers, how it falls short, and how it is seen (or misperceived).
I should also add that this is my own personal blog and my opinions are my own. They are not necessarily those of my employer (ESS) or anyone in any way associated with the company. If that wasn't already clear from the get-go, then for the sake of that guy who could fire me at a whim, please let it be clear now. Here are photos of him with the rest of the gang. I think they were all high on nitrous in front of some shrubbery at the time. I dunno. I wasn't there. LINK Also - ignore the text about them. Notice that they all have the same toothy smile. Could this explain the strange set of false teeth I happened upon in the storage room or are they actually all the same person (thus same teeth)? Oh, the mystery! Anywho . . . these opinions are my own and not those of the mothership (which my want to beam me up for refactoring or somesuch after reading this blogpost).
Security Primer in No Particular Order - preamble
Why no particular order? Well . . . let's face it - I'm just not that organized . And I'm sure that even if I were something would occur to me out of order after I'd published it. So no particular order.
This is the "why I'm bothering to post the series and sorry it's not more helpful" post that kicks off the (at least) week or so of basic security know-how. I may amend this post or any of the ones to follow to add useful info.
Maybe after that I expound on useful tools or even sneaky tester tricks. I think I should run with themes.
So how do I explain computer security to my mom? Or my brother? Or some stranger on a bus who insists on talking to me despite that I'm trying to read a book? Hmmm. We'll see . . .
Most certainly I'm going to refer often to places like SANS and RSA and others. Of course there will be some nod to gov't standards like FIPS, too. And because I'm primarily focused on working on Windows ('cause most folks are), you'll get a fistful of links to MSDN content and KB articles (why doesn't MSFT offer something like KBAlertz?).
 I couldn't find it online, but I seem to remember some (translated) Pablo Neruda poem that began something like (in English translation, and this misses a lot of the meaning): "All the fishes in the sees are all organized". Having grown up in a union town, it speaks to me. But in the non-union way it also speaks to me. Then again, it's not Google-able, so maybe I imagined it.
Tuesday, September 19, 2006
Obscurity Rode in on a Dead Horse
I don't know who originated that mantra, but if I did, I'd sign that person up for lots of spam. Because I'm not a nice person. And because there's almost no one more worthy of useless, repetitive garbage clogging up the daily works than the person who first said those words. I would consider it to be a kind of poetic justice. We need more poetic justice in the world.
In and of itself, there's nothing wrong with the *intent* of the statement. Regarding crypto algorithms, just not divulging the algo isn't as safe as using one with a known, tested strength. Ok. Fine. I accept that.
The problem is that the statement has been so often misapplied to anything in the security realm that it loses its meaning. It becomes often wrong. Much in the same way that as it is repeated ad infinitum it becomes nothing more than a mantra. Mere dogma. Dogma that kind of rhymes. It rings through with the mellifluous tones of a dead horse being beaten. Repeatedly.
How is it misapplied? Imagine that you stashed an extra house key in one of those fake rocks. (Who buys all of those anyway?) Is it obscurity to hide the keys there? Sure. Is it security? If it mitigates against easy compromise of the key, then I'd claim it is.
Security isn't just some academic thing. It's about mitigating against real risks in real life. This ain't rocket science. Anybody should be able to understand it. Risk: key compromise. Our chosen mitigation: fake rock.
Perhaps a better mitigation would have been to not leave a key outside your house in the first place. But what if you had a requirement to be able to get into your house even if you had locked your keys inside the house? In real life there are other concerns than one would find in a strict academic (read "not real world") scenario. Maybe . . . just maybe . . . that "obscurity" was just the security that you needed to meet all of your requirements and still mitigate against easy key compromise.
Sometimes obscurity *is* security. Conversely, the lack of obscurity may sometimes also be security. But that's another blogpost entirely.
I wonder if I'll need to explain next how Heisenberg's Uncertainty Principle doesn't apply to prime time network TV programming . . .
File.Exists Is Evil
File.Exists. If you code to the CLR you're probably familiar with that. What does it mean?
You call File.Exists and you find out that it exists. What does that mean?
It means that at some point between the time that you called the function and the time it returned that file existed. Or didn't. That's it. That's all you know.
Why is this bad?
It's bad because people tend to take for granted that the result from File.Exists is always *still* true. This is a problem mostly because the function should have been called File.Existed. That's all you really know. It used to be there. No promise about its current availability. Period.
Ok, so let's dig into it deeper. Why is this "evil" and not just "kinda wrong"?
Because devs build assumptions. Developer assumptions often translate into bugs. (Trust me - I'm a tester!) Developers often assume that the result of File.Exists tells them whether or not a file exists. That's not what it does. It only says whether or not in some past time that file existed. Thus, there's an assumption. Thus, a (probable) bug. Ick!
This is a race condition magnet. If you're reading this and you're a tester, then look for File.Exists in your devs' code. It's almost certainly the source of a bug. If you're a developer, ask yourself why you'd ever use File.Exists.
1) Can I do X with the file?
If this is your question, I recommend just trying to do X. Even if File.Exists works most of the time, those other times probably need to deal with whatever exception is thrown. Relying on File.Exists probably puts an implicit race in your code. Just don't go there.
2) Did FOO write something?
If it did, that log may not exist now. Chances are that you want something useful NOW and not a few milliseconds ago. Counting on FOO's file to have existed again introduces a race condition and there's probably an exception you're not wanting to handle. Just catch the exception and skip File.Exists. Make it simple. And robust. Write good code.
3) Should I overwrite or delete BAR?
Um . . . same as the other stuff I just said. Don't. Just don't. Make your code thread-safe. Reliance on File.Exists doesn't do that.
4+) Yes, there are more, but they're similar. I'll skip them.
At best, File.Exists can be a fairly reliable way to know that something *didn't* exist. Even then, there's a race and you're not being threadsafe. At worst, you've opened your code to Heisenbugs that you may not be able to diagnose.
I have no idea why anyone ever introduced such a construct as File.Exists. I can only tell you that it's evil. Avoid it. It only leads to bad code. Let's hope that saner heads prevail in DevDiv and this goes the way of the Democrats^H^H^H^H^H^H^H^H^Hdinosaurs.
Ok, I got a bit glib there. I meant to show examples of crap code that counted (unreliably) on File.Exists. I couldn't do it. It was too painful. Please forgive me.
(P.S. I lean a bit left, politically. Shut up already, lefties! It's a joke.)
Thursday, September 14, 2006
Sweet! I have my gag feather poised carefully near Robert Scoble's uvula. Now all I have to mention is how Microsoft apes Apple and . . .
Oh! It's all over now, folks. What a messy ending!
(This is why nobody lets me make movies.)
Um . . . who the heck cares? Technology feeds on its own and spawns better. Or sometimes worse. What prevails prevails.
I don't really care whether my iNewFancyWidget came from Steve Jobs or Stevie Wonder as long as it's easy to use, makes me happier, and lasts until Stevie puts out a new album. I hope the iNewFancyWidget is accessible for blind folks . . .
I don't really care who first invented the iNewFancyWidget as long as I can use it. If possible, for free. And to communicate with my friends and loved ones. Or to see pretty women naked in some more realistic way (pr0n drives tech).
I just don't care. Gimme what I want. I don't care about its provenance. I'm like a pawn shop in that way, I suppose . . .
(P.S. Yes, I'm skipping the technical post again tonight. I'll do it tomorrow.)
Tuesday, September 12, 2006
The teaser is this, though: Tomorrow: File.Exists - File.Existed?
Oooh . . . quite the cliff-hanger, eh? Yeah, you're right. It's going to be boring and geeky(yeah and so what if I like BOFH?). And existential. Oh, deeeeeeeep, man, you might be thinking after I dropped a word like "existential". Well . . . no. Not really. It's pretty common sense (not quite like that, actually) once you understand the sense of it. Just like all other common sense. And still boring and geeky.
So check in tomorrow as we delve into the horrible development practices encouraged by File.Exists and the nasty nasty bugs that come of it. [Queue spooky music. I'm outta here.]
Storing Credentials on Windows
Monday, September 11, 2006
On a related note, why isn't "Google" in Blogger's dictionary? Is it because Google claims that Google shouldn't be used as a verb even though the OED and Webster's say it's kosher now?
Pesky Salesmen (Or Maybe Support Reps)
I tried out several competing applications recently. I had a need that they all claimed to fill. They were each top hits when I searched for applications of that type. Your application was one of them.
After evaluating them, I determined which one I wanted to use. Yours wasn't it.
Before I had even finished my evaluation, I received an email from you thanking me for evaluating your product and telling me what it did. This struck me as odd, because if I hadn't already known what it claimed to do I wouldn't have downloaded it now would I?
A few days later you emailed me again with an offer to help me in my evaluation. Persistent bugger, aren't you?
A few days after that, yet another mail to see if I needed more time to evaluate your app. Trust me, I don't.
Moreover, maybe it's just me, but I absolutely hate people trying to sell me things. Yes, I had shown some kind of interest by downloading the software in the first place, but that doesn't mean I wanted to talk to any sales or support staff. If I had, I would have taken the initiative (the same kind of initiative it took to understand what your product does and to download it) to either email or call your company. I'm not shy. Honest.
Frankly, I wasn't intending to respond at all. I felt I'd already invested enough of my own time in using your software and determining that there are better products on the market. I felt that it wasn't worth spending more of my personal time dealing with you.
The more I thought about it, though, the more I empathized with you. You're probably a nice enough fellow. You probably believe in your product and just want to show everyone how wonderful it is (or isn't). At the very least, I owe you this bit of advice: please don't sell so hard to me. Or anyone else who only downloads your app. We don't expect or want that. It's the kind of behavior that entirely sours people on a company.
If you really want to be personally available to help me when I evaluate your product, I suggest you talk to your developers and have them make your contact information easily accessible through the application. The phone numbers and email address you sent me so that I could contact you with any questions? Put them in the app! For that matter, this is the 21st century - give me some IM contact info, too. Let me know up-front that my *personal* support or sales (or whatever your position is) representative for my trial of the product is Bill Smith (not his real name). But stay out of my face with it until I actually want help, please.
Ok, that's enough ranting from me. I'm not trying to ruin your day. I was just hoping to provide some insight on this particular customer and give you some personal feedback. We only grow as people by helping other people grow, right?
Thanks for your time and good luck in the future!
Impress Your Coworkers!
Then I got an email from marketing telling me that I did a great job in driving traffic toward the company's website. Huh? The morning was only getting weirder.
The marketing folks (whom I can't ever call "marketroids" here now because they'd know I said it) monitor the hits the ESS website gets. Apparently some people followed links from this blogpost and visited the site. So everyone in marketing read my blog. And the CEO found it, too. That explained everything.
I'd like to explain that I'm not in marketing, I'm not trying to shill anything here, and this blog is in no way attempting to represent that company I work for. So any claims that me putting in links like this one are really just some kind of marketing ploy are patently untrue. Seriously, though, this is my blog and it's about whatever I want to write. I don't want anyone to think otherwise.
Moreover, if you visited ESS and downloaded Taceo, I'd like to let you know that I know that 1.6.5 is buggy. Lots of known bugs. We released it just after I was hired. Don't think for even a second that our up-coming 1.7 release (early October?) is going to be such crap. It will, of course, still be software. I'll even go so far as to say that if you haven't tried Taceo yet but you've been wondering about it . . . wait until October.
Because I'd like tomorrow to be just as exciting as today was, I wrote that previous paragraph. I wonder who will say something to me about it. I wonder what those folks will say.
Someone who shall remain nameless also requested that I not blog about anything too negative like KILLING THE PRESIDENT because it might cast a bad light on ESS. The sentence you just read was intended for that nameless person and for the wonder that is the Google search engine, which should make it easy to find my blog by searching for the phrase KILLING THE PRESIDENT. Luckily, Google knows about alternate forms that some words can have and can substitute them, so I shouldn't have to include phrases like TERMINATE THE LIFE OF THE CHIEF EXECUTIVE or DEAD-IFY DUBYA, but I'll include them anyway.
On a side note, this means that some strangers have actually been reading my blog. Cool! Hello, strangers from the intarweb! Please make yourselves at home.
Note to self: Archive a copy of Taceo 1.6.5 and 1.7 when it ships. These could be very useful in a few years when it's job hunt time again, assuming my next gig is also in test. What did I do at ESS? Well, in the first couple I months I helped shake bugs out so that this [point to 1.6.5 while making a disgusting face] worked like this [point to 1.7 accompanied by a less disgusting face].
Sunday, September 10, 2006
Software Sucks - But Why?
One of those thought-invoking posts has been haunting me for over a day now. He visited Seagate and blogged about it. What really grabbed me was this offhand comment:
You rarely think about drives or storage media until they fail.
And you don't, do you? But what's the implication therein? Think about it . . . ok, had some thinking time? Right! What about the things you worry about that haven't entirely crapped out? Things like software?
Why does software suck?
As a tester, this question is dear to me. I am constantly surrounded by software that sucks. A lot. I have no idea why. It is my own personal hell. Welcome to my world: software.
Software sucks because people expect it to. Why code to a higher standard when everyone knows that the UX is gonna be crap? People expect it. Give them the status quo.
Software sucks because (good?) developers are lazy. Make more with less. That's what they do. And the "with less" means it's gonna suck.
Software sucks because testers don't bother to find the bugs. Ok, so I'm guilty of letting a few bugs ship, but not out of laziness or ennui. It happens.
Are any of those good answers? I don't think so.
In the case of something like Windows or Office, software sucks because 1) it has all kinds of compatibility problems and 2) because they're both expected to ship with *known* bugs (let alone the unknown ones), but more so because 3) they're not stable long-term. Those hard drives from Seagate are pretty stable technology. Seagate might make them larger. Or faster. But they aren't always trying to rearchitect the HDD with every release to make it "exciting". Hardware (once it is fairly venerable) is interested only in *working*. Software is far too experimental.
Ok, so to build on that, why is software so pliable when hardware isn't? By its very nature, it's easier to change software than hardware. Even firmware updates are really software. Once the beige box is in someone's home it's going to be years untl that person buys a new beige box. Software is highly available as download from any number of sources.
Let's try this from another angle. Software "engineers" aren't really engineers. They're hackers (in the older, less pergorative sense of the word). And worse, they're almost always playing with their code. They want to keep producing as much as possible. This is almost entirely antithetical to the hardware folks (measure a bunch of times; build once).
Then again, maybe software sucks because the market bears it.
I'm sure I can come up with more. I've really only started to rant on the topic recently.
Fixing the problem that DevDiv has with Authenticode
Here's code for a simple command line app that strips out all Authenticode signature info from a file, including just the entries in the file's header in case Visual Studio worked some nasty mojo on it. Enjoy!
// An app to make hiterto unsignable file signable again.
// 8/10/2006 - Drew
int wmain(DWORD argc, LPWSTR argv)
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD dwResult = ERROR_SUCCESS;
LPSTR lpszImageName = NULL;
size_t cchImageName = 0;
if(2 != argc 0 == wcscmp(L"-?",argv) 0 == wcscmp(L"/?",argv))
wprintf(L"%s takes one parameter - a file name to strip of its embedded Authenticode signature.\n\n", argv);
hFile = CreateFile(argv, GENERIC_READ GENERIC_WRITE, FILE_SHARE_READ FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE == hFile)
dwResult = GetLastError();
wprintf(L"CreateFile failed with error 0x%08x\n", dwResult);
dwResult = GetLastError();
wprintf(L"ImageRemoveCertificate failed with error 0x%08x\n", dwResult);
if(ERROR_INVALID_PARAMETER != dwResult)
wprintf(L"This happens when there's a listing in IMAGE_DIRECTORY_SECURITY\nin the PE's header, but the acutal Authenticode signature has been stripped.\nLet's fix that . . .\n");
dwResult = ERROR_SUCCESS;
if(CloseHandle(hFile)) hFile = INVALID_HANDLE_VALUE;
// This is somewhat sloppy, but if we're here we've almost certainly found a PE with an
// IMAGE_DIRECTORY_SECURITY that has nonzero SizeOfRawData and/or PointerToRawData,
// but the actual signature (that raw data) has been removed.
// What causes this? IIRC, strong name signing something that's already been Authenticode-signed.
// The workaround is to crack open the PE and write zeros into the directory entry so that everything
// that eventually calls through the Image*Certificate* APIs won't choke.
cchImageName = wcslen(argv) +1;
lpszImageName = (LPSTR)malloc(cchImageName); // Yeah - so I'm all old-school mallocy!
dwResult = GetLastError();
wprintf(L"Malloc failed. GLE == 0x%08x\n", dwResult);
if (-1 == sprintf_s(lpszImageName, cchImageName, "%S", argv))
dwResult = GetLastError();
wprintf(L"Failed to copy argv to string of chars. GLE == x0%08x\n", dwResult);
if(! MapAndLoad(lpszImageName, NULL, &image, FALSE, FALSE))
dwResult = GetLastError();
wprintf(L"MapAndLoad failed. GLE == 0x%08x", dwResult);
wprintf(L"certificates->Size == 0x%08x\n", image.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size);
wprintf(L"certificates->VA == 0x%08x\n", image.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress);
wprintf(L"Setting both fields to zero . . .\n");
image.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = 0;
image.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = 0;
dwResult = GetLastError();
wprintf(L"Failed to UnMapAndLoad. GLE == 0x%08x\n", dwResult);
if(INVALID_HANDLE_VALUE != hFile) CloseHandle(hFile);
if(ERROR_SUCCESS == dwResult) wprintf(L"Succeeded.\n");
Friday, September 08, 2006
File Under: Schadenfreude (Warning: I swear in this one!)
I laugh the nervous laughter of an ex-Microsoft's who was increasingly ever more aware of draconian IT practices over the years. Ha. Ha ha. Ha! Ha ha ha ha ha. Oh, dear . . .
I think Microsoft doesn't get it. Again. Surprise! ;-) Tech geeks live and breathe connectivity. They absolutely need their web access. But why? Is it the web? No. It's the information, stupid. Yes, that means Microsoft need to see mine's site. Because THAT'S WHAT PASSES FOR TRANSPARENCY AT MICROSOFT. They need to know what's happening throughout the company. Even if that means watching all the troll food and its inevitable reactions scroll by (PgDn, PgDn, PgDn . . .). Hell, maybe that means getting their pr0n (no link - make your own). Whatever it takes to make them more productive. Who am I to say? Why does MSFT care what their employees read at work? At all? *harrumph*
This totally stinks of Microsoft's leadership being afraid of the plebes. And they should be. If they hired right, all of those plebes are smarter and better fit to lead than the senatorial class of 68+ ("partner") folks laying down the laws.
So what happens next, Microsoft? If you want to bleed talent, I'd love to hire some! Give me your smart, your driven, your undervalued masses . . .
[Drew strikes a Statue of Liberty pose.]
We're always hiring talent here at ESS. Even if the job board doesn't say so. Just try us. If you're a superstar we're not gonna say no. Then again, if you're a superstar you don't really need the invitation, do you? Just come on in!
I Resolve . . .
I need to just state that publicly. Gotta stop the slide into blog netherland.
Ok, so here's something maybe of substance:
I read Joel Spolsky's blog pretty religiously. Meaning the feed shows up in RSS Bandit and eventually I get to it. I somehow ended up being the de facto build engineer a few weeks ago. While I was trying to figure out how to link Subversion, Bugzilla, our couple of email servers (don't even ask why we have separate POP3 *and* Exchange servers - I mean it - don't ask), my nightly build script (yeah, no link there 'cause it's some in-house kludge that I cooked up in a hurry), and product supports software (no name mentioned; nothing linked) I decided to look into that FogBugZ thing Joel's always peddling. Neat! In fact, very very neat. Our product support guy is looking into it right now and he seems impressed, too. I have this crazy feeling that a lot of the infrastructure problems I've been dealing with will go *poof* and I'll only have a few loose ends to tie up.
Does anyone (if you're reading this) have any opinions about FogBugZ? Frankly, it makes that crapola I was using at Microsoft look like . . . ok, crapola. I'm not sure it scales to the level of Microsoft's money-making divisions (all two of them), mind you, but ESS isn't Microsoft. There are pluses and minuses in that, but so far I think I'm in the black.