Friday, December 22, 2017

It's that time again

I won't go off on a rant about how mandatory password change policies are bad for users at best and actually erode security at worst. Or that NIST now recommends against mandatory password changes.

I'm not going to do that because I'm either preaching to the choir or shouting at the sea, demanding the tide stay out.  I submit that mandatory password change policies are the climate change of IT departments.  There are going to be people and organizations that, in the words of Captain, "you just can't reach".

For quite a while now I've been using completely random passwords with high entropy.  I have a few that unlock my keyrings, those I have committed to memory and are single-purpose (that is, I never use the same password for more than one keyring).  The others, though, I don't even bother trying to remember.  I use programs such as apg or KeePassX to create passwords for everything, each of them are again single-use, all of which look like a crypted password at a first glance.  For example, one I generated yesterday as a joke was x+KQ$zy^lqv<?;XD.3se9.  I'm guessing if you were trying to decyper a hash of my password and got that output, you wouldn't immediately think you'd been successful.

There's a problem with this approach, though.  KeePass and all of its variants (like the one I use on Android) are great for managing and providing those passwords to me when I need to enter them, but occasionally I still need to access those passwords without the benefit of a browser plugin, for example.

The worst of these examples is mutt.  I cannot imagine a scenario where I would willingly give up mutt as my primary means of using email, but it's really a pain in the butt to have it work with mandatory password changes.  I could just say to heck with it and use a password scheme for my email that is easy for me to remember and sticks to the specific rules of any password change policy, but that actually makes things a lot worse because now I'm doing exactly what all those articles I linked above say is the problem with mandatory password change policies.

Turns out, though, that mutt can do something pretty neat when it comes to saved passwords:

set imap_user="jjm"
set imap_pass=`/usr/bin/gpg --decrypt $HOME/passwd.gpg 2>/dev/null`

Which means now I store my passwords in a file (in my home directory in the example above, for the sake of keeping the example simple) that is encrypted with a password or passphrase of my chosing.  Of course, this is just another keyring, so I need to commit one more password to memory, but now any time I am required to change my password on that account, I can set it to a new password that has high entropy and is completely unrelated to any previous password I've ever used and I don't need to remember it.

How do I update that with a new password?  Easy:
$ echo "x+KQ$zy^lqv<?;XD.3se9" | gpg -c > passwd.gpg

So in this scenario the new password never even lands on my disk in an un-encrypted state.  Finally, there is a bit of a case for keeping old passwords around, so I can accomplish that with:
$ (gpg --decrypt passwd.gpg  2>/dev/null && gpg --decrypt old-passwds.gpg 2>/dev/null ) | gpg -c > old-passwds.gpg

Thus, old-passwds.gpg is an accumulation of previous passwords I've used for this account, also encrypted, never stored as cleartext on my disk, and the worst case is I need to remember two new keyring passwords or passphrases.  I think that's a pretty good compromise for complying with a mandatory password change policy that is widely accepted to be a bad idea.

Wednesday, January 18, 2017

Hello patch-id, my old friend.

I started off with a series of patches that I'd cherry-picked out of one branch into my current branch. All seemed good, so I was ready to merge them. Except something happened to the upstream and I was unable to actually push my commits. Now, though, I'm presented with an interesting mess. I have my own series that I know I've tested, the branch from which I've cherry-picked them has a ton of unrelated (and untested by me) commits and I want to enlist someone's help with getting these dozen commits merged into the main development branch.

How do I do this?

Well, I thought, first off we'll ensure my tree is clean.

   # git fetch --all --tags
   # git status
   On branch master
   Your branch is ahead of 'oe/master' by 12 commits.
     (use "git push" to publish your local commits)

   nothing to commit, working directory clean

All's good. Next, let's go ensure all of our commits are in the upstream branch, trusting the summary line to be good enough as a first indicator because there's no way I would've touched the summary in my tree when cherry-picking or amending or anything. The only failure would be if something in my tree has subsequently gone missing from the up-stream -next tree. And given this is a -next tree and not intended to be fast-forward, this seems like a reasonable thing to check.

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --oneline --grep={} oe/master-next

Works pretty well it seems. Numbers check?

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --oneline --grep={} oe/master-next | wc -l

Yup. Okay, now we have essentially two lists of commit ids. My branch and the upstream branch where I picked from. Let's make sure those commits are basically the same.  We'll do this with git-patch-id, a tool that, in ancient times, I created by hand by formatting patches out of my tree and then doing an md5 (it was ancient times, leave me alone) of the patches without headers.  Apparently I wasn't the only one doing this sort of crime, because now git has something very much like that built right in.  Truly we live in an age of wonders.

Moving on.

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} oe/master-next | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' > upstream.txt

   # git log --pretty="format:'%s'" oe/master..HEAD| \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' > local.txt

So, with a dozen patches, it's easy enough to just visually compare them, but I figured I'd go the one extra step and automate comparison of the lists as well.

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} oe/master-next | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' | cut -f1 -d' ' \
   > > upstream.txt

   # git log --pretty="format:'%s'" oe/master..HEAD | \
   > xargs -n1 -i git log --pretty="format:%H " --grep={} | \
   > xargs -n1 -i sh -c 'git show {} | git patch-id' | cut -f1 -d' ' \
   > > local.txt

   # diff upstream.txt local.txt

And in my case this revealed that I had one commit that was substantially different, since patch-id returned differences. On closer examination of the commit ids in each tree it was obvious that I'd made a significant change based on a discussion with the author and I'd said I would make the discussed change in place rather than requesting a new patch. So ultimately this was all worth it.