From d41919bb06bc1fb66681383bd885dfd593779b9f Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Fri, 18 Dec 2009 13:17:45 -0500 Subject: Do not blindly accept zero-length passwords --- server/providers/krb5/krb5_auth.c | 5 ++++- server/providers/krb5/krb5_child.c | 20 +++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/server/providers/krb5/krb5_auth.c b/server/providers/krb5/krb5_auth.c index 74981b19b..a124371ed 100644 --- a/server/providers/krb5/krb5_auth.c +++ b/server/providers/krb5/krb5_auth.c @@ -316,7 +316,7 @@ errno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf) return ENOMEM; } - buf->size = 8*sizeof(uint32_t) + strlen(kr->pd->upn) + strlen(kr->ccname) + + buf->size = 9*sizeof(uint32_t) + strlen(kr->pd->upn) + strlen(kr->ccname) + strlen(keytab) + kr->pd->authtok_size; if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) { @@ -343,6 +343,9 @@ errno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf) ((uint32_t *)(&buf->data[rp]))[0] = validate; rp += sizeof(uint32_t); + ((uint32_t *)(&buf->data[rp]))[0] = kr->is_offline; + rp += sizeof(uint32_t); + ((uint32_t *)(&buf->data[rp]))[0] = (uint32_t) strlen(kr->pd->upn); rp += sizeof(uint32_t); diff --git a/server/providers/krb5/krb5_child.c b/server/providers/krb5/krb5_child.c index 6b4c7cc0f..04cf1f067 100644 --- a/server/providers/krb5/krb5_child.c +++ b/server/providers/krb5/krb5_child.c @@ -686,7 +686,8 @@ static errno_t create_empty_ccache(int fd, struct krb5_req *kr) } static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd, - char **ccname, char **keytab, uint32_t *validate) + char **ccname, char **keytab, uint32_t *validate, + uint32_t *offline) { size_t p = 0; uint32_t len; @@ -707,6 +708,11 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd, *validate = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); + if ((p + sizeof(uint32_t)) > size) return EINVAL; + len = *((uint32_t *)(buf + p)); + *offline = len; + p += sizeof(uint32_t); + if ((p + sizeof(uint32_t)) > size) return EINVAL; len = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); @@ -791,7 +797,7 @@ static int krb5_cleanup(void *ptr) } static int krb5_setup(struct pam_data *pd, const char *user_princ_str, - struct krb5_req **krb5_req) + uint32_t offline, struct krb5_req **krb5_req) { struct krb5_req *kr = NULL; krb5_error_code kerr = 0; @@ -829,9 +835,8 @@ static int krb5_setup(struct pam_data *pd, const char *user_princ_str, switch(pd->cmd) { case SSS_PAM_AUTHENTICATE: - /* if authtok_size is 1 we got an empty password, this means we - * are offline and need to create an empty ccache file */ - if (pd->authtok_size == 1) { + /* If we are offline, we need to create an empty ccache file */ + if (offline) { kr->child_req = create_empty_ccache; } else { kr->child_req = tgt_req_child; @@ -910,6 +915,7 @@ int main(int argc, const char *argv[]) char *ccname; char *keytab; uint32_t validate; + uint32_t offline; int opt; poptContext pc; int debug_fd = -1; @@ -983,13 +989,13 @@ int main(int argc, const char *argv[]) } close(STDIN_FILENO); - ret = unpack_buffer(buf, len, pd, &ccname, &keytab, &validate); + ret = unpack_buffer(buf, len, pd, &ccname, &keytab, &validate, &offline); if (ret != EOK) { DEBUG(1, ("unpack_buffer failed.\n")); goto fail; } - ret = krb5_setup(pd, pd->upn, &kr); + ret = krb5_setup(pd, pd->upn, offline, &kr); if (ret != EOK) { DEBUG(1, ("krb5_setup failed.\n")); goto fail; -- cgit