11984Scsgr/*
251462Smarkm * Copyright (c) 1999
351462Smarkm *      Mark Murray.  All rights reserved.
443092Smarkm *
551462Smarkm * Redistribution and use in source and binary forms, with or without
651462Smarkm * modification, are permitted provided that the following conditions
751462Smarkm * are met:
851462Smarkm * 1. Redistributions of source code must retain the above copyright
951462Smarkm *    notice, this list of conditions and the following disclaimer.
1051462Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1151462Smarkm *    notice, this list of conditions and the following disclaimer in the
1251462Smarkm *    documentation and/or other materials provided with the distribution.
1351462Smarkm *
1451462Smarkm * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND
1551462Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1651462Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1751462Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE
1851462Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1951462Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2051462Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2151462Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2251462Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2351462Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2451462Smarkm * SUCH DAMAGE.
2542981Sbrandon */
2642981Sbrandon
2783551Sdillon#include <sys/cdefs.h>
2883551Sdillon__FBSDID("$FreeBSD$");
2942981Sbrandon
3070419Speter#include <sys/types.h>
3117141Sjkh#include <string.h>
3270419Speter#include <libutil.h>
3391754Smarkm#include <unistd.h>
3451462Smarkm#include "crypt.h"
351984Scsgr
3664918Sgreenstatic const struct {
3764918Sgreen	const char *const name;
3864918Sgreen	char *(*const func)(const char *, const char *);
3964918Sgreen	const char *const magic;
4064918Sgreen} crypt_types[] = {
4170419Speter#ifdef HAS_DES
4270419Speter	{
4364918Sgreen		"des",
4464918Sgreen		crypt_des,
4564918Sgreen		NULL
4664918Sgreen	},
4765053Sgreen#endif
4864918Sgreen	{
4970421Speter		"md5",
5070421Speter		crypt_md5,
5170421Speter		"$1$"
5270421Speter	},
5374106Smarkm#ifdef HAS_BLOWFISH
5470421Speter	{
5574106Smarkm		"blf",
5674106Smarkm		crypt_blowfish,
5774106Smarkm		"$2"
5874106Smarkm	},
5974106Smarkm#endif
6074106Smarkm	{
61115720Smarkm		"nth",
62115720Smarkm		crypt_nthash,
63115720Smarkm		"$3$"
64115720Smarkm	},
65115720Smarkm	{
66220497Smarkm		"sha256",
67221471Sobrien		crypt_sha256,
68220497Smarkm		"$5$"
69220497Smarkm	},
70220497Smarkm	{
71220497Smarkm		"sha512",
72221471Sobrien		crypt_sha512,
73220497Smarkm		"$6$"
74220497Smarkm	},
75220497Smarkm	{
7664918Sgreen		NULL,
7791754Smarkm		NULL,
7864918Sgreen		NULL
7964918Sgreen	}
8064918Sgreen};
8164918Sgreen
82236967Sdes#ifdef HAS_DES
83236967Sdes#define CRYPT_DEFAULT	"des"
84236967Sdes#else
85236967Sdes#define CRYPT_DEFAULT	"md5"
86236967Sdes#endif
87236967Sdes
8870419Speterstatic int crypt_type = -1;
8964918Sgreen
9070419Speterstatic void
9170419Spetercrypt_setdefault(void)
9270419Speter{
9391754Smarkm	size_t i;
9470419Speter
9570419Speter	if (crypt_type != -1)
9670419Speter		return;
9770419Speter	for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
98236967Sdes		if (strcmp(CRYPT_DEFAULT, crypt_types[i].name) == 0) {
9991754Smarkm			crypt_type = (int)i;
10070419Speter			return;
10170419Speter		}
10270419Speter	}
10370419Speter	crypt_type = 0;
10470419Speter}
10570419Speter
10664918Sgreenconst char *
10770419Spetercrypt_get_format(void)
10870419Speter{
10964918Sgreen
11070419Speter	crypt_setdefault();
11164918Sgreen	return (crypt_types[crypt_type].name);
11264918Sgreen}
11364918Sgreen
11464918Sgreenint
11591754Smarkmcrypt_set_format(const char *type)
11670419Speter{
11791754Smarkm	size_t i;
11864918Sgreen
11970419Speter	crypt_setdefault();
12064918Sgreen	for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
12164918Sgreen		if (strcmp(type, crypt_types[i].name) == 0) {
12291754Smarkm			crypt_type = (int)i;
12364918Sgreen			return (1);
12464918Sgreen		}
12564918Sgreen	}
12664918Sgreen	return (0);
12764918Sgreen}
12864918Sgreen
12943092Smarkmchar *
13091754Smarkmcrypt(const char *passwd, const char *salt)
1311984Scsgr{
13291754Smarkm	size_t i;
13364918Sgreen
13470419Speter	crypt_setdefault();
13564918Sgreen	for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) {
13664918Sgreen		if (crypt_types[i].magic != NULL && strncmp(salt,
13764918Sgreen		    crypt_types[i].magic, strlen(crypt_types[i].magic)) == 0)
13864918Sgreen			return (crypt_types[i].func(passwd, salt));
13964918Sgreen	}
14064918Sgreen	return (crypt_types[crypt_type].func(passwd, salt));
1411984Scsgr}
142