diff options
Diffstat (limited to 'src/util/authtok.c')
-rw-r--r-- | src/util/authtok.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/src/util/authtok.c b/src/util/authtok.c new file mode 100644 index 000000000..684b07622 --- /dev/null +++ b/src/util/authtok.c @@ -0,0 +1,202 @@ +/* + SSSD - auth utils + + Copyright (C) Simo Sorce <simo@redhat.com> 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "authtok.h" + +enum sss_authtok_type sss_authtok_get_type(struct sss_auth_token *tok) +{ + return tok->type; +} + +size_t sss_authtok_get_size(struct sss_auth_token *tok) +{ + switch (tok->type) { + case SSS_AUTHTOK_TYPE_PASSWORD: + case SSS_AUTHTOK_TYPE_CCFILE: + return tok->length; + case SSS_AUTHTOK_TYPE_EMPTY: + return 0; + } + + return EINVAL; +} + +uint8_t *sss_authtok_get_data(struct sss_auth_token *tok) +{ + return tok->data; +} + +errno_t sss_authtok_get_password(struct sss_auth_token *tok, + const char **pwd, size_t *len) +{ + switch (tok->type) { + case SSS_AUTHTOK_TYPE_EMPTY: + return ENOENT; + case SSS_AUTHTOK_TYPE_PASSWORD: + *pwd = (const char *)tok->data; + if (len) { + *len = tok->length - 1; + } + return EOK; + case SSS_AUTHTOK_TYPE_CCFILE: + return EACCES; + } + + return EINVAL; +} + +errno_t sss_authtok_get_ccfile(struct sss_auth_token *tok, + const char **ccfile, size_t *len) +{ + switch (tok->type) { + case SSS_AUTHTOK_TYPE_EMPTY: + return ENOENT; + case SSS_AUTHTOK_TYPE_CCFILE: + *ccfile = (const char *)tok->data; + if (len) { + *len = tok->length - 1; + } + return EOK; + case SSS_AUTHTOK_TYPE_PASSWORD: + return EACCES; + } + + return EINVAL; +} + +static errno_t sss_authtok_set_string(TALLOC_CTX *mem_ctx, + struct sss_auth_token *tok, + enum sss_authtok_type type, + const char *context_name, + const char *str, size_t len) +{ + size_t size; + + if (len == 0) { + len = strlen(str); + } else { + while (len > 0 && str[len - 1] == '\0') len--; + } + + if (len == 0) { + /* we do not allow zero length typed tokens */ + return EINVAL; + } + + size = len + 1; + + tok->data = talloc_named(mem_ctx, size, context_name); + if (!tok->data) { + return ENOMEM; + } + memcpy(tok->data, str, len); + tok->data[len] = '\0'; + tok->type = type; + tok->length = size; + + return EOK; + +} + +void sss_authtok_set_empty(struct sss_auth_token *tok) +{ + switch (tok->type) { + case SSS_AUTHTOK_TYPE_EMPTY: + return; + case SSS_AUTHTOK_TYPE_PASSWORD: + safezero(tok->data, tok->length); + break; + case SSS_AUTHTOK_TYPE_CCFILE: + break; + } + + tok->type = SSS_AUTHTOK_TYPE_EMPTY; + talloc_zfree(tok->data); + tok->length = 0; +} + +errno_t sss_authtok_set_password(TALLOC_CTX *mem_ctx, + struct sss_auth_token *tok, + const char *password, size_t len) +{ + sss_authtok_set_empty(tok); + + return sss_authtok_set_string(mem_ctx, tok, + SSS_AUTHTOK_TYPE_PASSWORD, + "password", password, len); +} + +errno_t sss_authtok_set_ccfile(TALLOC_CTX *mem_ctx, + struct sss_auth_token *tok, + const char *ccfile, size_t len) +{ + sss_authtok_set_empty(tok); + + return sss_authtok_set_string(mem_ctx, tok, + SSS_AUTHTOK_TYPE_CCFILE, + "ccfile", ccfile, len); +} + +errno_t sss_authtok_set(TALLOC_CTX *mem_ctx, + struct sss_auth_token *tok, + enum sss_authtok_type type, + uint8_t *data, size_t len) +{ + switch (type) { + case SSS_AUTHTOK_TYPE_PASSWORD: + return sss_authtok_set_password(mem_ctx, tok, (const char *)data, len); + case SSS_AUTHTOK_TYPE_CCFILE: + return sss_authtok_set_ccfile(mem_ctx, tok, (const char *)data, len); + case SSS_AUTHTOK_TYPE_EMPTY: + sss_authtok_set_empty(tok); + return EOK; + } + + return EINVAL; +} + +errno_t sss_authtok_copy(TALLOC_CTX *mem_ctx, + struct sss_auth_token *src, + struct sss_auth_token *dst) +{ + sss_authtok_set_empty(dst); + + if (src->type == SSS_AUTHTOK_TYPE_EMPTY) { + return EOK; + } + + dst->data = talloc_memdup(mem_ctx, src->data, src->length); + if (!dst->data) { + return ENOMEM; + } + dst->length = src->length; + dst->type = src->type; + + return EOK; +} + +void sss_authtok_wipe_password(struct sss_auth_token *tok) +{ + if (tok->type != SSS_AUTHTOK_TYPE_PASSWORD) { + return; + } + + safezero(tok->data, tok->length); +} + |