SSH-Agent and Windows

The Problem

During my day job I use a Windows laptop to make working with a number of .NET projects easier. That said, I’ve not completely abandoned Node as a platform, nor do I wish to leave Bash behind. Ergo, I wind up using msysgit to emulate a Bash-like environment for Windows. To make things even easier, I use ConEmu to provide a tabbed interface around msysgit. The final piece of the problem is that I have multiple git accounts with their own SSH key (one GitHub for Enterprise, and one Github), and each of thse keys has a passphrase.

The naive approach is to just add eval `ssh-agent -s` to the top of my .bashrc file. The Problem is that this requires a separate ssh-add call for every tab, requiring me to enter my passphrase in every tab. This pretty-well defeats any ease-of-use I was originally looking for.

The Solution

The following is a modified form of GitHub’s solution, which surprisingly works perfectly in ConEmu, unchanged. The only change I wanted to make was to automate adding every id_rsa_* SSH key in my ~/.ssh folder.

Enjoy!

# SSH Agent
# Note: ~/.ssh/environment should not be used, as it
#       already has a different purpose in SSH.

env=~/.ssh/agent.env

# Note: Don't bother checking SSH_AGENT_PID. It's not used
#       by SSH itself, and it might even be incorrect
#       (for example, when using agent-forwarding over SSH).

agent_is_running() {
  if [ "$SSH_AUTH_SOCK" ]; then
    # ssh-add returns:
    #   0 = agent running, has keys
    #   1 = agent running, no keys
    #   2 = agent not running
    ssh-add -l >/dev/null 2>&1 || [ $? -eq 1 ]
  else
    false
  fi
}

agent_has_keys() {
  ssh-add -l >/dev/null 2>&1
}

agent_load_env() {
  . "$env" >/dev/null
}

agent_start() {
  (umask 077; ssh-agent >"$env")
  . "$env" >/dev/null
}

add_all_keys() {
  ls ~/.ssh | grep id_rsa[^.]*$ | sed "s:^:`echo ~`/.ssh/:" | xargs -n 1 ssh-add
}

if ! agent_is_running; then
  agent_load_env
fi

# if your keys are not stored in ~/.ssh/id_rsa.pub or ~/.ssh/id_dsa.pub, you'll need
# to paste the proper path after ssh-add
if ! agent_is_running; then
  agent_start
  add_all_keys
elif ! agent_has_keys; then
  add_all_keys
fi

echo `ssh-add -l | wc -l` SSH keys registered.

unset env

Screenshake on Tweet

A fun little bookmarklet I made for @tha_rami and @legobutts. It applies screenshake to Twitter every time you press the Tweet button.

Make It So

  1. Drag this bookmarklet to your bookmarks.
  2. Open Twitter.
  3. Click the bookmarklet.
  4. Tweet away, and enjoy your epic screenshake!

Thanks

Special thanks to the guys over at the Nuclear Throne Wiki. This code is based on theirs, albeit with some improvements.

Test

Want to test it out, but can’t think of anything witty to tweet?

  1. Activate the awesome
  2. Smile.

Geographical Closure

Kiddo,

It was a strange feeling to return to the world I grew up in. After several episodes of completely leaving my world and moving to a new one, taking such a large step backward was anathema to such an extreme defense mechanism. I know I left these places behind to try and bury some version of myself along with it, so exhuming any portion of that past self seemed disagreeable at best.

Nevertheless, Carlisle is the place Jess fell in love with, and I can’t argue with that.

Now, putting Pennsylvania behind me for the second time, I might understand a sliver of God’s grace in bringing me back in the first place: closure. I left a life of lies and disappointments to find a life of fulfillment, honesty, and integrity elsewhere. Coming back to this place meant coming to grips with who I was, forgiving him, and thanking Him for making me who I am now.

Even moreso, coming back meant New Me spending time with Old Friends. As few as I had left to return to, it’s been an incredible blessing to slip back into this world for a few months and experience it with those who either stayed or willfully returned. They’ve shown me a great deal of peace, whether they know it or not. I’m not even certain what words I could use to thank them, the feeling is so immutably personal.

Finally, it’s allowed me to have an extended period of time with my immediate family as New Me, and especially as an “adult”. It feels like most “Millennials” (though it occasionally pains me to admit membership) returned from college and, whether by choice or lack of work, spent time with their immediate families again after getting their diploma.

Ravenous for success, I never returned after Bucknell. I hunted job after job, self-absorbed with career like so many. A return to Penn’s Woods meant returning to bond with my family as a more mature individual, even if a little later than my peers (not to mention my wife) did likewise.

This is my sense of Geographical Closure — the permanent sense of completing the business of growing up. It meant returning to the place I grew up in to return to the act of growing up. More than having children of my own, more than getting married, simply being here, I feel all grown-up now.

Hello (again), world. I’ll see you in Washington.

Perfectly Imperfect Bash

A quick and dirty nerdy reflection on some Perfectly Imperfect Bash I just wrote while exploring the skip-worktree flag in Git:

git ls-files -v | grep 'S ' | xargs -n 1 git update-index --no-skip-worktree

To the uninitiated:

  1. git ls-files -v lists all files in my git workspace, prefixed with a single-letter flag.
  2. grep 'S ' filters based on those flags, looking for any file prefixed with an S. I’ve been messing with these files, and want to revert that flag.
  3. xargs -n 1 runs the final git command once per line.
  4. git update-index --no-skip-worktree performs the actual work of resetting the errant flag.

That boldfaced word in part 3 is the crux of my reflection. Part 4 would actually receive two arguments: the flag and the file itself. Upon brief reflection I asked an all-important question for engineers to ask: “Who cares?” I realized Git would attempt to interact with a file named S, complaining at its non-existence but continuing with the real file anyway. I could spend the additional few minutes doing it the Right Way, but…

Who cares?

Maybe you do. Maybe you find it irresponsible that I’d make Git complain so much. If that sounds like you, here’s your solution.

git ls-files -v | grep 'S ' | xargs -n 1 git update-index --no-skip-worktree 2> /dev/null

You’re welcome. Go forth and keep shipping.

Motivation: “The Gap”

In a moment of Fantastic Inspiration, I was presented with an elegant solution to a problem so many makers have: motivation.

More specifically, a co-bootstrapper and friend was concerned that he felt unmotivated to come home after a day of programming and continue programming on our product. Coincidentally, I’ve been having motivational problems with my day job. In a random moment of inspiration, I decided to see if the motivational issues were the same, coining the issue itself “The Gap”.

The Gap is the distance between the decision to build something and the ability to first see it manifest. There is no set unit or method of measurement for The Gap. It doesn’t need one: with no further explanation, I wager any maker reading this knows what different sizes of Gap feel like. The feeling that occurs when The Gap is “too big” is very personal, both easily identified and very potent.

Your goal as a project leader is to make The Gap both as small and as rewarding to cross as possible. Without belaboring the point too much, I’ll give a handful of example solutions:

  • If it’s an individual project, find a collaborator. They’ll increase the reward of crossing The Gap by sharing in your accomplishments.
  • If it’s an existing project, find a mentor. They’ll shrink The Gap for you: typically, the bulk of The Gap is built up with missing information.
  • If you’re already an expert, find ways to improve the tooling for you and your team. The second-largest material of The Gap comes from bad tooling, especially when said tooling is slow.

The Best Password Database – Your Mind

In the wake of Heartbleed, one particularly interesting side effect kept surfacing: users of Lastpass were encouraged to regenerate all “important” (read: All) passwords. 1Password, on the other hand, announced that they weren’t affected. I think it’s great that these password security options are promoting good practices. That said, OpenSSL’s bug today is Agile’s bug tomorrow. It’s still software, and it’s inevitable for it to become vulnerable someday.

The Solution

I don’t remember where I first heard about the first version of this trick, but it’s possible to make human-memorable, secure passwords from the website or app in question. Taking that one step further, if we build those passwords from a set of easy-to-remember building blocks, we can even write those passwords down!

Here’s how it works. Let’s say we want to make a new password for Facebook (which, according to this great tool, is “either fixed or unaffected”). Since this is the first password we’re making, we’ll first need some building blocks. Let’s make a building block called name. Instead of just being the name, “Facebook”, let’s make it the name reversed, “koobecaf”. To add to that, let’s make a second building block, salt, that’s a constant group of letters: “heartbleed”.

The names of the building blocks can be written down, though their meaning remains secret. In our Password List, then, we’d write:

Facebook = name + salt

Anyone could read that, and never guess the actual password. Not only do they not know what to do with name, but they don’t know what the salt is. Even if they attempted to break the password by brute force, the password is 18 characters long, which is great. According to this tool by Dropbox, the password would take “centuries” to crack. That’s secure enough for me.

Tips

  • Always use at least two building blocks per password.
  • Never use the websites name exactly. Change it somehow. Take only the first six letters, reverse it, translate it into French. Just don’t use the site’s name by itself.
  • Have as few building blocks as possible, since they’re what you actually have to remember.
  • Store your passwords someplace easily accessible. Even though it’s always a bad idea to write passwords down, you’re not writing down the password, just the building blocks needed to figure it out. So write them down on Post-its, put them in a notebook, store them in your Notes app on your phone, whatever it takes.
  • A “salt” like I showed above is highly recommended. They’re easy to remember, and they can add a lot of security to a password.
  • Some websites don’t allow long passwords. In that case, you’ll have to use shorter building blocks.
  • Feel free to throw in other operators for those blocks, too. For example, one of my pre-Heartbleed passwords was ALG + ALT_SALT / 2. That means it was the ALG block, then the first half of the ALT_SALT block.

Example

Here is a sample of my actual password list, albeit pre-Heartbleed. It only uses three building blocks over seven passwords. (The whole list has seven building blocks, half of which are one-offs for weird password restrictions, over 48 passwords.)

AppSumo: ALG + ALT_SALT
BattleNet: ALG + ALT_SALT / 2
Coursera: ALG + SALT
DigitalOcean: ALG + SALT
Evernote: ALG + ALT_SALT
Evolve: ALG
Facebook: ALG + SALT

My “Annual” Snowman, 2014 Edition

Me and My Snowman 2014
My “Annual” Snowman, 2014 Edition.

This is my “annual” snowman for 2014. He’s about 7 feet tall; I’m slightly in front of him. His arms are a bit hard to see, but one goes out to his walking stick, and the other is raised to his left, waving to the passing cars.

Wipe that snow off your shoulder, Mr. Snowman.

Anatomy of a Schoon TODO

In its original Dutch, my nickname, Schoon, means “clean”. Doubly-appropriate, perhaps, that my method of TODO comments be called a “Schoon TODO” by former colleagues. It’s the cleanest I’ve seen.

Quick disclaimer, perhaps: I don’t know this style to be unique, but I don’t know it not to be unique. I’ve never verified either way, so I won’t assert either to be true. Just take this as “the way I do things, and maybe that’s helpful.”

Here’s a sample, simple, real-world pair of TODO comments in code I just wrote (and which prompted this post):

  // TODO(schoon) - Validation.
  // TODO(schoon) - Ensure the appId (at the least) is unique?

To break this down, there are seven important components to these comments:

  1. Indentation – Make sure your comments are aligned with the surrounding code.
  2. Single-line comment – Please, no blocks.
  3. TODO – Not FIXME, not HACK. At best, these mean different things. At worst, these confuse people. For example, I use HACK to indicate something that needs to change without indicating how, and I never use FIXME.
  4. Your name – It should be apparent who can solve this problem, but don’t make us grep the git log to find it was your idea. Own your TODOs.
  5. Punctuation – Whether it’s a dash or not, make it consistent and put some breathing room in your comment.
  6. Details – The most important part of the comment along with the rest of the comment. Provide enough detail to remind yourself what needs to be done: no more, no less. If there are a lot of details, use your bug tracking software. TODOs are for little, immediate notes.
  7. Punctuation – This is almost the most important little detail. A period indicates this is a concrete, sure TODO. A question mark indicates you’re unsure, and more thoughts and discussions should follow.

I wrote both of these in a two-space-indented block of code, and I’m unsure if or how appId needs to be unique. It needs to be properly-formatted as an appId, however, so that validation needs to happen. But that’s enough analysis – go forth and make your TODOs more useful.

Overwhelming Uncertainty

Kiddo,

On a completely different track from my thoughts on Insufficient Uncertainty, today I’m fighting off Overwhelming Uncertainty. Michael Lopp, a.k.a. Rands, introduced me to the concept of “entropy surfing” through his Trickle Theory post. The post is worth a full read, but here’s the ending from this well-written analysis of software development:

Fact is, your world is changing faster than you’ll ever be able to keep up with and you can view that fact from two different perspectives:

1) I believe I can control my world and through an aggressive campaign of task management, personal goals, and a CAN DO attitude, I will succeed in doing the impossible. Go me!

-or-

2) I know there is no controlling the world, but I will fluidly surf the entropy by constantly changing myself.

Surfing entropy takes confidence. This isn’t Tony Robbins confidence, this is a personal confidence you earn by constantly adapting yourself to the impossible.

How different is that feeling from dealing with a serious illness? Granted, a trip to the ER ending in a prescription and a generic diagnosis are nothing compared to, say, cancer. That said, both of those people and more suffer from the same, shared, additional problem: Overwhelming Uncertainty.

More troublesome, perhaps, than the diagnosis or treatments themselves is the intimate understanding that we know very little about how well our body is doing at any given time. Only once sufficient data and observation takes place do we learn anything about it, and when we do – our world changes. Fast.

We’re left with those same two options: foolishly attempt to control the chaos, or confidently surf the entropy.

Personally, if only for a lack of fortitude on my own, my confidence comes from faith. And there are days when I’m securely on my feet, on the board, surfing with the best. Then there’s today, and I’m tossed in the waves. I’ll get back on the board, though, and I pray that when your world changes, you’ll have the confidence to join me on the surf.

Remote Meeting Courtesies

With an increasing prevalence of meetings done over Skype, Hangouts, and similar, I feel that everyone (especially remote workers, but this isn’t specific to folks who primarily work remotely) should know a few basic courtesies involved with this young form of interaction.

In decreasing order of importance:

  1. Mute yourself unless you are speaking. – I know you’re being silent while on the call, and that’s fantastic. The problem is that your computer is picking up the faintest sounds, amplifying them, and sending them to the server anyway. Unless you’re actually trying to speak to the group, use the mute feature of the software. This always reduces the background noise of the call, even if you’re not making any.
  2. Don’t interrupt. – While this may seem like an obvious carry-over from in-person meetings, it’s far nastier over these VOIP services. In-person it’s pretty straightforward to interject and add to a teammates comment, as more nuanced communication such as body language can come to your aid and broadcast your intent. When all you’re left with is your voice (often, the primary video being displayed is the person speaking, so video doesn’t cut it outside of the accompanying voice), it’s extremely difficult to cleanly add to another’s statement without creating noise and frustration. You’re statement is still valid and wanted, but the noisiness of interrupting mid-sentence is not.
  3. Pause often while speaking to let others interject. – Because it’s such a noisy ordeal to interrupt someone while speaking, you should pause between ideas. That way, anyone else wishing to speak can interject and add their own two cents. Going back to the lack of body language, you should treat VOIP meetings as miniature speaking engagements, and the same advice applies: pausing allows the other folks in the meeting time to digest your salient arguments. If Bob abuses his ability to interrupt, most VOIP systems allow you to mute others…
  4. Use the chat for out-of-band conversations. – Continuing the trend of not interrupting, if you have a sufficiently-small or unrelated point to add, consider using the built-in chat feature. A separate, minor discussion can occur and be resolved in the chat while the major discussion occurs over VOIP.
  5. Avoid using chat. – It should go without saying, but abusing the chat feature is distracting and rude. Any time and energy spent in chat is detracting from the person speaking, and is unfair to both that person and their ideas.

The first point is by far the biggest and most important, so I’ll reiterate: Mute yourself any time you’re not addressing the group! Following that rule alone will vastly improve meeting online.

That, or you could just hold meetings like this:

The study and studies of the Schoon(s).