mirror of
https://github.com/linux-pam/linux-pam.git
synced 2024-12-03 22:53:42 +08:00
libpam: make use of secure memory erasure
Non trivial changes: - erase responses in pam_get_authtok_internal() on error branch
This commit is contained in:
parent
19a2926817
commit
e2d01a42c1
@ -161,7 +161,7 @@ pam_read_passwords(int fd, int npass, char **passwords)
|
||||
if (npass > 0) {
|
||||
memcpy(passwords[i], pptr, rbytes);
|
||||
}
|
||||
memset(pptr, '\0', rbytes);
|
||||
pam_overwrite_n(pptr, rbytes);
|
||||
}
|
||||
}
|
||||
offset += rbytes;
|
||||
@ -169,7 +169,7 @@ pam_read_passwords(int fd, int npass, char **passwords)
|
||||
|
||||
/* clear up */
|
||||
if (offset > 0 && npass > 0) {
|
||||
memset(passwords[i], '\0', offset);
|
||||
pam_overwrite_n(passwords[i], offset);
|
||||
}
|
||||
|
||||
return i;
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "pam_private.h"
|
||||
#include "pam_inline.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -41,34 +42,34 @@ int pam_end(pam_handle_t *pamh, int pam_status)
|
||||
|
||||
_pam_drop_env(pamh); /* purge the environment */
|
||||
|
||||
_pam_overwrite(pamh->authtok); /* blank out old token */
|
||||
pam_overwrite_string(pamh->authtok); /* blank out old token */
|
||||
_pam_drop(pamh->authtok);
|
||||
|
||||
_pam_overwrite(pamh->oldauthtok); /* blank out old token */
|
||||
pam_overwrite_string(pamh->oldauthtok); /* blank out old token */
|
||||
_pam_drop(pamh->oldauthtok);
|
||||
|
||||
_pam_overwrite(pamh->former.prompt);
|
||||
pam_overwrite_string(pamh->former.prompt);
|
||||
_pam_drop(pamh->former.prompt); /* drop saved prompt */
|
||||
|
||||
_pam_overwrite(pamh->service_name);
|
||||
pam_overwrite_string(pamh->service_name);
|
||||
_pam_drop(pamh->service_name);
|
||||
|
||||
_pam_overwrite(pamh->user);
|
||||
pam_overwrite_string(pamh->user);
|
||||
_pam_drop(pamh->user);
|
||||
|
||||
_pam_overwrite(pamh->confdir);
|
||||
pam_overwrite_string(pamh->confdir);
|
||||
_pam_drop(pamh->confdir);
|
||||
|
||||
_pam_overwrite(pamh->prompt);
|
||||
pam_overwrite_string(pamh->prompt);
|
||||
_pam_drop(pamh->prompt); /* prompt for pam_get_user() */
|
||||
|
||||
_pam_overwrite(pamh->tty);
|
||||
pam_overwrite_string(pamh->tty);
|
||||
_pam_drop(pamh->tty);
|
||||
|
||||
_pam_overwrite(pamh->rhost);
|
||||
pam_overwrite_string(pamh->rhost);
|
||||
_pam_drop(pamh->rhost);
|
||||
|
||||
_pam_overwrite(pamh->ruser);
|
||||
pam_overwrite_string(pamh->ruser);
|
||||
_pam_drop(pamh->ruser);
|
||||
|
||||
_pam_drop(pamh->pam_conversation);
|
||||
@ -76,16 +77,16 @@ int pam_end(pam_handle_t *pamh, int pam_status)
|
||||
|
||||
_pam_drop(pamh->former.substates);
|
||||
|
||||
_pam_overwrite(pamh->xdisplay);
|
||||
pam_overwrite_string(pamh->xdisplay);
|
||||
_pam_drop(pamh->xdisplay);
|
||||
|
||||
_pam_overwrite(pamh->xauth.name);
|
||||
pam_overwrite_string(pamh->xauth.name);
|
||||
_pam_drop(pamh->xauth.name);
|
||||
_pam_overwrite_n(pamh->xauth.data, (unsigned int)pamh->xauth.datalen);
|
||||
pam_overwrite_n(pamh->xauth.data, (unsigned int)pamh->xauth.datalen);
|
||||
_pam_drop(pamh->xauth.data);
|
||||
_pam_overwrite_n((char *)&pamh->xauth, sizeof(pamh->xauth));
|
||||
pam_overwrite_object(&pamh->xauth);
|
||||
|
||||
_pam_overwrite(pamh->authtok_type);
|
||||
pam_overwrite_string(pamh->authtok_type);
|
||||
_pam_drop(pamh->authtok_type);
|
||||
|
||||
/* and finally liberate the memory for the pam_handle structure */
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include "pam_private.h"
|
||||
#include "pam_inline.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -100,7 +101,7 @@ void _pam_drop_env(pam_handle_t *pamh)
|
||||
|
||||
for (i=pamh->env->requested-1; i-- > 0; ) {
|
||||
D(("dropping #%3d>%s<", i, pamh->env->list[i]));
|
||||
_pam_overwrite(pamh->env->list[i]); /* clean */
|
||||
pam_overwrite_string(pamh->env->list[i]); /* clean */
|
||||
_pam_drop(pamh->env->list[i]); /* forget */
|
||||
}
|
||||
pamh->env->requested = 0;
|
||||
@ -227,7 +228,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value)
|
||||
} else { /* replace old */
|
||||
D(("replacing item: %s\n with: %s"
|
||||
, pamh->env->list[item], name_value));
|
||||
_pam_overwrite(pamh->env->list[item]);
|
||||
pam_overwrite_string(pamh->env->list[item]);
|
||||
_pam_drop(pamh->env->list[item]);
|
||||
}
|
||||
|
||||
@ -261,7 +262,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value)
|
||||
*/
|
||||
|
||||
D(("deleting: env#%3d:[%s]", item, pamh->env->list[item]));
|
||||
_pam_overwrite(pamh->env->list[item]);
|
||||
pam_overwrite_string(pamh->env->list[item]);
|
||||
_pam_drop(pamh->env->list[item]);
|
||||
--(pamh->env->requested);
|
||||
D(("mmove: item[%d]+%d -> item[%d]"
|
||||
@ -341,7 +342,7 @@ static char **_copy_env(pam_handle_t *pamh)
|
||||
/* out of memory */
|
||||
|
||||
while (dump[++i]) {
|
||||
_pam_overwrite(dump[i]);
|
||||
pam_overwrite_string(dump[i]);
|
||||
_pam_drop(dump[i]);
|
||||
}
|
||||
_pam_drop(dump);
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "pam_private.h"
|
||||
#include "pam_inline.h"
|
||||
|
||||
#include <security/pam_ext.h>
|
||||
|
||||
@ -174,6 +175,10 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item,
|
||||
(chpass > 1 && resp[1] == NULL))
|
||||
{
|
||||
/* We want to abort */
|
||||
pam_overwrite_string (resp[0]);
|
||||
_pam_drop (resp[0]);
|
||||
pam_overwrite_string (resp[1]);
|
||||
_pam_drop (resp[1]);
|
||||
if (chpass)
|
||||
pam_error (pamh, _("Password change has been aborted."));
|
||||
return PAM_AUTHTOK_ERR;
|
||||
@ -182,18 +187,18 @@ pam_get_authtok_internal (pam_handle_t *pamh, int item,
|
||||
if (chpass > 1 && strcmp (resp[0], resp[1]) != 0)
|
||||
{
|
||||
pam_error (pamh, MISTYPED_PASS);
|
||||
_pam_overwrite (resp[0]);
|
||||
pam_overwrite_string (resp[0]);
|
||||
_pam_drop (resp[0]);
|
||||
_pam_overwrite (resp[1]);
|
||||
pam_overwrite_string (resp[1]);
|
||||
_pam_drop (resp[1]);
|
||||
return PAM_TRY_AGAIN;
|
||||
}
|
||||
|
||||
_pam_overwrite (resp[1]);
|
||||
pam_overwrite_string (resp[1]);
|
||||
_pam_drop (resp[1]);
|
||||
|
||||
retval = pam_set_item (pamh, item, resp[0]);
|
||||
_pam_overwrite (resp[0]);
|
||||
pam_overwrite_string (resp[0]);
|
||||
_pam_drop (resp[0]);
|
||||
if (retval != PAM_SUCCESS)
|
||||
return retval;
|
||||
@ -263,13 +268,13 @@ pam_get_authtok_verify (pam_handle_t *pamh, const char **authtok,
|
||||
{
|
||||
pam_set_item (pamh, PAM_AUTHTOK, NULL);
|
||||
pam_error (pamh, MISTYPED_PASS);
|
||||
_pam_overwrite (resp);
|
||||
pam_overwrite_string (resp);
|
||||
_pam_drop (resp);
|
||||
return PAM_TRY_AGAIN;
|
||||
}
|
||||
|
||||
retval = pam_set_item (pamh, PAM_AUTHTOK, resp);
|
||||
_pam_overwrite (resp);
|
||||
pam_overwrite_string (resp);
|
||||
_pam_drop (resp);
|
||||
if (retval != PAM_SUCCESS)
|
||||
return retval;
|
||||
|
@ -1033,7 +1033,7 @@ void _pam_free_handlers_aux(struct handler **hp)
|
||||
_pam_drop(h->argv); /* This is all allocated in a single chunk */
|
||||
_pam_drop(h->mod_name);
|
||||
h = h->next;
|
||||
memset(last, 0, sizeof(*last));
|
||||
pam_overwrite_object(last);
|
||||
free(last);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "pam_private.h"
|
||||
#include "pam_inline.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
@ -79,7 +80,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
|
||||
*/
|
||||
if (__PAM_FROM_MODULE(pamh)) {
|
||||
if (pamh->authtok != item) {
|
||||
_pam_overwrite(pamh->authtok);
|
||||
pam_overwrite_string(pamh->authtok);
|
||||
TRY_SET(pamh->authtok, item);
|
||||
}
|
||||
} else {
|
||||
@ -95,7 +96,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
|
||||
*/
|
||||
if (__PAM_FROM_MODULE(pamh)) {
|
||||
if (pamh->oldauthtok != item) {
|
||||
_pam_overwrite(pamh->oldauthtok);
|
||||
pam_overwrite_string(pamh->oldauthtok);
|
||||
TRY_SET(pamh->oldauthtok, item);
|
||||
}
|
||||
} else {
|
||||
@ -139,24 +140,23 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
|
||||
if (&pamh->xauth == item)
|
||||
break;
|
||||
if (pamh->xauth.namelen) {
|
||||
_pam_overwrite(pamh->xauth.name);
|
||||
pam_overwrite_string(pamh->xauth.name);
|
||||
free(pamh->xauth.name);
|
||||
}
|
||||
if (pamh->xauth.datalen) {
|
||||
_pam_overwrite_n(pamh->xauth.data,
|
||||
(unsigned int) pamh->xauth.datalen);
|
||||
pam_overwrite_n(pamh->xauth.data, (unsigned int) pamh->xauth.datalen);
|
||||
free(pamh->xauth.data);
|
||||
}
|
||||
pamh->xauth = *((const struct pam_xauth_data *) item);
|
||||
if ((pamh->xauth.name=_pam_strdup(pamh->xauth.name)) == NULL) {
|
||||
memset(&pamh->xauth, '\0', sizeof(pamh->xauth));
|
||||
pam_overwrite_object(&pamh->xauth);
|
||||
return PAM_BUF_ERR;
|
||||
}
|
||||
if ((pamh->xauth.data=_pam_memdup(pamh->xauth.data,
|
||||
pamh->xauth.datalen)) == NULL) {
|
||||
_pam_overwrite(pamh->xauth.name);
|
||||
pam_overwrite_string(pamh->xauth.name);
|
||||
free(pamh->xauth.name);
|
||||
memset(&pamh->xauth, '\0', sizeof(pamh->xauth));
|
||||
pam_overwrite_object(&pamh->xauth);
|
||||
return PAM_BUF_ERR;
|
||||
}
|
||||
break;
|
||||
@ -330,7 +330,7 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
|
||||
|
||||
/* ok, we can resume where we left off last time */
|
||||
pamh->former.want_user = PAM_FALSE;
|
||||
_pam_overwrite(pamh->former.prompt);
|
||||
pam_overwrite_string(pamh->former.prompt);
|
||||
_pam_drop(pamh->former.prompt);
|
||||
}
|
||||
|
||||
@ -388,7 +388,7 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
|
||||
* note 'resp' is allocated by the application and is
|
||||
* correctly free()'d here
|
||||
*/
|
||||
_pam_drop_reply(resp, 1);
|
||||
pam_drop_response(resp, 1);
|
||||
}
|
||||
|
||||
D(("completed"));
|
||||
|
@ -40,10 +40,10 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <security/pam_modules.h>
|
||||
#include <security/_pam_macros.h>
|
||||
#include <security/pam_ext.h>
|
||||
|
||||
#include "pam_private.h"
|
||||
#include "pam_inline.h"
|
||||
|
||||
int
|
||||
pam_vprompt (pam_handle_t *pamh, int style, char **response,
|
||||
@ -88,10 +88,10 @@ pam_vprompt (pam_handle_t *pamh, int style, char **response,
|
||||
*response = pam_resp == NULL ? NULL : pam_resp->resp;
|
||||
else if (pam_resp && pam_resp->resp)
|
||||
{
|
||||
_pam_overwrite (pam_resp->resp);
|
||||
pam_overwrite_string (pam_resp->resp);
|
||||
_pam_drop (pam_resp->resp);
|
||||
}
|
||||
_pam_overwrite (msgbuf);
|
||||
pam_overwrite_string (msgbuf);
|
||||
_pam_drop (pam_resp);
|
||||
free (msgbuf);
|
||||
if (retval != PAM_SUCCESS)
|
||||
|
Loading…
Reference in New Issue
Block a user