diff --git a/src/main.c b/src/main.c index 0ad58f1..351b435 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -483,8 +484,32 @@ int main(int argc, char **argv) if (quiet) to_dev_null(STDOUT_FILENO); + /* Snapshot password/passphrase from the environment, then wipe + * them in place. getenv() returns a pointer directly into the + * process's original environment block, which stays readable by + * any local process with the same uid via /proc/PID/environ for + * as long as the bytes remain unmodified -- calling unsetenv() + * alone does NOT clear this, since /proc/PID/environ reflects + * the raw exec-time memory, not libc's environ[] bookkeeping. + * Copy the value to the heap, then memset the original bytes to + * remove them from that memory, keeping non-interactive usage + * (scripts, CI) working without leaving the secret exposed for + * the remaining lifetime of the process. + */ s.password = getenv(ENV_SSH_AUTH_PASSWORD); s.passphrase = getenv(ENV_SSH_AUTH_PASSPHRASE); + if (s.password) { + char *p = s.password; + s.password = strdup(p); + memset(p, 0, strlen(p)); + } + if (s.passphrase) { + char *p = s.passphrase; + s.passphrase = strdup(p); + memset(p, 0, strlen(p)); + } + unsetenv(ENV_SSH_AUTH_PASSWORD); + unsetenv(ENV_SSH_AUTH_PASSPHRASE); if ((m = mscp_init(&o, &s)) == NULL) { pr_err("mscp_init: %s", priv_get_err());