Path: blob/main/crypto/krb5/src/plugins/pwqual/test/main.c
34890 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* plugins/pwqual/test/main.c - test module for password quality interface */2/*3* Copyright (C) 2010,2013 by the Massachusetts Institute of Technology.4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9*10* * Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in15* the documentation and/or other materials provided with the16* distribution.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS21* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE22* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,23* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES24* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR25* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,27* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED29* OF THE POSSIBILITY OF SUCH DAMAGE.30*/3132/*33* This file implements a module named "combo" which tests whether a password34* matches a pair of words in the dictionary. It also implements several dummy35* modules named "dyn1", "dyn2", and "dyn3" which are used for ordering tests.36*/3738#include <k5-platform.h>39#include <krb5/pwqual_plugin.h>40#include <sys/types.h>41#include <sys/stat.h>42#include <fcntl.h>43#include <unistd.h>4445typedef struct combo_moddata_st {46const char **word_list; /* list of word pointers */47char *word_block; /* actual word data */48} *combo_moddata;4950static krb5_error_code51init_dict(combo_moddata dict, const char *dict_file)52{53int fd;54size_t count, len, i;55char *p, *t;56struct stat sb;5758/* Read the dictionary file into memory in one blob. */59if (dict_file == NULL)60return 0;61fd = open(dict_file, O_RDONLY);62if (fd == -1)63return (errno == ENOENT) ? 0 : errno;64if (fstat(fd, &sb) == -1) {65close(fd);66return errno;67}68dict->word_block = malloc(sb.st_size + 1);69if (dict->word_block == NULL)70return ENOMEM;71if (read(fd, dict->word_block, sb.st_size) != sb.st_size)72return errno;73close(fd);74dict->word_block[sb.st_size] = '\0';7576/* Decompose the blob into newline-separated words. */77p = dict->word_block;78len = sb.st_size;79count = 0;80while (len > 0 && (t = memchr(p, '\n', len)) != NULL) {81*t = '\0';82len -= t - p + 1;83p = t + 1;84count++;85}86dict->word_list = calloc(count + 1, sizeof(char *));87if (dict->word_list == NULL)88return ENOMEM;89p = dict->word_block;90for (i = 0; i < count; i++) {91dict->word_list[i] = p;92p += strlen(p) + 1;93}94return 0;95}9697static void98destroy_dict(combo_moddata dict)99{100if (dict == NULL)101return;102free(dict->word_list);103free(dict->word_block);104free(dict);105}106107static krb5_error_code108combo_open(krb5_context context, const char *dict_file,109krb5_pwqual_moddata *data)110{111krb5_error_code ret;112combo_moddata dict;113114*data = NULL;115116/* Allocate and initialize a dictionary structure. */117dict = malloc(sizeof(*dict));118if (dict == NULL)119return ENOMEM;120dict->word_list = NULL;121dict->word_block = NULL;122123/* Fill in the dictionary structure with data from dict_file. */124ret = init_dict(dict, dict_file);125if (ret != 0) {126destroy_dict(dict);127return ret;128}129130*data = (krb5_pwqual_moddata)dict;131return 0;132}133134static krb5_error_code135combo_check(krb5_context context, krb5_pwqual_moddata data,136const char *password, const char *policy_name,137krb5_principal princ, const char **languages)138{139combo_moddata dict = (combo_moddata)data;140const char *remainder, **word1, **word2;141142if (dict->word_list == NULL)143return 0;144145for (word1 = dict->word_list; *word1 != NULL; word1++) {146if (strncasecmp(password, *word1, strlen(*word1)) != 0)147continue;148remainder = password + strlen(*word1);149for (word2 = dict->word_list; *word2 != NULL; word2++) {150if (strcasecmp(remainder, *word2) == 0) {151krb5_set_error_message(context, KADM5_PASS_Q_DICT,152"Password may not be a pair of "153"dictionary words");154return KADM5_PASS_Q_DICT;155}156}157}158159return 0;160}161162static void163combo_close(krb5_context context, krb5_pwqual_moddata data)164{165destroy_dict((combo_moddata)data);166}167168krb5_error_code169pwqual_combo_initvt(krb5_context context, int maj_ver, int min_ver,170krb5_plugin_vtable vtable);171krb5_error_code172pwqual_dyn1_initvt(krb5_context context, int maj_ver, int min_ver,173krb5_plugin_vtable vtable);174krb5_error_code175pwqual_dyn2_initvt(krb5_context context, int maj_ver, int min_ver,176krb5_plugin_vtable vtable);177krb5_error_code178pwqual_dyn3_initvt(krb5_context context, int maj_ver, int min_ver,179krb5_plugin_vtable vtable);180181krb5_error_code182pwqual_combo_initvt(krb5_context context, int maj_ver, int min_ver,183krb5_plugin_vtable vtable)184{185krb5_pwqual_vtable vt;186187if (maj_ver != 1)188return KRB5_PLUGIN_VER_NOTSUPP;189vt = (krb5_pwqual_vtable)vtable;190vt->name = "combo";191vt->open = combo_open;192vt->check = combo_check;193vt->close = combo_close;194return 0;195}196197krb5_error_code198pwqual_dyn1_initvt(krb5_context context, int maj_ver, int min_ver,199krb5_plugin_vtable vtable)200{201((krb5_pwqual_vtable)vtable)->name = "dyn1";202return 0;203}204205krb5_error_code206pwqual_dyn2_initvt(krb5_context context, int maj_ver, int min_ver,207krb5_plugin_vtable vtable)208{209((krb5_pwqual_vtable)vtable)->name = "dyn2";210return 0;211}212213krb5_error_code214pwqual_dyn3_initvt(krb5_context context, int maj_ver, int min_ver,215krb5_plugin_vtable vtable)216{217((krb5_pwqual_vtable)vtable)->name = "dyn3";218return 0;219}220221222