On Thu, Apr 5, 2012 at 6:51 AM, Otto Moerbeek <o...@drijf.net> wrote: > That sounds like timing bases attacks to guess a username still will work. > > -Otto
First thing I thought when reading your reply: absolute nonsense. With that mindset I really wanted to disprove your suggestion. For this I have set-up two different scenarios: 1.) Local 'attack' without use of getpwnam (plain-vanilla login_yubikey) 2.) Local 'attack' with use of getpwnam (altered version, read: with applied diff) Each scenario was run two times: one time targeting existing users and one time targeting not existing users. I measured the time it took to get a reply (accept / reject) after sending a password. Each test-run was done a couple ten thousand times. I compared data from the two test-runs within each scenario using a simple t-test. For scenario 1, I found that the probability that one can guess that a user exist or not is less than 0,00000014%. For scenario 2 the probability is less than 0.0021%. Albeit the probability is small, it increased four orders in magnitude. In my own opinion I have failed to disprove your suggestion. I now can imagine that somebody who has knowledge on the subject can derive useful information as a result from the alteration to login_yubikey. So, in a nutshell: I guess you are right! >From the different diffs I've send in I learned that code needs to be readable, regexp is a no-no and that the use of getpwnam is probably not a good idea. I changed my first diff to reflect the above learning's. As I am out of alternative ideas: Opinions? / Alternatives? / Comments? Index: login_yubikey.c =================================================================== RCS file: /cvs/src/libexec/login_yubikey/login_yubikey.c,v retrieving revision 1.4 diff -u -p -r1.4 login_yubikey.c --- login_yubikey.c 1 Feb 2012 16:07:28 -0000 1.4 +++ login_yubikey.c 5 Apr 2012 10:53:57 -0000 @@ -165,10 +165,18 @@ main(int argc, char *argv[]) static int clean_string(const char *s) { + int nlim, n = 1; + + nlim = strlen(s); while (*s) { - if (!isalnum(*s) && *s != '-' && *s != '_') + if (n == 1 && !isalnum(*s) && *s != '_') + return (0); + else if (n == nlim && !isalnum(*s) && *s != '_' && *s != '-') + return (0); + else if (!isalnum(*s) && *s != '_' && *s != '-' && *s != '.') return (0); ++s; + ++n; } return (1); }