From 04e607f9ab674c8dbbf27ea8bb59158178a72f69 Mon Sep 17 00:00:00 2001 From: nuvious Date: Mon, 4 Apr 2022 09:16:36 -0400 Subject: [PATCH] Swapped the user and global (#27) * Swapped the user and global run order per issue #21 intent. * Forgot to pull main becore starting. Updated version, changelog, spelling pass on all files, and linted with clang-tidy. * Removed dockerfile inadvertently comitted to repo. * Fixed a minor grammar issue and nit-picked line lengths. --- CHANGELOG.md | 62 ++++++++++++++++++------------- README.md | 77 +++++++++++++++++++++++++-------------- docs/Contributing.md | 29 ++++++++++----- docs/examples/Pushover.md | 21 +++++++---- src/duress.c | 42 +++++++++++++-------- src/duress.h | 2 + src/duress_sign.c | 6 +-- src/pam_test.c | 2 +- src/util.c | 16 +++++--- src/util.h | 2 +- src/version.h | 6 +-- 11 files changed, 166 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a333b0..e02924a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,27 +1,37 @@ # Changelog - - 1.0.0 - - Initial commit of prototype tested on Debian 10. - - 1.0.1 - - Fixed some potential memory leaks, linted, and adjusted documentation. - - 1.1.0 - - Fixed privilege escalation vulnerability that could allow an unprivileged user to run commands as root. - - 1.1.1 - - OSX support and makefile improvements contributed by [cormacrelf](https://github.com/cormacrelf). - - 1.1.2 - - Fixed issue #11; error when running scripts under /etc/duress.d resulting in account unavailable error. - - Fixed issue #10; documentation or pushover script. - - Added link to demo video. - - Removed unnecessary casts for malloc calls. - - Created dbg_log wrapper function to clean up DEBUG compile flag use. - - 1.1.3 - - Fixed privilege escalation issue #16 [reported by wowaname](https://news.ycombinator.com/item?id=28276200) from Hacker News. - - Redirected output of all scripts/binaries to /dev/null by convention. - - 1.1.4 - - Memory leak resolved by [Jürgen Hötzel on github](https://github.com/juergenhoetzel). - - 1.1.5 - - Makefile improvements by [Prateek Ganguli on github](https://github.com/pganguli). Debug build path now added. - - 1.1.6 - - Removal of unnecessary intermediate shell. Contribution by [Jürgen Hötzel on github](https://github.com/juergenhoetzel). - - Debug builds will not redirect output of stderr and stdout to /dev/null by default to support testing/debugging. - - 1.1.7 - - Removal of exit statements; replaced with NULL to preven the PAM application exiting. Contribution by [Jürgen Hötzel on github](https://github.com/juergenhoetzel). + +- 2.0.0 + - **BREAKING CHANGE:** Changed run order of scripts to run user scripts first and system scripts after. This enables + the possibility of uninstalling pam-duress as a system level operation. + - Linted with clang-tidy. No linter errors in files. + - Changed outputs of errno to strerror(errno). + - General spelling pass. +- 1.1.7 + - Removal of exit statements; replaced with NULL to prevent the PAM application exiting. Contribution by + [Jürgen Hötzel on github](https://github.com/juergenhoetzel). +- 1.1.6 + - Removal of unnecessary intermediate shell. Contribution by + [Jürgen Hötzel on github](https://github.com/juergenhoetzel). + - Debug builds will not redirect output of stderr and stdout to /dev/null by default to support testing/debugging. +- 1.1.5 + - Makefile improvements by [Prateek Ganguli on github](https://github.com/pganguli). Debug build path now added. +- 1.1.4 + - Memory leak resolved by [Jürgen Hötzel on github](https://github.com/juergenhoetzel). +- 1.1.3 + - Fixed privilege escalation issue #16 [reported by wowaname](https://news.ycombinator.com/item?id=28276200) from + Hacker News. + - Redirected output of all scripts/binaries to /dev/null by convention. +- 1.1.2 + - Fixed issue #11; error when running scripts under /etc/duress.d resulting in account unavailable error. + - Fixed issue #10; documentation or pushover script. + - Added link to demo video. + - Removed unnecessary casts for malloc calls. + - Created dbg_log wrapper function to clean up DEBUG compile flag use. +- 1.1.1 + - OSX support and makefile improvements contributed by [cormacrelf](https://github.com/cormacrelf). +- 1.1.0 + - Fixed privilege escalation vulnerability that could allow an unprivileged user to run commands as root. +- 1.0.1 + - Fixed some potential memory leaks, linted, and adjusted documentation. +- 1.0.0 + - Initial commit of prototype tested on Debian 10. diff --git a/README.md b/README.md index a3dca23..4ca183c 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,24 @@ # Intro -The PAM Duress is a module designed to allow users to generate 'duress' passwords that when used in place of their normal password will execute arbitrary scripts. +The PAM Duress is a module designed to allow users to generate 'duress' passwords that when used in place of their +normal password will execute arbitrary scripts. -This functionality could be used to allow someone pressed to give a password under coercion to provide a password that grants access but in the background runs scripts to clean up sensitive data, close connections to other networks to limit lateral movement, and/or to send off a notification or alert (potentially one with detailed information like location, visible wifi hotspots, a picture from the camera, a link to a stream from the microphone, etc). You could even spawn a process to remove the pam_duress module so the threat actor won't be able to see if the duress module was available. +This functionality could be used to allow someone pressed to give a password under coercion to provide a password that +grants access but in the background runs scripts to clean up sensitive data, close connections to other networks to +limit lateral movement, and/or to send off a notification or alert (potentially one with detailed information like +location, visible wifi hot-spots, a picture from the camera, a link to a stream from the microphone, etc). You could +even spawn a process to remove the pam_duress module so the threat actor won't be able to see if the duress module was +available. -This is transparent to the person coercing the password from the user as the duress password will grant authentication and drop to the user's shell. +This is transparent to the person coercing the password from the user as the duress password will grant authentication +and drop to the user's shell. -Duress scripts can be generated on an individual user basis or generated globally. Users can also re-use global duress passwords to sign their own duress scripts (rare instance where this could actually be useful from a security perspective). +Duress scripts can be generated on an individual user basis or generated globally. Users can also re-use global duress +passwords to sign their own duress scripts (rare instance where this could actually be useful from a security +perspective). -Contributions to this project are more than welcome; refer to our guidance on making contributions [here](docs/Contributing.md). +Contributions to this project are more than welcome; refer to our guidance on making contributions +[here](docs/Contributing.md). ## Demo @@ -44,14 +54,16 @@ sudo make install ## Configuration -Configuration of the duress module is split into two different configuration directories. After installation, you'll need to manually create both of them. +Configuration of the duress module is split into two different configuration directories. After installation, you'll +need to manually create both of them. ```bash mkdir -p ~/.duress # Local duress scripts. sudo mkdir -p /etc/duress.d # Global Duress scripts. ``` -After creating the directories you can create script and put them in these directories. To assign a password to execute a particular script you use the duress_sign to create a combination password hash and integrity hash for the script. +After creating the directories you can create script and put them in these directories. To assign a password to execute +a particular script you use the duress_sign to create a combination password hash and integrity hash for the script. ```bash $> duress_sign ~/.duress/delete_workspace.sh @@ -70,11 +82,15 @@ drwxr-xr-x 8 user user 4096 Aug 20 15:11 .. **NOTE:** Scripts will only execute with permission masks of 500, 540, or 550 -**NOTE:** User generated duress scripts are only run when they attempt to log in AND use a duress password that one of their scripts is signed with. If user Jill signs their scripts with the same password as a global script, when they use it the global scripts will run, followed by Jill's duress scripts, but Bob, Jane, or Dan's scripts will not be run even if they also re-used the same duress scripts. +**NOTE:** User generated duress scripts are only run when they attempt to log in AND use a duress password that one of +their scripts is signed with. If user Jill signs their scripts with the same password as a global script, when they use +it the global scripts will run, followed by Jill's duress scripts, but Bob, Jane, or Dan's scripts will not be run even +if they also re-used the same duress scripts. ## PAM Configuration Modify /etc/pam.d/common-auth from the following defaults: + ```bash auth [success=1 default=ignore] pam_unix.so @@ -92,24 +108,30 @@ auth requisite pam_deny.so ``` ### Order of Operations Normal Password - - User enters their standard username and password. - - pam_unix.o confirms them and returns PAM_SUCESS and skips 2 past pam_deny.o. + +- User enters their standard username and password. +- pam_unix.o confirms them and returns PAM_SUCESS and skips 2 past pam_deny.o. ### Order of Operations Duress Password - - The pam_unix.o module first checks standard username and password, but since the duress password is not the users actual password it fails resulting in a default behavior of 'ignore' per the configuration. - - PAM then applies the username/password to pam_duress.so which: - - Enumerates files in /etc/duress.d/ - - Checks for files that have matching .sha256 extensions - - Hashes the provided password salted with the sha256 hash of the file and compares it with the one stored in the .sha256 extension file - - If the hashes match, the script is executed via: - - `export PAMUSER=[USERNAME]; /bin/sh [FILE]` for /etc/duress.d scripts (run as root). - - `export PAMUSER=[USERNAME]; su - [USERNAME] -c "/bin/sh [FILE]"` for ~/.duress scripts (run as the user). - - NOTE: PAMUSER is set so global duress scripts can specify the account flagging duress. - - Process is repeated for all files in ~/.duress/ for the user attempting to log in. - - Finally if ANY script is run, PAM_SUCCESS is return. Otherwise PAM_IGNORE is returned. - - If PAM_SUCESS is returned PAM will skip 1 and move past pam_deny.o to continue the pam module processes, eventually dropping to an authenticated shell. Otherwise the default 'ignore' behavior is honored moving to pam_deny.o, resulting in a failed authentication. - -![Simple Flow Diagram](docs/img/diagram.png "Simple Flow Diagra") + +- The pam_unix.o module first checks standard username and password, but since the duress password is not the users + actual password it fails resulting in a default behavior of 'ignore' per the configuration. +- PAM then applies the username/password to pam_duress.so which: + - Enumerates files in /etc/duress.d/ + - Checks for files that have matching .sha256 extensions + - Hashes the provided password salted with the sha256 hash of the file and compares it with the one stored in the + .sha256 extension file + - If the hashes match, the script is executed via: + - `export PAMUSER=[USERNAME]; /bin/sh [FILE]` for /etc/duress.d scripts (run as root). + - `export PAMUSER=[USERNAME]; su - [USERNAME] -c "/bin/sh [FILE]"` for ~/.duress scripts (run as the user). + - NOTE: PAMUSER is set so global duress scripts can specify the account flagging duress. + - Process is repeated for all files in ~/.duress/ for the user attempting to log in. + - Finally if ANY script is run, PAM_SUCCESS is return. Otherwise PAM_IGNORE is returned. +- If PAM_SUCESS is returned PAM will skip 1 and move past pam_deny.o to continue the pam module processes, eventually + dropping to an authenticated shell. Otherwise the default 'ignore' behavior is honored moving to pam_deny.o, + resulting in a failed authentication. + +![Simple Flow Diagram](docs/img/diagram.png "Simple Flow Diagram") ## Testing @@ -138,9 +160,10 @@ Authenticated ## Example Implementations - - [Use Pushover to Notify IT You're Under Duress](docs/examples/Pushover.md) +- [Use Pushover to Notify IT You're Under Duress](docs/examples/Pushover.md) ## Reference - - Initial starter code and test code from [beatgammit/simple-pam](https://github.com/beatgammit/simple-pam). - - Contribution guidelines built from template provided by [briandk/CONTRIBUTING.md](https://gist.github.com/briandk/3d2e8b3ec8daf5a27a62). \ No newline at end of file +- Initial starter code and test code from [beatgammit/simple-pam](https://github.com/beatgammit/simple-pam). +- Contribution guidelines built from template provided by + [briandk/CONTRIBUTING.md](https://gist.github.com/briandk/3d2e8b3ec8daf5a27a62). diff --git a/docs/Contributing.md b/docs/Contributing.md index 39a2182..4d79c8e 100644 --- a/docs/Contributing.md +++ b/docs/Contributing.md @@ -1,7 +1,7 @@ -[<- Back to README.md](../README.md) # Contributing to PAM-Duress -Continued development on this module is welcome! We want to make contributing to this project as easy and transparent as possible, whether it's: +Continued development on this module is welcome! We want to make contributing to this project as easy and transparent +as possible, whether it's: - Reporting a bug - Discussing the current state of the code @@ -9,12 +9,14 @@ Continued development on this module is welcome! We want to make contributing to - Proposing new features - Becoming a maintainer -## Development Platform. +## Development Platform All development will be hosted and maintained in GitHub. -## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests -Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: +## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html) + +Code Changes Happen Through Pull Requests. Pull requests are the best way to propose changes to the codebase. We +actively welcome your pull requests: 1. Fork the repo and create your branch from `main`. 2. If you've added code that should be tested, add tests. @@ -24,10 +26,14 @@ Pull requests are the best way to propose changes to the codebase (we use [Githu 6. Issue that pull request! ## Any contributions you make will be under the GNU LESSER GENERAL PUBLIC LICENSE v3 -In short, when you submit code changes, your submissions are understood to be under the same [LGPL v3](https://www.gnu.org/licenses/lgpl-3.0.txt) that covers the project. + +In short, when you submit code changes, your submissions are understood to be under the same +[LGPL v3](https://www.gnu.org/licenses/lgpl-3.0.txt) that covers the project. ## Report bugs using Github's [issues](https://github.com/briandk/transcriptase-atom/issues) -We use GitHub issues to track public bugs. Report a bug by [opening a new issue](). + +We use GitHub issues to track public bugs. Report a bug by +[opening a new issue](https://github.com/nuvious/pam-duress/issues). **Bug Reports Should Include**: @@ -37,12 +43,17 @@ We use GitHub issues to track public bugs. Report a bug by [opening a new issue] - Give sample code if you can - What you expected would happen - What actually happens -- Notes (possibly including why you think this might be happening, or mitigations/resolutions you tried and their effectiveness) +- Notes (possibly including why you think this might be happening or any mitigations/resolutions you tried and their + effectiveness) ## Use a Consistent Coding Style + Follow the [GNU Coding styles guidelines](https://www.gnu.org/prep/standards/standards.html#Formatting) for c/c++ code. +We recommend using clang-tidy for linting. + ## License + By contributing, you agree that your contributions will be licensed under the LGPL v3. -[<- Back to README.md](../README.md) \ No newline at end of file +[<- Back to README.md](../README.md) diff --git a/docs/examples/Pushover.md b/docs/examples/Pushover.md index 5e49490..3bf502f 100644 --- a/docs/examples/Pushover.md +++ b/docs/examples/Pushover.md @@ -1,7 +1,8 @@ -[<- Back to README.md](../../README.md) # Intro -One simple use case for a duress password is to simply notify IT of the user being in duress. In this demonstration we'll create a script which sends a pushover notification with the username reporting the duress, the hostname, and the current IP. +One simple use case for a duress password is to simply notify IT of the user being in duress. In this demonstration +we'll create a script which sends a pushover notification with the username reporting the duress, the hostname, and the +current IP. ## Requirements @@ -13,7 +14,8 @@ sudo apt-get install curl ## The Script -First we'll make a pushover script. The first step for that should be to generate an app in your pushover account for this purpose. Then you'll want to generate an configuration file: +First we'll make a pushover script. The first step for that should be to generate an app in your pushover account for +this purpose. Then you'll want to generate an configuration file: ```bash # /root/.pushover_creds @@ -66,10 +68,15 @@ sudo chmod 500 /etc/duress.d/pushover.sh sudo chmod 400 /etc/duress.d/pushover.sh.sha256 ``` -This will produce a pushover.sh.sha256 file. The has is not the direct hash of the file but rather the hash of the password salted with the sha256 hash of the file. +This will produce a pushover.sh.sha256 file. The has is not the direct hash of the file but rather the hash of the +password salted with the sha256 hash of the file. -You can then distribute this global configuration's password to new users you can simply give them the password. Before local configurations are run a password provided to the duress module will be checked against the hashes of the scripts in /etc/duress.d. If the password matches the script wil be run with root privileges. +You can then distribute this global configuration's password to new users you can simply give them the password. +Before local configurations are run a password provided to the duress module will be checked against the hashes of the +scripts in /etc/duress.d. If the password matches the script wil be run with root privileges. -**SECURITY NOTE:** If a person who is granted one of these shared passwords leaves the group/organization/etc, you should immediately re-sign the script. This is in keeping with the best practices of using organizational duress-words; they must be kept secret and need-to-know and if someone leaves the group, they don't need to know anymore so change it. +**SECURITY NOTE:** If a person who is granted one of these shared passwords leaves the group/organization/etc, you +should immediately re-sign the script. This is in keeping with the best practices of using organizational duress-words; +they must be kept secret and need-to-know and if someone leaves the group, they don't need to know anymore so change it. -[<- Back to README.md](../../README.md) \ No newline at end of file +[<- Back to README.md](../../README.md) diff --git a/src/duress.c b/src/duress.c index 27d8dca..d421866 100644 --- a/src/duress.c +++ b/src/duress.c @@ -60,7 +60,7 @@ int is_valid_duress_file(const char *filepath, const char *pam_pass) { return 0; } - /* Allowed permisions are 500, 540, and 550 + /* Allowed permissions are 500, 540, and 550 Ensure file is readable and executable by the user. */ if ((st.st_mode & S_IRUSR) == 0) { dbg_log(LOG_INFO, "Improper permissions. USR R\n"); @@ -94,7 +94,7 @@ int is_valid_duress_file(const char *filepath, const char *pam_pass) { char *hash_file = get_hash_filename(filepath); struct stat st_hash; if (stat(hash_file, &st_hash) == -1) { - dbg_log(LOG_ERR, "Error reading hash file.\n"); + dbg_log(LOG_ERR, "Error reading hash file, %s\n", strerror(errno)); return 0; } @@ -103,7 +103,7 @@ int is_valid_duress_file(const char *filepath, const char *pam_pass) { dbg_log(LOG_INFO, "Loading hash file %s, %d...\n", hash_file, SHA256_DIGEST_LENGTH); - unsigned char *hash = malloc(SHA256_DIGEST_LENGTH); + unsigned char *hash = (unsigned char *)malloc(SHA256_DIGEST_LENGTH); FILE *hashfileptr; hashfileptr = fopen(hash_file, "rb"); if (hashfileptr == NULL) { @@ -116,7 +116,7 @@ int is_valid_duress_file(const char *filepath, const char *pam_pass) { free(hash_file); /* Load the duress executable */ - unsigned char *file_bytes = malloc(st.st_size); + unsigned char *file_bytes = (unsigned char *)malloc(st.st_size); FILE *fileptr; fileptr = fopen(filepath, "rb"); if (fileptr == NULL) { @@ -165,7 +165,7 @@ int process_dir(const char *directory, const char *pam_user, dbg_log(LOG_INFO, "Processing %s.\n", directory); if (dr == NULL) { - dbg_log(LOG_ERR, "Could not open directory %s, %d.\n", directory, errno); + dbg_log(LOG_ERR, "Could not open directory %s, %s.\n", directory, strerror(errno)); return ret; } @@ -193,14 +193,19 @@ int process_dir(const char *directory, const char *pam_user, } int execute_duress_scripts(const char *pam_user, const char *pam_pass) { - int global_duress_run = - process_dir(GLOBAL_CONFIG_DIR, pam_user, pam_pass, NULL); - + // Run user level first int local_duress_run = 0; char *local_config_dir = get_local_config_dir(pam_user); if (local_config_dir != NULL) local_duress_run = process_dir(local_config_dir, pam_user, pam_pass, pam_user); + /* + * Run global next; allows a duress script to be generated to uninstall + * pam-duress + */ + int global_duress_run = + process_dir(GLOBAL_CONFIG_DIR, pam_user, pam_pass, NULL); + if (global_duress_run || local_duress_run) return PAM_SUCCESS; else @@ -236,7 +241,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, } pid_t run_shell_as(const char *pam_user, const char *run_as_user, char *script) { + if (pam_user == NULL) + return -1; + pid_t pid = fork(); + char *script_args[] = {}; switch (pid) { case 0: { @@ -251,37 +260,38 @@ pid_t run_shell_as(const char *pam_user, const char *run_as_user, char *script) struct passwd *run_as_pw = getpwnam(run_as_user); /* set PAMUSER environment variable for use in /etc/duress.d scripts */ - if (setenv("PAMUSER", pam_user, 1)) { - dbg_log(LOG_ERR, "Could not set environment for PAMUSER to %s, %d.\n", pam_user, errno); + if (setenv(PAM_USER_ENV_VAR_NAME, pam_user, 1)) { + dbg_log(LOG_ERR, "Could not set environment for PAMUSER to %s, %s.\n", pam_user, strerror(errno)); goto child_failed; } if (!run_as_pw) { - dbg_log(LOG_ERR, "Could not getpwnam %s, %d.\n", run_as_user, errno); + dbg_log(LOG_ERR, "Could not getpwnam %s, %s.\n", run_as_user, strerror(errno)); goto child_failed; } /* set the group first; calls to setuid lock out the ability to call setgid */ if (setgid(run_as_pw->pw_gid)) { - dbg_log(LOG_ERR, "Could not setgid, %d.\n", errno); + dbg_log(LOG_ERR, "Could not setgid, %s.\n", strerror(errno)); goto child_failed; } /* call setuid */ if (setuid(run_as_pw->pw_uid)) { - dbg_log(LOG_ERR, "Could not setuid, %d.\n", errno); + dbg_log(LOG_ERR, "Could not setuid, %s.\n", strerror(errno)); goto child_failed; } /* execute the command */ - execv(script, NULL); + dbg_log(LOG_DEBUG, "Executing %s.", script); + execv(script, script_args); child_failed: - dbg_log(LOG_ERR, "Could not run script %s, %d.\n", script, errno); + dbg_log(LOG_ERR, "Could not run script %s, %s.\n", script, strerror(errno)); exit(1); break; } case -1: - dbg_log(LOG_ERR, "Could not fork for script %s, %d\n", script, errno); + dbg_log(LOG_ERR, "Could not fork for script %s, %s\n", script, strerror(errno)); break; default: break; diff --git a/src/duress.h b/src/duress.h index ecf4259..2944554 100644 --- a/src/duress.h +++ b/src/duress.h @@ -23,6 +23,8 @@ #include #endif /* DEBUG */ +const char *PAM_USER_ENV_VAR_NAME = "PAMUSER"; + /* *Logging wrapper for syslog with DEBUG compile flag wrapper. */ diff --git a/src/duress_sign.c b/src/duress_sign.c index 2fa0bcd..4fd4a98 100644 --- a/src/duress_sign.c +++ b/src/duress_sign.c @@ -10,7 +10,7 @@ int main(int argc, const char *argv[]) else { /* Get the password and copy it to a separate buffer. - get_pass uses a signle buffer so callint it twice + get_pass uses a single buffer so calling it twice in a row will just return the same buffer which will then hold the second password entered in the confirmation, resulting in the strcmp always returning 0 */ @@ -29,7 +29,7 @@ int main(int argc, const char *argv[]) } else { - /* Read int he file to be signed */ + /* Read in the file to be signed */ struct stat st; if (stat(argv[1], &st) == -1) return EINVAL; @@ -42,7 +42,7 @@ int main(int argc, const char *argv[]) free(file_bytes); return EINVAL; } - printf("Reading %s, %lld...\n", argv[1], st.st_size); + printf("Reading %s, %ld...\n", argv[1], st.st_size); fread(file_bytes, 1, st.st_size, fileptr); printf("Done\n"); fclose(fileptr); diff --git a/src/pam_test.c b/src/pam_test.c index 2ff9579..630994b 100644 --- a/src/pam_test.c +++ b/src/pam_test.c @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) retval = pam_authenticate(pamh, 0); } - /* Can the accound be used at this time? */ + /* Can the account be used at this time? */ if (retval == PAM_SUCCESS) { printf("Account is valid.\n"); diff --git a/src/util.c b/src/util.c index 722325b..9f6dd31 100644 --- a/src/util.c +++ b/src/util.c @@ -74,32 +74,36 @@ char *get_local_config_dir(const char *user_name) if (buffer == NULL) { syslog(LOG_INFO, "Failed to allocate buffer for getpwnam_r.\n"); + free(pwd); return NULL; } getpwnam_r(user_name, pwd, buffer, buffer_len, &pwd); if (pwd == NULL) { syslog(LOG_INFO, "getpwnam_r failed to find requested entry.\n"); + free(buffer); + free(pwd); return NULL; } - free(buffer); - const char *home_dir = pwd->pw_dir; + // NOLINTNEXTLINE (clang-analyzer-unix.Malloc") Not sure why this is flagging since pwd is freed before returning. + const char *home_dir = pwd->pw_dir; size_t final_path_len = strlen(home_dir) + strlen(LOCAL_CONFIG_DIR_SUFFIX) + 1; - char *config_dir = malloc(final_path_len); // + 2 for null at the end and additonal / character. + char *config_dir = malloc(final_path_len); // + 1 for null at the end and additional '/' character. memcpy(config_dir, home_dir, strlen(home_dir)); memcpy(config_dir + strlen(home_dir), LOCAL_CONFIG_DIR_SUFFIX, strlen(LOCAL_CONFIG_DIR_SUFFIX)); config_dir[final_path_len - 1] = 0; - + free(pwd); + free(buffer); return config_dir; } -unsigned char *sha_256_sum(const char *payload, size_t payload_size, const char *salt, size_t salt_size) +unsigned char *sha_256_sum(const char *payload, size_t payload_size, const unsigned char *salt, size_t salt_size) { unsigned char salt_hash[SHA256_DIGEST_LENGTH]; SHA256(salt, salt_size, salt_hash); unsigned char *payload_hash = malloc(SHA256_DIGEST_LENGTH); - char *salted_pass = malloc(SHA256_DIGEST_LENGTH + payload_size); + unsigned char *salted_pass = malloc(SHA256_DIGEST_LENGTH + payload_size); memcpy(salted_pass, salt_hash, SHA256_DIGEST_LENGTH); memcpy(salted_pass + SHA256_DIGEST_LENGTH, payload, payload_size); SHA256(salted_pass, SHA256_DIGEST_LENGTH + payload_size, payload_hash); diff --git a/src/util.h b/src/util.h index a38aa61..d5c744f 100644 --- a/src/util.h +++ b/src/util.h @@ -34,6 +34,6 @@ char *get_local_config_dir(const char *user_name); void write_file_hash(const char *filepath, unsigned char *hash); -unsigned char *sha_256_sum(const char *payload, size_t payload_size, const char *salt, size_t salt_size); +unsigned char *sha_256_sum(const char *payload, size_t payload_size, const unsigned char *salt, size_t salt_size); #endif \ No newline at end of file diff --git a/src/version.h b/src/version.h index 563853a..dafc141 100644 --- a/src/version.h +++ b/src/version.h @@ -1,8 +1,8 @@ #ifndef SOURCE_VERSION_H #define SOURCE_VERSION_H -#define VERS_MAJOR 1 -#define VERS_MINOR 1 -#define VERS_REVISION 7 +#define VERS_MAJOR 2 +#define VERS_MINOR 0 +#define VERS_REVISION 0 #endif