<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">I wrote the below ruby script myself to test all my passwords against the same service.</p>
<p dir="auto">It’s tested on macOS, two of my passwords had been breached, both for last.fm.</p>
<p dir="auto">I haven’t used the service in ages, but wanted to update my passwords nonetheless.</p>
<p dir="auto">The last.fm breach was in March of 2012, so I expected both passwords to have been disabled.</p>
<p dir="auto">I login to last.fm, no problem, and no info box that asks me to update password.</p>
<p dir="auto">I then go ahead to update my password. I use apg to generate a random password.</p>
<p dir="auto">Lo and behold, last.fm tells me my new password is too weak and I should pick another, LMFAO!</p>
<pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px; color:black" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7"><span style="color: #888888">#!/usr/bin/env ruby</span>
<span style="color: #007020">require</span> <span style="background-color: #fff0f0">'digest'</span>
<span style="color: #007020">require</span> <span style="background-color: #fff0f0">'shellwords'</span>
<span style="color: #003366; font-weight: bold">PASSWORD_STORE_DIR</span> <span style="color: #333333">=</span> <span style="color: #003366; font-weight: bold">ENV</span><span style="color: #333333">[</span><span style="background-color: #fff0f0">'PASSWORD_STORE_DIR'</span><span style="color: #333333">]</span> <span style="color: #333333">||</span> <span style="color: #003366; font-weight: bold">File</span><span style="color: #333333">.</span>expand_path(<span style="background-color: #fff0f0">'~/.password-store'</span>)
<span style="color: #003366; font-weight: bold">Dir</span><span style="color: #333333">.</span>chdir(<span style="color: #003366; font-weight: bold">PASSWORD_STORE_DIR</span>) <span style="color: #008800; font-weight: bold">do</span>
<span style="color: #003366; font-weight: bold">Dir</span><span style="color: #333333">.</span>glob(<span style="background-color: #fff0f0">'**/*.gpg'</span>) <span style="color: #008800; font-weight: bold">do</span> <span style="color: #333333">|</span>file<span style="color: #333333">|</span>
path <span style="color: #333333">=</span> <span style="background-color: #fff0f0">"</span><span style="background-color: #eeeeee">#{</span><span style="color: #003366; font-weight: bold">PASSWORD_STORE_DIR</span><span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0">/</span><span style="background-color: #eeeeee">#{</span>file<span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0">"</span>
pass <span style="color: #333333">=</span> <span style="color: #DD2200; background-color: #fff0f0">%x{ gpg -d </span><span style="background-color: #eeeeee">#{</span>path<span style="color: #333333">.</span>shellescape<span style="background-color: #eeeeee">}</span><span style="color: #DD2200; background-color: #fff0f0"> 2>/dev/null | head -n1 }</span><span style="color: #333333">.</span>chomp
<span style="color: #007020">hash</span> <span style="color: #333333">=</span> <span style="color: #003366; font-weight: bold">Digest</span><span style="color: #333333">::</span><span style="color: #003366; font-weight: bold">SHA1</span><span style="color: #333333">.</span>hexdigest(pass)<span style="color: #333333">.</span>upcase
prefix, suffix <span style="color: #333333">=</span> <span style="color: #007020">hash</span><span style="color: #333333">[</span><span style="color: #0000DD; font-weight: bold">0</span><span style="color: #333333">..</span><span style="color: #0000DD; font-weight: bold">4</span><span style="color: #333333">]</span>, <span style="color: #007020">hash</span><span style="color: #333333">[</span><span style="color: #0000DD; font-weight: bold">5</span><span style="color: #333333">..</span><span style="color: #0000DD; font-weight: bold">39</span><span style="color: #333333">]</span>
url <span style="color: #333333">=</span> <span style="background-color: #fff0f0">"https://api.pwnedpasswords.com/range/</span><span style="background-color: #eeeeee">#{</span>prefix<span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0">"</span>
response <span style="color: #333333">=</span> <span style="color: #DD2200; background-color: #fff0f0">%x{ curl -sL </span><span style="background-color: #eeeeee">#{</span>url<span style="color: #333333">.</span>shellescape<span style="background-color: #eeeeee">}</span><span style="color: #DD2200; background-color: #fff0f0">|grep </span><span style="background-color: #eeeeee">#{</span>suffix<span style="color: #333333">.</span>shellescape<span style="background-color: #eeeeee">}</span><span style="color: #DD2200; background-color: #fff0f0"> }</span>
<span style="color: #008800; font-weight: bold">if</span> <span style="color: #dd7700; font-weight: bold">$?</span><span style="color: #333333">.</span>exitstatus <span style="color: #333333">==</span> <span style="color: #0000DD; font-weight: bold">0</span>
count <span style="color: #333333">=</span> response<span style="color: #333333">.</span>chomp<span style="color: #333333">.</span>split(<span style="background-color: #fff0f0">':'</span>)<span style="color: #333333">[</span><span style="color: #0000DD; font-weight: bold">1</span><span style="color: #333333">]</span>
dir, <span style="color: #007020">name</span> <span style="color: #333333">=</span> <span style="color: #003366; font-weight: bold">File</span><span style="color: #333333">.</span>dirname(file), <span style="color: #003366; font-weight: bold">File</span><span style="color: #333333">.</span>basename(file, <span style="background-color: #fff0f0">'.gpg'</span>)
subpath <span style="color: #333333">=</span> dir <span style="color: #333333">==</span> <span style="background-color: #fff0f0">'.'</span> ? <span style="color: #007020">name</span> : <span style="background-color: #fff0f0">"</span><span style="background-color: #eeeeee">#{</span>dir<span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0">/</span><span style="background-color: #eeeeee">#{</span><span style="color: #007020">name</span><span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0">"</span>
<span style="color: #007020">puts</span> <span style="background-color: #fff0f0">"</span><span style="background-color: #eeeeee">#{</span>count<span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0"> leaks of your password (‘</span><span style="background-color: #eeeeee">#{</span>pass<span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0">’) for </span><span style="background-color: #eeeeee">#{</span>subpath<span style="background-color: #eeeeee">}</span><span style="background-color: #fff0f0">"</span>
<span style="color: #008800; font-weight: bold">end</span>
<span style="color: #008800; font-weight: bold">end</span>
<span style="color: #008800; font-weight: bold">end</span>
</code></pre>
</div>
</div>
</body>
</html>