From owner-freebsd-audit Sun Aug 11 9:58:51 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 197F437B400 for ; Sun, 11 Aug 2002 09:58:42 -0700 (PDT) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id 3FCA143E5E for ; Sun, 11 Aug 2002 09:58:41 -0700 (PDT) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 11 Aug 2002 17:58:40 +0100 (BST) To: audit@freebsd.org Subject: pw(1) support for pre-encrypted passwords Date: Sun, 11 Aug 2002 17:58:40 +0100 From: Ian Dowse Message-ID: <200208111758.aa74510@salmon.maths.tcd.ie> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG The following patch adds support to pw(1) for specifying an encrypted password to be added directly to the password database. It adds a new option, "-H" that works just like the existing "-h" option (the password is read from a user-specified file descriptor) except that pw(1) does not pass the string through crypt(). This is partially based on the patch in PR bin/22033, but is hopefully more consistent with existing features (the proposed patch used "-h -w crypt" instead of "-H fd", but -w and -h used to be mutually exclusive in practice). Index: pw.8 =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw.8,v retrieving revision 1.31 diff -u -r1.31 pw.8 --- pw.8 14 Jul 2002 14:45:10 -0000 1.31 +++ pw.8 11 Aug 2002 00:26:34 -0000 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD: src/usr.sbin/pw/pw.8,v 1.31 2002/07/14 14:45:10 charnier Exp $ .\" -.Dd December 9, 1996 +.Dd August 10, 2002 .Dt PW 8 .Os .Sh NAME @@ -51,7 +51,7 @@ .Op Fl s Ar shell .Op Fl o .Op Fl L Ar class -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -101,7 +101,7 @@ .Op Fl w Ar method .Op Fl s Ar shell .Op Fl L Ar class -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -130,7 +130,7 @@ .Op Fl g Ar gid .Op Fl M Ar members .Op Fl o -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -152,7 +152,7 @@ .Op Fl l Ar name .Op Fl M Ar members .Op Fl m Ar newmembers -.Op Fl h Ar fd +.Op Fl h Ar fd | Fl H Ar fd .Op Fl N .Op Fl P .Op Fl Y @@ -508,6 +508,12 @@ then the password will be set to .Ql \&* , rendering the account inaccessible via password-based login. +.It Fl H Ar fd +Read an encrypted password string from the specified file descriptor. +This is like +.Fl h , +but the password should be supplied already encrypted in a form +suitable for writing directly to the password database. .El .Pp It is possible to use Index: pw.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw.c,v retrieving revision 1.26 diff -u -r1.26 pw.c --- pw.c 9 Jul 2001 09:24:01 -0000 1.26 +++ pw.c 11 Aug 2002 00:30:30 -0000 @@ -106,18 +106,18 @@ static const char *opts[W_NUM][M_NUM] = { { /* user */ - "V:C:qn:u:c:d:e:p:g:G:mk:s:oL:i:w:h:Db:NPy:Y", + "V:C:qn:u:c:d:e:p:g:G:mk:s:oL:i:w:h:H:Db:NPy:Y", "V:C:qn:u:rY", - "V:C:qn:u:c:d:e:p:g:G:ml:k:s:w:L:h:FNPY", + "V:C:qn:u:c:d:e:p:g:G:ml:k:s:w:L:h:H:FNPY", "V:C:qn:u:FPa7", "V:C:q", "V:C:q", "V:C:q" }, { /* grp */ - "V:C:qn:g:h:M:pNPY", + "V:C:qn:g:h:H:M:pNPY", "V:C:qn:g:Y", - "V:C:qn:g:l:h:FM:m:NPY", + "V:C:qn:g:l:h:H:FM:m:NPY", "V:C:qn:g:FPa", "V:C:q" } @@ -315,6 +315,7 @@ "\t-o duplicate uid ok\n" "\t-L class user class\n" "\t-h fd read password on fd\n" + "\t-H fd read encrypted password on fd\n" "\t-Y update NIS maps\n" "\t-N no update\n" " Setting defaults:\n" @@ -357,6 +358,7 @@ "\t-s shell name of login shell\n" "\t-w method set new password using method\n" "\t-h fd read password on fd\n" + "\t-H fd read encrypted password on fd\n" "\t-Y update NIS maps\n" "\t-N no update\n", "usage: pw usershow [uid|name] [switches]\n" Index: pw_group.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw_group.c,v retrieving revision 1.13 diff -u -r1.13 pw_group.c --- pw_group.c 22 Jun 2000 16:48:41 -0000 1.13 +++ pw_group.c 11 Aug 2002 00:09:53 -0000 @@ -158,11 +158,13 @@ * software. */ - if ((arg = getarg(args, 'h')) != NULL) { + if ((arg = getarg(args, 'h')) != NULL || + (arg = getarg(args, 'H')) != NULL) { if (strcmp(arg->val, "-") == 0) grp->gr_passwd = "*"; /* No access */ else { int fd = atoi(arg->val); + int precrypt = (arg->ch == 'H'); int b; int istty = isatty(fd); struct termios t; @@ -196,7 +198,12 @@ *p = '\0'; if (!*line) errx(EX_DATAERR, "empty password read on file descriptor %d", fd); - grp->gr_passwd = pw_pwcrypt(line); + if (precrypt) { + if (strchr(line, ':') != NULL) + return EX_DATAERR; + grp->gr_passwd = line; + } else + grp->gr_passwd = pw_pwcrypt(line); } } Index: pw_user.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/usr.sbin/pw/pw_user.c,v retrieving revision 1.51 diff -u -r1.51 pw_user.c --- pw_user.c 24 Jun 2002 11:33:17 -0000 1.51 +++ pw_user.c 11 Aug 2002 02:39:47 -0000 @@ -86,6 +86,7 @@ * -L class user class * -l name new login name * -h fd password filehandle + * -H fd encrypted password filehandle * -F force print or add * Setting defaults: * -D set user defaults @@ -544,7 +545,8 @@ warnx("WARNING: home `%s' is not a directory", pwd->pw_dir); } - if ((arg = getarg(args, 'w')) != NULL && getarg(args, 'h') == NULL) { + if ((arg = getarg(args, 'w')) != NULL && + getarg(args, 'h') == NULL && getarg(args, 'H') == NULL) { login_cap_t *lc; lc = login_getpwclass(pwd); @@ -602,7 +604,8 @@ } } - if ((arg = getarg(args, 'h')) != NULL) { + if ((arg = getarg(args, 'h')) != NULL || + (arg = getarg(args, 'H')) != NULL) { if (strcmp(arg->val, "-") == 0) { if (!pwd->pw_passwd || *pwd->pw_passwd != '*') { pwd->pw_passwd = "*"; /* No access */ @@ -610,6 +613,7 @@ } } else { int fd = atoi(arg->val); + int precrypt = (arg->ch == 'H'); int b; int istty = isatty(fd); struct termios t; @@ -624,7 +628,10 @@ /* Disable echo */ n.c_lflag &= ~(ECHO); tcsetattr(fd, TCSANOW, &n); - printf("%sassword for user %s:", (mode == M_UPDATE) ? "New p" : "P", pwd->pw_name); + printf("%s%spassword for user %s:", + (mode == M_UPDATE) ? "new " : "", + precrypt ? "encrypted " : "", + pwd->pw_name); fflush(stdout); } } @@ -635,7 +642,8 @@ fflush(stdout); } if (b < 0) { - warn("-h file descriptor"); + warn("-%c file descriptor", precrypt ? 'H' : + 'h'); return EX_IOERR; } line[b] = '\0'; @@ -643,12 +651,18 @@ *p = '\0'; if (!*line) errx(EX_DATAERR, "empty password read on file descriptor %d", fd); - lc = login_getpwclass(pwd); - if (lc == NULL || - login_setcryptfmt(lc, "md5", NULL) == NULL) - warn("setting crypt(3) format"); - login_close(lc); - pwd->pw_passwd = pw_pwcrypt(line); + if (precrypt) { + if (strchr(line, ':') != NULL) + return EX_DATAERR; + pwd->pw_passwd = line; + } else { + lc = login_getpwclass(pwd); + if (lc == NULL || + login_setcryptfmt(lc, "md5", NULL) == NULL) + warn("setting crypt(3) format"); + login_close(lc); + pwd->pw_passwd = pw_pwcrypt(line); + } edited = 1; } } @@ -1087,7 +1101,8 @@ /* * We give this information back to the user */ - if (getarg(args, 'h') == NULL && getarg(args, 'N') == NULL) { + if (getarg(args, 'h') == NULL && getarg(args, 'H') == NULL && + getarg(args, 'N') == NULL) { if (isatty(STDOUT_FILENO)) printf("Password for '%s' is: ", user); printf("%s\n", pwbuf); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message