crypt.c revision 272830
1226048Sobrien/*- 2226048Sobrien * Copyright (c) 1999 Mark Murray 3330569Sgordon * Copyright (c) 2014 Dag-Erling Sm��rgrav 4226048Sobrien * All rights reserved. 5226048Sobrien * 6226048Sobrien * Redistribution and use in source and binary forms, with or without 7226048Sobrien * modification, are permitted provided that the following conditions 8226048Sobrien * are met: 9226048Sobrien * 1. Redistributions of source code must retain the above copyright 10226048Sobrien * notice, this list of conditions and the following disclaimer. 11226048Sobrien * 2. Redistributions in binary form must reproduce the above copyright 12226048Sobrien * notice, this list of conditions and the following disclaimer in the 13226048Sobrien * documentation and/or other materials provided with the distribution. 14226048Sobrien * 15226048Sobrien * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND 16226048Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17226048Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18226048Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE 19226048Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20226048Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21226048Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22226048Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23226048Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24226048Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25226048Sobrien * SUCH DAMAGE. 26226048Sobrien */ 27226048Sobrien 28226048Sobrien#include <sys/cdefs.h> 29226048Sobrien__FBSDID("$FreeBSD: head/lib/libcrypt/crypt.c 272830 2014-10-09 16:45:11Z des $"); 30226048Sobrien 31226048Sobrien#include <sys/types.h> 32226048Sobrien 33226048Sobrien#include <libutil.h> 34226048Sobrien#include <string.h> 35226048Sobrien#include <unistd.h> 36226048Sobrien 37226048Sobrien#include "crypt.h" 38226048Sobrien 39226048Sobrien/* 40226048Sobrien * List of supported crypt(3) formats. 41226048Sobrien * 42226048Sobrien * The default algorithm is the last entry in the list (second-to-last 43226048Sobrien * array element since the last is a sentinel). The reason for placing 44226048Sobrien * the default last rather than first is that DES needs to be at the 45226048Sobrien * bottom for the algorithm guessing logic in crypt(3) to work correctly, 46226048Sobrien * and it needs to be the default for backward compatibility. 47226048Sobrien */ 48226048Sobrienstatic const struct crypt_format { 49226048Sobrien const char *const name; 50226048Sobrien char *(*const func)(const char *, const char *); 51226048Sobrien const char *const magic; 52226048Sobrien} crypt_formats[] = { 53226048Sobrien { "md5", crypt_md5, "$1$" }, 54226048Sobrien#ifdef HAS_BLOWFISH 55226048Sobrien { "blf", crypt_blowfish, "$2" }, 56226048Sobrien#endif 57226048Sobrien { "nth", crypt_nthash, "$3$" }, 58226048Sobrien { "sha256", crypt_sha256, "$5$" }, 59226048Sobrien { "sha512", crypt_sha512, "$6$" }, 60330569Sgordon#ifdef HAS_DES 61226048Sobrien { "des", crypt_des, "_" }, 62226048Sobrien#endif 63226048Sobrien 64226048Sobrien /* sentinel */ 65226048Sobrien { NULL, NULL, NULL } 66226048Sobrien}; 67226048Sobrien 68226048Sobrienstatic const struct crypt_format *crypt_format = 69226048Sobrien &crypt_formats[(sizeof crypt_formats / sizeof *crypt_formats) - 2]; 70226048Sobrien 71226048Sobrien#define DES_SALT_ALPHABET \ 72226048Sobrien "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 73226048Sobrien 74226048Sobrien/* 75226048Sobrien * Returns the name of the currently selected format. 76226048Sobrien */ 77226048Sobrienconst char * 78226048Sobriencrypt_get_format(void) 79226048Sobrien{ 80226048Sobrien 81226048Sobrien return (crypt_format->name); 82226048Sobrien} 83226048Sobrien 84226048Sobrien/* 85226048Sobrien * Selects the format to use for subsequent crypt(3) invocations. 86226048Sobrien */ 87226048Sobrienint 88226048Sobriencrypt_set_format(const char *format) 89226048Sobrien{ 90226048Sobrien const struct crypt_format *cf; 91226048Sobrien 92226048Sobrien for (cf = crypt_formats; cf->name != NULL; ++cf) { 93226048Sobrien if (strcasecmp(cf->name, format) == 0) { 94226048Sobrien crypt_format = cf; 95226048Sobrien return (1); 96226048Sobrien } 97226048Sobrien } 98226048Sobrien return (0); 99226048Sobrien} 100226048Sobrien 101226048Sobrien/* 102226048Sobrien * Hash the given password with the given salt. If the salt begins with a 103226048Sobrien * magic string (e.g. "$6$" for sha512), the corresponding format is used; 104226048Sobrien * otherwise, the currently selected format is used. 105226048Sobrien */ 106267843Sdelphijchar * 107267843Sdelphijcrypt(const char *passwd, const char *salt) 108267843Sdelphij{ 109267843Sdelphij const struct crypt_format *cf; 110267843Sdelphij#ifdef HAS_DES 111267843Sdelphij int len; 112267843Sdelphij#endif 113267843Sdelphij 114267843Sdelphij for (cf = crypt_formats; cf->name != NULL; ++cf) 115267843Sdelphij if (cf->magic != NULL && strstr(salt, cf->magic) == salt) 116267843Sdelphij return (cf->func(passwd, salt)); 117267843Sdelphij#ifdef HAS_DES 118 len = strlen(salt); 119 if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) 120 return (crypt_des(passwd, salt)); 121#endif 122 return (crypt_format->func(passwd, salt)); 123} 124