Path: blob/main/crypto/heimdal/kadmin/random_password.c
34865 views
/*1* Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "kadmin_locl.h"3435/* This file defines some a function that generates a random password,36that can be used when creating a large amount of principals (such37as for a batch of students). Since this is a political matter, you38should think about how secure generated passwords has to be.3940Both methods defined here will give you at least 55 bits of41entropy.42*/4344/* If you want OTP-style passwords, define OTP_STYLE */4546#ifdef OTP_STYLE47#include <otp.h>48#else49static void generate_password(char **pw, int num_classes, ...);50#endif5152void53random_password(char *pw, size_t len)54{55#ifdef OTP_STYLE56{57OtpKey newkey;5859krb5_generate_random_block(&newkey, sizeof(newkey));60otp_print_stddict (newkey, pw, len);61strlwr(pw);62}63#else64char *pass;65generate_password(&pass, 3,66"abcdefghijklmnopqrstuvwxyz", 7,67"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2,68"@$%&*()-+=:,/<>1234567890", 1);69strlcpy(pw, pass, len);70memset(pass, 0, strlen(pass));71free(pass);72#endif73}7475/* some helper functions */7677#ifndef OTP_STYLE78/* return a random value in range 0-127 */79static int80RND(unsigned char *key, int keylen, int *left)81{82if(*left == 0){83krb5_generate_random_block(key, keylen);84*left = keylen;85}86(*left)--;87return ((unsigned char*)key)[*left];88}8990/* This a helper function that generates a random password with a91number of characters from a set of character classes.9293If there are n classes, and the size of each class is Pi, and the94number of characters from each class is Ni, the number of possible95passwords are (given that the character classes are disjoint):9697n n98----- / ---- \99| | Ni | \ |100| | Pi | \ Ni| !101| | ---- * | / |102| | Ni! | /___ |103i=1 \ i=1 /104105Since it uses the RND function above, neither the size of each106class, nor the total length of the generated password should be107larger than 127 (without fixing RND).108109*/110static void111generate_password(char **pw, int num_classes, ...)112{113struct {114const char *str;115int len;116int freq;117} *classes;118va_list ap;119int len, i;120unsigned char rbuf[8]; /* random buffer */121int rleft = 0;122123*pw = NULL;124125classes = malloc(num_classes * sizeof(*classes));126if(classes == NULL)127return;128va_start(ap, num_classes);129len = 0;130for(i = 0; i < num_classes; i++){131classes[i].str = va_arg(ap, const char*);132classes[i].len = strlen(classes[i].str);133classes[i].freq = va_arg(ap, int);134len += classes[i].freq;135}136va_end(ap);137*pw = malloc(len + 1);138if(*pw == NULL) {139free(classes);140return;141}142for(i = 0; i < len; i++) {143int j;144int x = RND(rbuf, sizeof(rbuf), &rleft) % (len - i);145int t = 0;146for(j = 0; j < num_classes; j++) {147if(x < t + classes[j].freq) {148(*pw)[i] = classes[j].str[RND(rbuf, sizeof(rbuf), &rleft)149% classes[j].len];150classes[j].freq--;151break;152}153t += classes[j].freq;154}155}156(*pw)[len] = '\0';157memset(rbuf, 0, sizeof(rbuf));158free(classes);159}160#endif161162163