71 lines
1.8 KiB
Plaintext
71 lines
1.8 KiB
Plaintext
|
--- src/consoles.h
|
||
|
+++ src/consoles.h 2011-07-27 11:10:26.620613503 +0000
|
||
|
@@ -39,6 +39,7 @@ struct console {
|
||
|
int fd, id;
|
||
|
#define CON_SERIAL 0x0001
|
||
|
#define CON_NOTTY 0x0002
|
||
|
+#define CON_EIGHTBIT 0x1000
|
||
|
pid_t pid;
|
||
|
struct chardata cp;
|
||
|
struct termios tio;
|
||
|
--- src/sulogin.c
|
||
|
+++ src/sulogin.c 2011-07-27 13:10:16.791925602 +0000
|
||
|
@@ -635,6 +635,7 @@ char *getpasswd(struct console *con)
|
||
|
ptr = &pass[0];
|
||
|
cp->eol = *ptr = '\0';
|
||
|
|
||
|
+ con->flags &= ~CON_EIGHTBIT;
|
||
|
eightbit = ((con->flags & CON_SERIAL) == 0 || (tty.c_cflag & (PARODD|PARENB)) == 0);
|
||
|
while (cp->eol == '\0') {
|
||
|
if (read(fd, &c, 1) < 1) {
|
||
|
@@ -697,6 +698,8 @@ char *getpasswd(struct console *con)
|
||
|
goto quit;
|
||
|
}
|
||
|
*ptr++ = ascval;
|
||
|
+ if (((unsigned char)ascval) & 0x80)
|
||
|
+ con->flags |= CON_EIGHTBIT;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
@@ -839,6 +842,30 @@ void usage(void)
|
||
|
fprintf(stderr, "Usage: sulogin [-e] [-p] [-t timeout] [tty device]\n\r");
|
||
|
}
|
||
|
|
||
|
+/*
|
||
|
+ * Wrapper for blowfish signedness bug (CVE-2011-2483)
|
||
|
+ */
|
||
|
+
|
||
|
+static
|
||
|
+int checkpw(const char *answer, const char *passwd, const struct console *con)
|
||
|
+{
|
||
|
+ char buf[64];
|
||
|
+
|
||
|
+ if (strcmp(crypt(answer, passwd), passwd) == 0)
|
||
|
+ return 1;
|
||
|
+ if (strncmp(passwd, "$2a$", 4) != 0)
|
||
|
+ return 0;
|
||
|
+ if ((con->flags & CON_EIGHTBIT) == 0)
|
||
|
+ return 0;
|
||
|
+ if (strlen(passwd) >= 64)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ strncpy(buf, passwd, 64);
|
||
|
+ buf[2] = 'x';
|
||
|
+
|
||
|
+ return (strcmp(crypt(answer, buf), buf) == 0);
|
||
|
+}
|
||
|
+
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
char *tty = NULL;
|
||
|
@@ -967,8 +994,7 @@ int main(int argc, char **argv)
|
||
|
if ((answer = getpasswd(con)) == NULL)
|
||
|
break;
|
||
|
|
||
|
- if (passwd[0] == '\0' ||
|
||
|
- strcmp(crypt(answer, passwd), passwd) == 0) {
|
||
|
+ if (passwd[0] == '\0' || checkpw(answer, passwd, con)) {
|
||
|
*usemask |= (1<<con->id);
|
||
|
sushell(pwd);
|
||
|
*usemask &= ~(1<<con->id);
|