crypt.c revision 266813
162587Sitojun/*- 295023Ssuz * Copyright (c) 1999 Mark Murray 362587Sitojun * Copyright (c) 2014 Dag-Erling Sm��rgrav 453541Sshin * All rights reserved. 553541Sshin * 653541Sshin * Redistribution and use in source and binary forms, with or without 753541Sshin * modification, are permitted provided that the following conditions 853541Sshin * are met: 953541Sshin * 1. Redistributions of source code must retain the above copyright 1053541Sshin * notice, this list of conditions and the following disclaimer. 1153541Sshin * 2. Redistributions in binary form must reproduce the above copyright 1253541Sshin * notice, this list of conditions and the following disclaimer in the 1353541Sshin * documentation and/or other materials provided with the distribution. 1453541Sshin * 1553541Sshin * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND 1653541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1753541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1853541Sshin * ARE DISCLAIMED. IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE 1953541Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2053541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2153541Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2253541Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2353541Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2453541Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2553541Sshin * SUCH DAMAGE. 2653541Sshin */ 2753541Sshin 2853541Sshin#include <sys/cdefs.h> 2953541Sshin__FBSDID("$FreeBSD: head/lib/libcrypt/crypt.c 266813 2014-05-28 16:50:18Z ume $"); 3053541Sshin 3153541Sshin#include <sys/types.h> 3253541Sshin 3353541Sshin#include <libutil.h> 3453541Sshin#include <string.h> 3553541Sshin#include <unistd.h> 3653541Sshin 3753541Sshin#include "crypt.h" 3853541Sshin 3953541Sshin/* 4053541Sshin * List of supported crypt(3) formats. The first element in the list will 4153541Sshin * be the default. 4253541Sshin */ 4353541Sshinstatic const struct crypt_format { 4453541Sshin const char *const name; 4553541Sshin char *(*const func)(const char *, const char *); 4653541Sshin const char *const magic; 4753541Sshin} crypt_formats[] = { 4853541Sshin /* default format */ 4953541Sshin { "sha512", crypt_sha512, "$6$" }, 5053541Sshin 5153541Sshin /* other supported formats */ 5253541Sshin { "md5", crypt_md5, "$1$" }, 5353541Sshin#ifdef HAS_BLOWFISH 5453541Sshin { "blf", crypt_blowfish, "$2" }, 5553541Sshin#endif 5653541Sshin { "nth", crypt_nthash, "$3$" }, 5753541Sshin { "sha256", crypt_sha256, "$5$" }, 5853541Sshin#ifdef HAS_DES 5953541Sshin { "des", crypt_des, "_" }, 6053541Sshin#endif 6153541Sshin 6253541Sshin /* sentinel */ 6353541Sshin { NULL, NULL, NULL } 6453541Sshin}; 6553541Sshin 6653541Sshinstatic const struct crypt_format *crypt_format = &crypt_formats[0]; 6753541Sshin 6862587Sitojun#define DES_SALT_ALPHABET \ 6962587Sitojun "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 7062587Sitojun 7155009Sshin/* 7264060Sdarrenr * Returns the name of the currently selected format. 73120649Sume */ 7455009Sshinconst char * 7553541Sshincrypt_get_format(void) 7653541Sshin{ 7778064Sume 7853541Sshin return (crypt_format->name); 7983366Sjulian} 8053541Sshin 8153541Sshin/* 8253541Sshin * Selects the format to use for subsequent crypt(3) invocations. 8353541Sshin */ 8453541Sshinint 8553541Sshincrypt_set_format(const char *format) 8653541Sshin{ 8753541Sshin const struct crypt_format *cf; 8853541Sshin 8953541Sshin for (cf = crypt_formats; cf->name != NULL; ++cf) { 9053541Sshin if (strcasecmp(cf->name, format) == 0) { 9153541Sshin crypt_format = cf; 9253541Sshin return (1); 9353541Sshin } 9464060Sdarrenr } 9564060Sdarrenr return (0); 9664060Sdarrenr} 9753541Sshin 9853541Sshin/* 9953541Sshin * Hash the given password with the given salt. If the salt begins with a 10062587Sitojun * magic string (e.g. "$6$" for sha512), the corresponding format is used; 10153541Sshin * otherwise, the currently selected format is used. 10253541Sshin */ 10395023Ssuzchar * 10462587Sitojuncrypt(const char *passwd, const char *salt) 10553541Sshin{ 10653541Sshin const struct crypt_format *cf; 10762587Sitojun#ifdef HAS_DES 10862587Sitojun int len; 10953541Sshin#endif 11053541Sshin 11153541Sshin for (cf = crypt_formats; cf->name != NULL; ++cf) 11253541Sshin if (cf->magic != NULL && strstr(salt, cf->magic) == salt) 11378064Sume return (cf->func(passwd, salt)); 11478064Sume#ifdef HAS_DES 11578064Sume len = strlen(salt); 11678064Sume if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) 11778064Sume return (crypt_des(passwd, salt)); 11878064Sume#endif 11978064Sume return (crypt_format->func(passwd, salt)); 120105199Ssam} 121105199Ssam