From 735644766f96181880d8a5ad91454064daa36706 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 3 Aug 2019 10:37:27 -0600 Subject: [PATCH] apps/fsutils/passwd: Handle the improved the format of the /etc/passwd format. It is now a little similar to other systems. --- fsutils/passwd/passwd_append.c | 16 ++++++- fsutils/passwd/passwd_encrypt.c | 3 +- fsutils/passwd/passwd_find.c | 74 ++++++++++++++++++--------------- fsutils/passwd/passwd_update.c | 2 +- include/fsutils/passwd.h | 5 ++- 5 files changed, 60 insertions(+), 40 deletions(-) diff --git a/fsutils/passwd/passwd_append.c b/fsutils/passwd/passwd_append.c index 5209b9fad..5185429ad 100644 --- a/fsutils/passwd/passwd_append.c +++ b/fsutils/passwd/passwd_append.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/fsutils/passwd/passwd_append.c * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -85,7 +85,19 @@ int passwd_append(FAR const char *username, FAR const char *password) return errcode; } - ret = fprintf(stream, "%s %s\n", username, encrypted); + /* The format of the password file is: + * + * user:x:uid:gid:home + * + * Where: + * user: User name + * x: Encrypted password + * uid: User ID (0 for now) + * gid: Group ID (0 for now) + * home: Login directory (/ for now) + */ + + ret = fprintf(stream, "%s:%s:0:0:/\n", username, encrypted); if (ret < 0) { int errcode = errno; diff --git a/fsutils/passwd/passwd_encrypt.c b/fsutils/passwd/passwd_encrypt.c index ef547b7f6..f19e6bc33 100644 --- a/fsutils/passwd/passwd_encrypt.c +++ b/fsutils/passwd/passwd_encrypt.c @@ -51,6 +51,7 @@ /**************************************************************************** * Private Data ****************************************************************************/ + /* This should be better protected */ static uint32_t g_tea_key[4] = @@ -75,7 +76,7 @@ static uint32_t g_tea_key[4] = * binary - 5 bit value * * Returned Value: - * The ASCII base64 character + * The ASCII base64 character. Must not return the field delimiter ':' * ****************************************************************************/ diff --git a/fsutils/passwd/passwd_find.c b/fsutils/passwd/passwd_find.c index c38f37da4..4e737eca1 100644 --- a/fsutils/passwd/passwd_find.c +++ b/fsutils/passwd/passwd_find.c @@ -68,11 +68,10 @@ int passwd_find(FAR const char *username, FAR struct passwd_s *passwd) { FAR char *iobuffer; FAR char *name; - FAR char *src; - FAR char *dest; + FAR char *encrypted; + FAR char *ptr; FILE *stream; off_t offset; - int enclen; int ret; /* Allocate an I/O buffer for the transfer */ @@ -95,6 +94,17 @@ int passwd_find(FAR const char *username, FAR struct passwd_s *passwd) /* Read the password file line by line until the record with the matching * username is found, or until the end of the file is reached. + * + * The format of the password file is: + * + * user:x:uid:gid:home + * + * Where: + * user: User name + * x: Encrypted password + * uid: User ID + * gid: Group ID + * home: Login directory */ offset = 0; @@ -102,38 +112,39 @@ int passwd_find(FAR const char *username, FAR struct passwd_s *passwd) while (fgets(iobuffer, CONFIG_FSUTILS_PASSWD_IOBUFFER_SIZE, stream) != NULL) { - /* Skip over any leading whitespace */ + ptr = iobuffer; + name = ptr; - for (src = iobuffer; *src && isspace((int)*src); src++); - if (*src == '\0') + /* Skip to the end of the name and properly terminate it,. The name + * must be terminated with the field delimiter ':'. + */ + + for (; *ptr != '\0' && *ptr != ':'; ptr++); + if (*ptr == '\0') { /* Bad file format? */ continue; } - name = src; - - /* Skip to the end of the name and properly terminate it */ - - for (; *src && !isspace((int)*src); src++); - if (*src == '\0') - { - /* Bad file format? */ - - continue; - } - - *src++ = '\0'; + *ptr++ = '\0'; /* Check for a username match */ if (strcmp(username, name) == 0) { - /* We have a match, skip over any whitespace after the user name */ + /* We have a match. The encrypted password must immediately + * follow the ':' delimiter. + */ - for (; *src && isspace((int)*src); src++); - if (*src == '\0') + encrypted = ptr; + + /* Skip to the end of the encrypted password and properly + * terminate it. + */ + + for (; *ptr != '\0' && *ptr != ':'; ptr++); + if (*ptr == '\0') { /* Bad file format? */ @@ -141,25 +152,20 @@ int passwd_find(FAR const char *username, FAR struct passwd_s *passwd) break; } + *ptr++ = '\0'; + /* Copy the offset and password into the returned structure */ - passwd->offset = offset; - dest = passwd->encrypted; - enclen = 0; - - while (*src && !isspace((int)*src) && enclen < MAX_ENCRYPTED) - { - *dest++ = *src++; - enclen++; - } - - if (enclen >= MAX_ENCRYPTED) + if (strlen(encrypted) >= MAX_ENCRYPTED) { ret = -E2BIG; break; } - *dest = '\0'; + passwd->offset = offset; + strncpy(passwd->encrypted, encrypted, MAX_ENCRYPTED); + passwd->encrypted[MAX_ENCRYPTED] = '\0'; + ret = OK; break; } diff --git a/fsutils/passwd/passwd_update.c b/fsutils/passwd/passwd_update.c index 058e19da5..7dde170ea 100644 --- a/fsutils/passwd/passwd_update.c +++ b/fsutils/passwd/passwd_update.c @@ -50,7 +50,7 @@ * Name: passwd_update * * Description: - * Change a new user to the /etc/passwd file. If the user does not exist, + * Change a user in the /etc/passwd file. If the user does not exist, * then this function will fail. * * Input Parameters: diff --git a/include/fsutils/passwd.h b/include/fsutils/passwd.h index e92d4f3d6..d72d2bbc0 100644 --- a/include/fsutils/passwd.h +++ b/include/fsutils/passwd.h @@ -1,7 +1,7 @@ /**************************************************************************** * apps/include/fsutils/passwd.h * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ int passwd_deluser(FAR const char *username); * Name: passwd_update * * Description: - * Change a new user to the /etc/passwd file. If the user does not exist, + * Change a user in the /etc/passwd file. If the user does not exist, * then this function will fail. * * Input Parameters: @@ -113,6 +113,7 @@ int passwd_deluser(FAR const char *username); ****************************************************************************/ int passwd_update(FAR const char *username, FAR const char *password); + #endif /* CONFIG_FS_WRITABLE && CONFIG_FSUTILS_PASSWD_READONLY */ /****************************************************************************