1265880Sdes/*- 2265880Sdes * Copyright (c) 1999 Mark Murray 3265880Sdes * Copyright (c) 2014 Dag-Erling Sm��rgrav 4265880Sdes * 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> 32265880Sdes 33265880Sdes#include <libutil.h> 3417141Sjkh#include <string.h> 3591754Smarkm#include <unistd.h> 36265880Sdes 3751462Smarkm#include "crypt.h" 381984Scsgr 39265880Sdes/* 40273438Sdelphij * List of supported crypt(3) formats. 41273438Sdelphij * 42273438Sdelphij * The default algorithm is the last entry in the list (second-to-last 43273438Sdelphij * array element since the last is a sentinel). The reason for placing 44273438Sdelphij * the default last rather than first is that DES needs to be at the 45273438Sdelphij * bottom for the algorithm guessing logic in crypt(3) to work correctly, 46273438Sdelphij * and it needs to be the default for backward compatibility. 47265880Sdes */ 48265880Sdesstatic const struct crypt_format { 4964918Sgreen const char *const name; 5064918Sgreen char *(*const func)(const char *, const char *); 5164918Sgreen const char *const magic; 52265880Sdes} crypt_formats[] = { 53265880Sdes { "md5", crypt_md5, "$1$" }, 5474106Smarkm#ifdef HAS_BLOWFISH 55265880Sdes { "blf", crypt_blowfish, "$2" }, 5674106Smarkm#endif 57265880Sdes { "nth", crypt_nthash, "$3$" }, 58265880Sdes { "sha256", crypt_sha256, "$5$" }, 59273438Sdelphij { "sha512", crypt_sha512, "$6$" }, 60238481Sdes#ifdef HAS_DES 61265880Sdes { "des", crypt_des, "_" }, 62238481Sdes#endif 63238481Sdes 64265880Sdes /* sentinel */ 65265880Sdes { NULL, NULL, NULL } 66265880Sdes}; 6764918Sgreen 68273438Sdelphijstatic const struct crypt_format *crypt_format = 69273438Sdelphij &crypt_formats[(sizeof crypt_formats / sizeof *crypt_formats) - 2]; 7070419Speter 71265880Sdes#define DES_SALT_ALPHABET \ 72265880Sdes "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 7370419Speter 74265880Sdes/* 75265880Sdes * Returns the name of the currently selected format. 76265880Sdes */ 7764918Sgreenconst char * 7870419Spetercrypt_get_format(void) 7970419Speter{ 8064918Sgreen 81265880Sdes return (crypt_format->name); 8264918Sgreen} 8364918Sgreen 84265880Sdes/* 85265880Sdes * Selects the format to use for subsequent crypt(3) invocations. 86265880Sdes */ 8764918Sgreenint 88265880Sdescrypt_set_format(const char *format) 8970419Speter{ 90265880Sdes const struct crypt_format *cf; 9164918Sgreen 92265880Sdes for (cf = crypt_formats; cf->name != NULL; ++cf) { 93265880Sdes if (strcasecmp(cf->name, format) == 0) { 94265880Sdes crypt_format = cf; 9564918Sgreen return (1); 9664918Sgreen } 9764918Sgreen } 9864918Sgreen return (0); 9964918Sgreen} 10064918Sgreen 101265880Sdes/* 102265880Sdes * Hash the given password with the given salt. If the salt begins with a 103265880Sdes * magic string (e.g. "$6$" for sha512), the corresponding format is used; 104265880Sdes * otherwise, the currently selected format is used. 105265880Sdes */ 10643092Smarkmchar * 10791754Smarkmcrypt(const char *passwd, const char *salt) 1081984Scsgr{ 109265880Sdes const struct crypt_format *cf; 110267116Sume#ifdef HAS_DES 111267116Sume int len; 112267116Sume#endif 11364918Sgreen 114265880Sdes for (cf = crypt_formats; cf->name != NULL; ++cf) 115265880Sdes if (cf->magic != NULL && strstr(salt, cf->magic) == salt) 116265880Sdes return (cf->func(passwd, salt)); 117265880Sdes#ifdef HAS_DES 118267116Sume len = strlen(salt); 119267116Sume if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) 120265880Sdes return (crypt_des(passwd, salt)); 121265880Sdes#endif 122265880Sdes return (crypt_format->func(passwd, salt)); 1231984Scsgr} 124