When I'm feeling especially paranoid, I worry that even my secure passwords are vulnerable to key loggers and other software that could be running on a computer. This is doubly true for public terminals. Also, as a consultant, I don't like to install applications on my work computer so I use portable applications off of a USB drive that I carry with my keys. Gizmo Richards' newsletter has a great article about improving password security in the June issue as part of a series about increasing security when using public terminals. So what can you do to improve your security when entering passwords?
Quite a lot actually. Of the many different options available to improve your password security to me the most attractive is to enter your passwords using a password manager like RoboForm2Go running from your own USB flash drive. The article also goes into alternative techniques to make entering a password more secure in order to obfuscate it from anyone snooping on you.  - Choose passwords with random characters that are long. This is standard password strength advise that is covered here and here.
- Look behind you for people/cameras that may be able to see what you're doing. Shield your keyboard if you're worried about visibility. You may feel silly about looking paranoid, but it only takes a few seconds and the only people would will even notice are ones that are trying to spy on you.
- Enter your password in a way other than just typing. This includes pasting from the clipboard, drag and drop from another place, use ALT+numpad combinations to insert letters, insert dummy characters and remove later, enter parts of your password in a different order, highlight and drag characters to another location, and maybe even using the character map to insert characters. Ideally you would use a few of these techniques together.
This information is useful even if you're not using portable apps, but worry about password strength and vulnerability. There will never be a totally foolproof method, but one of the best methods to increase security is to do things that make you less of a target. Just like pickpockets will target people who are more vulnerable, hackers and spies will target people using little to no security and ignore you because it would take too long to figure out what you're doing. Labels: security
As part of a significant refactoring effort, I was moving code from one project to another and accidentally made a change that resulted in a much different result than I expected. I'm getting a date from a database query, but that date column allows nulls. Here's what I had before: DateTime? someDate = (dataReader["DATE_COLUMN"]) != null ? Convert.ToDateTime(dataReader["DATE_COLUMN"]) : new DateTime?(); And here's what I ended up typing in my refactored code: DateTime? someDate = (dataReader["DATE_COLUMN"]) != null ? Convert.ToDateTime(dataReader["DATE_COLUMN"]) : default(DateTime); I didn't even realize I'd written the code differently, probably because they should have the same result, but they didn't. The first version, new DateTime?(), has the value null, while the second version, default(DateTime), has the value 1/1/0001. That's not even a valid date in SQL Server! The following code in a console application will demonstrate different default values. Console.WriteLine("new DateTime?() = {0}", new DateTime?()); Console.WriteLine("default(DateTime) = {0}", default(DateTime)); Console.WriteLine(); Console.WriteLine("new TimeSpan?() = {0}", new TimeSpan?()); Console.WriteLine("default(TimeSpan) = {0}", default(TimeSpan)); It looks like a new instance of a nullable object will always be null, while the default value for that type won't be null. Of course, I came to this conclusion with very limited tests, but it's good enough for me.  Labels: c#
I'm annoyed when sites require you to register in order to access certain parts. It's one thing to mandate authentication if a user is modifying or submitting content, but to for things like downloading sample code it is ridiculous. If you run into this situation, go to Bugmenot.com, type in the domain of the web site, then try one of the registered username/passwords. If you can't find one that works, you can register yourself, using a temporary email address of course, and submit your registration information to Bugmenot. Yet another victory for the web community. Labels: web
I've blogged before about my tendency to use the mouse over the keyboard. Currently I have a Microsoft Natural Ergonomic Keyboard 4000. I liked my old Microsoft Natural Multimedia Keyboard, but the keys were sticking and the light grey colored plastic was seriously discolored and nasty looking (my sweat is great at discoloring things). My wife didn't like the ergonomic split keyboard of the 4000 I got for home, so I took it with me when I started my new job. Comparison Pros - 5 customizable buttons designed for launching apps
- standard layout of the insert/delete, home/end, pgup/pgdn buttons
- black coloring looks nice and won't show sweat residue
- back/forward buttons (see below) and zoom in/out toggle
- wrist pad feels really nice
Cons - only media buttons - play/pause
- volume up/down/mute controls windows, not media player
- wrist pad is already staining where my wrists rest
- zoom in/out button not customizable
- I don't like how pressing keys feels - not enough tactile feedback
Back / ForwardI never really liked the back and forward buttons that tend to end up on mice, and having them on the keyboard is even more useless. When I'm surfing, I'm actively using my mouse, so I don't mind clicking back/forward in my browser's toolbar. I end up mapping the mouse buttons to other things. I also don't surf while at work, so I found a practical re-mapping for these buttons. Visual Studio shortcutsLukeH's recent post about the F12 button reminded me of a custom configuration I have set up.  The post mentioned the navigate back/forward functionality in Visual Studio. I configured my keyboard's back/forward buttons to the these navigation keystrokes so I can easily move around in code without moving my hand to the mouse. I've found this configuration very useful. I've actually been trying to learn more keyboard shortcuts lately, and set my own. I've downloaded Roy Osherove's Keyboard Jedi application, but I'm too much of a wimp to turn on the no-mouse feature. Where's the mouse?My motivation behind using more keyboard shortcuts is because I moved my keyboard to a keyboard tray that doesn't have any room for the mouse. I was using my mouse on the desktop, but my shoulder really started hurting from having my right arm extended so often. Also, my wrist was resting on the edge of the desk which was sometimes cutting off circulation.  My solution was to get a trackball to fit in the 3.5 inches of space available on the keyboard tray. I tried the Logitech Cordless TrackMan Programmable Optical Mouse, but the thumb buttons were too close to the keyboard and I just couldn't get used to using my fingers to navigate and click. I now use the Logitech Trackman Wheel Scroll Optical Mouse trackball and I'm amazed how quickly I adapted to using it. ( why can't Logitech come up with product names that don't all look the same?) My navigation speed is still a lot slower than with a regular mouse, and when it's getting close to lunch time I sometimes find my thumb starting twitching making accuracy very difficult, so I still have my regular mouse attached. This is also useful when a co-worker stops by and wants to take over to show me something. It's funny how many people are surprised that you can have multiple I/O devices of the same type attached, but it really doesn't cause a problem unless the configuration applications conflict. Reminds me of a year ago when I was working on virtual keyboard functionality and had three keyboards, all different languages, attached at once in order to do unit testing. Unfortunately, the trackball doesn't have any thumb buttons, but I did remap the middle click to bring up my Clipboard Recorder floating window, which is occasionally useful. Labels: devices
With my family out of town for the past couple of days, I found myself with a lot of free time that I'm not normally used to. I was planning on doing some things that I've wanted to get done for a while now. I didn't get any of these things done. I look back and realize that I didn't use my time effectively. I need a new strategy. The NormNormally, a full time job, significant commute and a toddler add up and leave me with almost no free time each day. What free time I do have with ends up being at the end of the day, spent on time fillers that are of questionable value, but allow me to let off some steam. Things such as reading blogs, watching TV, playing games on my DS. While my television time has gone down significantly (thanks to TiVo), it's empty time. The same could be said for playing video games, but at least they're more interactive and engaging. Reading blogs could be considered useful, but I seem to only really learn anything from maybe 10% of what I read. Everyone needs time for activities that allow them to relax, but I think I've gotten so used to spending my free time in this way, when I end up with a large chunk of time to do something useful I fall back to the things that I'm used to doing. I've been conditioned to fill my free time with small chunks of relaxing activities. So with several evenings with no responsibilities, what did I spend my time doing? - I put in extra hours at work.
- I read blogs.
- I slept in.
- I played video games.
- I spent time making lists of things I've been meaning to get done.
Boring!Have I really become such a dull person. I'm not going to complain about having time to do all of this, because it was nice. But, please! Working overtime? I think it was so novel to not have to leave by a certain time to pick up my son at day care that I worked later than usual. When I got home, I had the computer to myself, and got sucked into catching up on my feeds. I was so lost in the moment of not being distracted, that I even forgot to eat supper. The next morning I slept in and worked late again. "Hey, I don't have to leave until I get my current task done!" I arrived home late again, low on energy. "I need to focus on getting some of these things on my mind done, " I said to myself. "I know, I'll make a list!" I started up the laptop. "Let me just read my email first. Oh yeah, and I'll quickly check some of the blogs that I like to read regularly." You can see where this is leading. By the time I made my list, it was late at night. The list was also so large it was overwhelming. Luckily, one of the blog posts I read made me realize that I need to manage my time better. J. D. Meier has some good advice on time management that I'm going to try to leverage. I need to cut my list down mercilessly and figure out what my top priority is. Another problem I have is that there are so many amazing new technologies coming out lately, in addition to existing languages and frameworks I'd like to learn, that I can't possibly learn them all so I need to focus on one, but I don't know which one to choose. The PlanMy plan is to commit to a 30 Day Improvement Sprint focused on my top priority. I can't spend a lot of time each day, but if I spend it consistently I will get results. I'm still not sure what my focus area is, but it will be obvious because part of that goal is to blog daily about my progress. Labels: effectiveness
If you've ever been annoyed about having to activate a window, or part of a window, in order to scroll with your mouse wheel, then KatMouse is for you. KatMouse is a free application that allows you to scroll the window below your mouse cursor, even if it's not the active window or is behind other window(s). It's so simple that it's a no-brainer install. I heard about this app from Roy Osherove's recent utilities post. Roy also mentions AutoHotKey, which is an excellent little open source keystroke/scripting app. The cool thing about AutoHotKey is that you can create automation scripts, compile them, and then run them on client machines without installing any software. Labels: tools
While coding this morning, I needed to quickly find an entity object in an array, so I used the generic List's Find method. Entity match = new List<Entity>(someEntityArray).Find( delegate(Entity test) { return test.Id = someId; } ); Later, when I tried to build, I was getting a very unhelpful compiler errors. error CS1502: The best overloaded method match for 'System.Collections.Generic.List.Find(System.Predicate)' has some invalid arguments and error CS1503: Argument '1': cannot convert from 'anonymous method' to 'System.Predicate' These errors didn't make sense to me, but I tried creating a Predicate object, then passing that into the Find method by moving some code around.
Predicate<Entity> pred = delegate(Entity test) { return test.Id = someId; }; Entity match = new List<Entity>(someEntityArray).Find(pred);At this point, I'm getting the compile errors error CS1662: Cannot convert anonymous method block to delegate type 'System.Predicate' because some of the return types in the block are not implicitly convertible to the delegate return type and error CS0029: Cannot implicitly convert type 'long' to 'bool' "Ah, now we're getting somewhere," I thought to myself, "but why would the anonymous method be converting long to bool? D'oh!" I bet a good portion of other developers reading this blog (assuming anyone does) probably noticed the problem at once. The old single equals sign instead of double equals sign in a comparison. Going back to my original code and adding an equals sign compiles fine. Entity match = new List<Entity>(someEntityArray).Find( delegate(Entity test) { return test.Id == someId; } ); This all got me wondering why the compile error was so far off. I did a quick google for the original error message and came across this blog post where Avner Kashtan had a similar problem and he ended up getting feedback from Microsoft that this is the correct behavior, although misleading, and things should be improved with lambda expressions. Labels: c#
Patrick Cauldwell has posted an excellent general purpose manifesto for developers on any project - This I Believe ... the Developer Edition. The post a very nicely condensed list of development guidelines and practices. I think it would be useful for every project to have a manifesto like this for developers to reference and keep everything on track. Labels: methodologies
I was writing some code today for a utility method to format names. You know, one of those functions that you find yourself writing even thought you've probably done it lots of times in the past, but you can't find the previous versions. I got to the part where it returns different values if other values are available, and realized something as I wrote the following code. if (!string.IsNullOrEmpty(lastName)) return lastName; else if (!string.IsNullOrEmpty(firstName)) return firstName; else if (!string.IsNullOrEmpty(middleName)) return middleName; else return string.Empty;
I realized that I could probably condense that into one line if I could chain together the variables with null coalescing operators. "What the hell," I thought, "I'll give it try and see if it compiles." return lastName ?? firstName ?? middleName ?? string.Empty;
Sure enough, it compiles. And it works! It's always a nice feeling to write beautiful code. Labels: c#
The support for extending existing types with custom methods in Orcas is something I've been fairly excited about for a while. Extension methods provide way to inject your static own method into someone else's type, where it will appear as if it was an instance method defined on that type. A Simple ExampleIn many of my projects, I have enumerations decorated with a description attribute and a static method in a utility class which will return the description of an enum value. This provides a way to have a user friendly description of an enum value. Now I can take that method in the utility class, modify it slightly to be an extension method, and have better looking, more intuitive and highly discoverable code. Let's say we have an enumeration of report titles. public enum ReportTitle { [EnumDescription("TPS Report")] TPS, [EnumDescription("Summary Report")] Summary, [EnumDescription("Expense Breakdown Report")] [EnumDescription("Expense Report")] ExpenseBreakdown, Unknown }
My .NET 2.0 utility method to get enum descriptions looks like this: public static string GetEnumDescription(Enum enumValue) { if (enumValue == null) return string.Empty;
Type enumType = enumValue.GetType(); Type descType = typeof(EnumDescriptionAttribute); FieldInfo fi = enumType.GetField(enumValue.ToString()); object[] descAttrs = fi.GetCustomAttributes(descType, false);
// concatenate multiple descriptions string desc = string.Empty; foreach (EnumDescriptionAttribute descAttr in descAttrs) desc += (desc.Length == 0) ? descAttr.Description : ", " + descAttr.Description;
if (desc == string.Empty) desc = enumValue.ToString();
return desc; }
I don't think I really need to show the EnumDescriptionAttribute code or code that gets report titles, because there are no surprised there. As an aside, if anyone wonders why I'm not using System.ComponentModel.DescriptionAttribute, its because that attribute doesn't support multiple decorators on a single type. This example code re-written with Visual Studio Orcas March CTP looks like this: public static string Description(this Enum enumValue) { if (enumValue == null) return string.Empty;
var enumType = enumValue.GetType(); var descType = typeof(EnumDescriptionAttribute); var fi = enumType.GetField(enumValue.ToString()); var descAttrs = fi.GetCustomAttributes(descType, false);
// concatenate multiple descriptions var desc = string.Empty; foreach (EnumDescriptionAttribute descAttr in descAttrs) desc += (desc.Length == 0) ? descAttr.Description : ", " + descAttr.Description;
if (desc == string.Empty) desc = enumValue.ToString();
return desc; }
And the enum value's description is easily found through intellisense:  I can also take it a step further by refactoring my code to include a generic extension method that returns all custom attributes from a value's type, and another that joins an array of strings into one comma delimited string. public static string Description(this Enum e) { var attrs = e.CustomAttributes<Enum, EnumDescriptionAttribute>(); var descs = new List<string>(attrs.Count); attrs.ForEach(a => descs.Add(a.Description)); return descs.Join(); }
public static List<TAttr> CustomAttributes<T, TAttr>(this T obj) where TAttr : System.Attribute { var fi = obj.GetType().GetField(obj.ToString()); var attrs = fi.GetCustomAttributes(typeof(TAttr), false); return new List<TAttr>((TAttr[])attrs); }
public static string Join(this List<string> values) { return values.Join(", "); } public static string Join(this List<string> values, string delimiter) { string result = string.Empty; values.ForEach(v => result += (result.Length == 0) ? v : delimiter + v); return result; }
Of course, the custom attributes method still needs to be refactored to support other types. Useful For More Than Utility MethodsSince extension methods can be used on sealed classes, they could also be used to hide methods from a publicly distributed assembly by putting extension methods in a non-distributed assembly. Of course, you could also accomplish this with a partial class. Sure, there are probably plenty of reasons why this would be a bad idea, but I get hyper over syntax additions, even if they're not really offering anything that you couldn't do before with more mundane code. There seems to be a lot of controversy over whether extension methods are a good practice and should be part of object oriented programming. Some of the reasons I've seen people use to not use extension methods are that they complicate code discoverability, they will make code reviews more difficult, they don't follow object oriented principles, or even that they contradict best practices published previously by Microsoft. I think Scott Wisniewski of the VB Compiler Team does a great job addressing the benefits of extension methods in his introduction to an excellent series of in depth blog posts, which are also a good read to get a VB.NET perspective on the new feature. Labels: betas, c#
|