crypt.c revision 267116
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: stable/9/lib/libcrypt/crypt.c 267116 2014-06-05 15:39:57Z ume $"); 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/* 40265880Sdes * List of supported crypt(3) formats. The first element in the list will 41265880Sdes * be the default. 42265880Sdes */ 43265880Sdesstatic const struct crypt_format { 4464918Sgreen const char *const name; 4564918Sgreen char *(*const func)(const char *, const char *); 4664918Sgreen const char *const magic; 47265880Sdes} crypt_formats[] = { 48265880Sdes /* default format */ 49265880Sdes { "sha512", crypt_sha512, "$6$" }, 50265880Sdes 51265880Sdes /* other supported formats */ 52265880Sdes { "md5", crypt_md5, "$1$" }, 5374106Smarkm#ifdef HAS_BLOWFISH 54265880Sdes { "blf", crypt_blowfish, "$2" }, 5574106Smarkm#endif 56265880Sdes { "nth", crypt_nthash, "$3$" }, 57265880Sdes { "sha256", crypt_sha256, "$5$" }, 58238481Sdes#ifdef HAS_DES 59265880Sdes { "des", crypt_des, "_" }, 60238481Sdes#endif 61238481Sdes 62265880Sdes /* sentinel */ 63265880Sdes { NULL, NULL, NULL } 64265880Sdes}; 6564918Sgreen 66265880Sdesstatic const struct crypt_format *crypt_format = &crypt_formats[0]; 6770419Speter 68265880Sdes#define DES_SALT_ALPHABET \ 69265880Sdes "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 7070419Speter 71265880Sdes/* 72265880Sdes * Returns the name of the currently selected format. 73265880Sdes */ 7464918Sgreenconst char * 7570419Spetercrypt_get_format(void) 7670419Speter{ 7764918Sgreen 78265880Sdes return (crypt_format->name); 7964918Sgreen} 8064918Sgreen 81265880Sdes/* 82265880Sdes * Selects the format to use for subsequent crypt(3) invocations. 83265880Sdes */ 8464918Sgreenint 85265880Sdescrypt_set_format(const char *format) 8670419Speter{ 87265880Sdes const struct crypt_format *cf; 8864918Sgreen 89265880Sdes for (cf = crypt_formats; cf->name != NULL; ++cf) { 90265880Sdes if (strcasecmp(cf->name, format) == 0) { 91265880Sdes crypt_format = cf; 9264918Sgreen return (1); 9364918Sgreen } 9464918Sgreen } 9564918Sgreen return (0); 9664918Sgreen} 9764918Sgreen 98265880Sdes/* 99265880Sdes * Hash the given password with the given salt. If the salt begins with a 100265880Sdes * magic string (e.g. "$6$" for sha512), the corresponding format is used; 101265880Sdes * otherwise, the currently selected format is used. 102265880Sdes */ 10343092Smarkmchar * 10491754Smarkmcrypt(const char *passwd, const char *salt) 1051984Scsgr{ 106265880Sdes const struct crypt_format *cf; 107267116Sume#ifdef HAS_DES 108267116Sume int len; 109267116Sume#endif 11064918Sgreen 111265880Sdes for (cf = crypt_formats; cf->name != NULL; ++cf) 112265880Sdes if (cf->magic != NULL && strstr(salt, cf->magic) == salt) 113265880Sdes return (cf->func(passwd, salt)); 114265880Sdes#ifdef HAS_DES 115267116Sume len = strlen(salt); 116267116Sume if ((len == 13 || len == 2) && strspn(salt, DES_SALT_ALPHABET) == len) 117265880Sdes return (crypt_des(passwd, salt)); 118265880Sdes#endif 119265880Sdes return (crypt_format->func(passwd, salt)); 1201984Scsgr} 121