1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/*
* Copyright (c) 2006 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "Python.h"
#if defined(_MSC_VER)
typedef unsigned __int8 u_int8_t;
typedef unsigned __int16 u_int16_t;
typedef unsigned __int32 u_int32_t;
#endif
/* $Id$ */
/* Import */
char *pybc_bcrypt(const char *, const char *);
void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
PyDoc_STRVAR(bcrypt_encode_salt_doc,
"encode_salt(csalt, log_rounds) -> encoded_salt\n\
Encode a raw binary salt and the specified log2(rounds) as a\n\
standard bcrypt text salt. Used internally by bcrypt.gensalt()\n");
static PyObject *
bcrypt_encode_salt(PyObject *self, PyObject *args, PyObject *kw_args)
{
static char *keywords[] = { "csalt", "log_rounds", NULL };
char *csalt = NULL;
int csaltlen = -1;
long log_rounds = -1;
char ret[64];
if (!PyArg_ParseTupleAndKeywords(args, kw_args, "s#l:encode_salt",
keywords, &csalt, &csaltlen, &log_rounds))
return NULL;
if (csaltlen != 16) {
PyErr_SetString(PyExc_ValueError, "Invalid salt length");
return NULL;
}
if (log_rounds < 4 || log_rounds > 31) {
PyErr_SetString(PyExc_ValueError, "Invalid number of rounds");
return NULL;
}
encode_salt(ret, csalt, csaltlen, log_rounds);
return PyString_FromString(ret);
}
PyDoc_STRVAR(bcrypt_hashpw_doc,
"hashpw(password, salt) -> hashed_password\n\
Hash the specified password and the salt using the OpenBSD\n\
Blowfish password hashing algorithm. Returns the hashed password.\n");
static PyObject *
bcrypt_hashpw(PyObject *self, PyObject *args, PyObject *kw_args)
{
static char *keywords[] = { "password", "salt", NULL };
char *password = NULL, *salt = NULL;
char *ret;
char *password_copy;
char *salt_copy;
if (!PyArg_ParseTupleAndKeywords(args, kw_args, "ss:hashpw", keywords,
&password, &salt))
return NULL;
password_copy = strdup(password);
salt_copy = strdup(salt);
Py_BEGIN_ALLOW_THREADS;
ret = pybc_bcrypt(password_copy, salt_copy);
Py_END_ALLOW_THREADS;
free(password_copy);
free(salt_copy);
if ((ret == NULL) ||
strcmp(ret, ":") == 0) {
PyErr_SetString(PyExc_ValueError, "Invalid salt");
return NULL;
}
return PyString_FromString(ret);
}
static PyMethodDef bcrypt_methods[] = {
{ "hashpw", (PyCFunction)bcrypt_hashpw,
METH_VARARGS|METH_KEYWORDS, bcrypt_hashpw_doc },
{ "encode_salt", (PyCFunction)bcrypt_encode_salt,
METH_VARARGS|METH_KEYWORDS, bcrypt_encode_salt_doc },
{NULL, NULL} /* sentinel */
};
PyDoc_STRVAR(module_doc, "Internal module used by bcrypt.\n");
PyMODINIT_FUNC
init_bcrypt(void)
{
PyObject *m;
m = Py_InitModule3("bcrypt._bcrypt", bcrypt_methods, module_doc);
PyModule_AddStringConstant(m, "__version__", "0.1");
}
|