1265879Sdes/*- 2265879Sdes * Copyright (c) 1999 Mark Murray 3265879Sdes * Copyright (c) 2014 Dag-Erling Sm��rgrav 4265879Sdes * All rights reserved. 543092Smarkm * 651462Smarkm * Redistribution and use in source and binary forms, with or without 751462Smarkm * modification, are permitted provided that the following conditions 851462Smarkm * are met: 951462Smarkm * 1. Redistributions of source code must retain the above copyright 1051462Smarkm * notice, this list of conditions and the following disclaimer. 1151462Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1251462Smarkm * notice, this list of conditions and the following disclaimer in the 1351462Smarkm * documentation and/or other materials provided with the distribution. 1451462Smarkm * 1551462Smarkm * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND 1651462Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1751462Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1851462Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE 1951462Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2051462Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2151462Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2251462Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2351462Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2451462Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2551462Smarkm * SUCH DAMAGE. 2642981Sbrandon */ 2742981Sbrandon 2883551Sdillon#include <sys/cdefs.h> 2983551Sdillon__FBSDID("$FreeBSD$"); 3042981Sbrandon 3170419Speter#include <sys/types.h> 32265879Sdes 33265879Sdes#include <libutil.h> 3417141Sjkh#include <string.h> 3591754Smarkm#include <unistd.h> 36265879Sdes 3751462Smarkm#include "crypt.h" 381984Scsgr 39265879Sdes/* 40273187Sdes * List of supported crypt(3) formats. 41273187Sdes * 42273187Sdes * The default algorithm is the last entry in the list (second-to-last 43273187Sdes * array element since the last is a sentinel). The reason for placing 44273187Sdes * the default last rather than first is that DES needs to be at the 45273187Sdes * bottom for the algorithm guessing logic in crypt(3) to work correctly, 46273187Sdes * and it needs to be the default for backward compatibility. 47265879Sdes */ 48265879Sdesstatic const struct crypt_format { 4964918Sgreen const char *const name; 5064918Sgreen char *(*const func)(const char *, const char *); 5164918Sgreen const char *const magic; 52265879Sdes} crypt_formats[] = { 53265879Sdes { "md5", crypt_md5, "$1$" }, 5474106Smarkm#ifdef HAS_BLOWFISH 55265879Sdes { "blf", crypt_blowfish, "$2" }, 5674106Smarkm#endif 57265879Sdes { "nth", crypt_nthash, "$3$" }, 58265879Sdes { "sha256", crypt_sha256, "$5$" }, 59273187Sdes { "sha512", crypt_sha512, "$6$" }, 60236967Sdes#ifdef HAS_DES 61265879Sdes { "des", crypt_des, "_" }, 62236967Sdes#endif 63236967Sdes 64265879Sdes /* sentinel */ 65265879Sdes { NULL, NULL, NULL } 66265879Sdes}; 6764918Sgreen 68273187Sdesstatic const struct crypt_format *crypt_format = 69273187Sdes &crypt_formats[(sizeof crypt_formats / sizeof *crypt_formats) - 2]; 7070419Speter 71265879Sdes#define DES_SALT_ALPHABET \ 72265879Sdes "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 7370419Speter 74265879Sdes/* 75265879Sdes * Returns the name of the currently selected format. 76265879Sdes */ 7764918Sgreenconst char * 7870419Spetercrypt_get_format(void) 7970419Speter{ 8064918Sgreen 81265879Sdes return (crypt_format->name); 8264918Sgreen} 8364918Sgreen 84265879Sdes/* 85265879Sdes * Selects the format to use for subsequent crypt(3) invocations. 86265879Sdes */ 8764918Sgreenint 88265879Sdescrypt_set_format(const char *format) 8970419Speter{ 90265879Sdes const struct crypt_format *cf; 9164918Sgreen 92265879Sdes for (cf = crypt_formats; cf->name != NULL; ++cf) { 93265879Sdes if (strcasecmp(cf->name, format) == 0) { 94265879Sdes crypt_format = cf; 9564918Sgreen return (1); 9664918Sgreen } 9764918Sgreen } 9864918Sgreen return (0); 9964918Sgreen} 10064918Sgreen 101265879Sdes/* 102265879Sdes * Hash the given password with the given salt. If the salt begins with a 103265879Sdes * magic string (e.g. "$6$" for sha512), the corresponding format is used; 104265879Sdes * otherwise, the currently selected format is used. 105265879Sdes */ 10643092Smarkmchar * 10791754Smarkmcrypt(const char *passwd, const char *salt) 1081984Scsgr{ 109265879Sdes const struct crypt_format *cf; 110267111Sume#ifdef HAS_DES 111267111Sume int len; 112267111Sume#endif 11364918Sgreen 114265879Sdes for (cf = crypt_formats; cf->name != NULL; ++cf) 115265879Sdes if (cf->magic != NULL && strstr(salt, cf->magic) == salt) 116265879Sdes return (cf->func(passwd, salt)); 117265879Sdes#ifdef HAS_DES 118267111Sume len = strlen(salt); 119267111Sume if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) 120265879Sdes return (crypt_des(passwd, salt)); 121265879Sdes#endif 122265879Sdes return (crypt_format->func(passwd, salt)); 1231984Scsgr} 124