/* * SPL - The SPL Programming Language * Copyright (C) 2004, 2005 Clifford Wolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * mod_crypt.c: A simple frontend to the C crypt() function */ /** * A crypt() function (like in C). */ #include #include #include #include #include #include #include "spl.h" #include "compat.h" extern void SPL_ABI(spl_mod_crypt_init)(struct spl_vm *vm, struct spl_module *mod, int restore); extern void SPL_ABI(spl_mod_crypt_done)(struct spl_vm *vm, struct spl_module *mod); /** * This function is a frontend to the C crypt() function. If salt is not given * or shorten then 2 characters then a random salt ([a-zA-Z0-9./]{2}) is used. */ // builtin crypt(key, salt) static struct spl_node *handler_crypt(struct spl_task *task, void UNUSED(*data)) { char *key = spl_clib_get_string(task); char *salt = spl_clib_get_string(task); char saltset[] = "abcdefghijklmnnopqrstuvwxyzABCDEFGHIJKLMNNOPQRSTUVWXYZ0123456789./"; unsigned char random_byte; char random_salt[12]; int generate_md5 = 0; int i; if (strlen(salt) == 3 && !strcmp(salt, "$1$")) generate_md5 = 1; if (generate_md5 || strlen(salt) < 2) { int fd = open("/dev/urandom", O_RDONLY); if (generate_md5) { random_salt[0] = salt[0]; random_salt[1] = salt[1]; random_salt[2] = salt[2]; for (i=3; i<11; i++) { if (fd >= 0) { read(fd, &random_byte, 1); random_salt[i] = saltset[random_byte % sizeof(saltset)]; } else random_salt[i] = 'X'; } random_salt[11] = 0; } else { if (fd >= 0) { read(fd, &random_byte, 1); random_salt[0] = saltset[random_byte % sizeof(saltset)]; read(fd, &random_byte, 1); random_salt[1] = saltset[random_byte % sizeof(saltset)]; } else { random_salt[0] = 'X'; random_salt[1] = 'X'; } random_salt[2] = 0; } if (fd >= 0) close(fd); salt = random_salt; } return SPL_NEW_STRING_DUP(crypt(key, salt)); } void SPL_ABI(spl_mod_crypt_init)(struct spl_vm *vm, struct spl_module UNUSED(*mod), int UNUSED(restore)) { spl_clib_reg(vm, "crypt", handler_crypt, 0); } void SPL_ABI(spl_mod_crypt_done)(struct spl_vm UNUSED(*vm), struct spl_module UNUSED(*mod)) { return; }