A note first off, particularly as this is cryptography-related: I have no idea
what I'm doing. Do not trust my code on my say so, which I'm not giving anyway.
That said, it works (TM).
There is apparently a new blowfish format supported by bcrypt, denoted by the
prefix $2b where the previous version used $2a. user(8) checks the length of
the crypted password supplied to the -p option but does not understand the new
($2b) format:
# usermod -p "$( echo secret | encrypt )" root
usermod: Invalid password:
`$2b$08$NTiZ2vg8UZqhbloFaJLqMOh9mvOVA8eh4upVCJGvVPGALINZje1I2'
The included patch assumes that the opaque crypted string for form b follows
the same rules as form a, which held true in my solitary test.
--- user.c 2014-07-20 04:38:40.000000000 +0300
+++ user.c.new 2015-02-24 17:33:06.049031636 +0200
@@ -876,12 +876,14 @@
int length; /* length of password */
} passwd_type_t;
-#define BLF "$2a"
+#define BLFa "$2a"
+#define BLFb "$2b"
#define MD5 "$1"
#define DES ""
static passwd_type_t passwd_types[] = {
- { BLF, 3, 54 }, /* Blowfish */
+ { BLFa, 3, 54 }, /* Blowfish (type a) */
+ { BLFb, 3, 54 }, /* Blowfish (type b) */
{ MD5, 2, 34 }, /* MD5 */
{ DES, 0, DES_Len }, /* standard DES */
{ NULL, -1, -1 } /* none - terminate search */
@@ -897,7 +899,7 @@
if (strncmp(newpasswd, pwtp->type, pwtp->desc_length) == 0) {
char *p;
- if (strcmp(pwtp->type, BLF) != 0) {
+ if (strcmp(pwtp->type, BLFa) != 0 && strcmp(pwtp->type, BLFb) != 0) {
return strlen(newpasswd) == pwtp->length;
}
/* Skip first three `$'. */