// Copyright 2015-2016 Luke Shumaker . // // This is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This software 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 Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this manual; if not, see // . // Package crypt provides an interface to the POSIX CRYPT option // group. // // Actually, it doesn't yet support encrypt() or setkey() package crypt import "unsafe" /* #cgo LDFLAGS: -lcrypt #define _GNU_SOURCE // for crypt_r(3) in crypt.h #include // for free(3) #include // for crypt_r(3) #include // for strdup(3) and memset(3) char *c_crypt(const char *key, const char *salt) { struct crypt_data data; data.initialized = 0; char *hash = crypt_r(key, salt, &data); if (hash) hash = strdup(hash); memset(&data, 0, sizeof(data)); return hash; } */ import "C" func Crypt(key string, salt string) string { ckey := C.CString(key) defer C.free(unsafe.Pointer(ckey)) csalt := C.CString(salt) defer C.free(unsafe.Pointer(csalt)) chash := C.c_crypt(ckey, csalt) defer C.free(unsafe.Pointer(chash)) hash := C.GoString(chash) return hash } func SaltOk(salt string) bool { if len(salt) < 2 { return false } hash := Crypt("", salt) if len(hash) < 2 { return false } return salt[0] == hash[0] && salt[1] == hash[1] } const SaltAlphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"