git ssb

0+

dangerousbeans / %aPBe2k3ugtjBr4rrsU1…



Tree: 054888806bcede3049ccb38bf421ec7986973657

Files: 054888806bcede3049ccb38bf421ec7986973657 / ext / mri / wrapper.c

7098 bytesRaw
1/*
2 * Written by Solar Designer and placed in the public domain.
3 * See crypt_blowfish.c for more information.
4 */
5
6#include <stdlib.h>
7#include <string.h>
8
9#include <errno.h>
10#ifndef __set_errno
11#define __set_errno(val) errno = (val)
12#endif
13
14#ifdef TEST
15#include <stdio.h>
16#include <unistd.h>
17#include <signal.h>
18#include <time.h>
19#include <sys/time.h>
20#include <sys/times.h>
21#ifdef TEST_THREADS
22#include <pthread.h>
23#endif
24#endif
25
26#include <ruby.h>
27#ifdef HAVE_RUBY_UTIL_H
28#include <ruby/util.h>
29#else
30#include <util.h>
31#endif
32
33#define CRYPT_OUTPUT_SIZE (7 + 22 + 31 + 1)
34#define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1)
35
36#if defined(__GLIBC__) && defined(_LIBC)
37#define __SKIP_GNU
38#endif
39#include "ow-crypt.h"
40
41extern char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
42 char *output, int size);
43extern char *_crypt_gensalt_blowfish_rn(unsigned long count,
44 __CONST char *input, int size, char *output, int output_size);
45
46extern unsigned char _crypt_itoa64[];
47extern char *_crypt_gensalt_traditional_rn(unsigned long count,
48 __CONST char *input, int size, char *output, int output_size);
49extern char *_crypt_gensalt_extended_rn(unsigned long count,
50 __CONST char *input, int size, char *output, int output_size);
51extern char *_crypt_gensalt_md5_rn(unsigned long count,
52 __CONST char *input, int size, char *output, int output_size);
53
54#if defined(__GLIBC__) && defined(_LIBC)
55/* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */
56#include "crypt.h"
57extern char *__md5_crypt_r(const char *key, const char *salt,
58 char *buffer, int buflen);
59/* crypt-entry.c needs to be patched to define __des_crypt_r rather than
60 * __crypt_r, and not define crypt_r and crypt at all */
61extern char *__des_crypt_r(const char *key, const char *salt,
62 struct crypt_data *data);
63extern struct crypt_data _ufc_foobar;
64#endif
65
66static int _crypt_data_alloc(void **data, int *size, int need)
67{
68 void *updated;
69
70 if (*data && *size >= need) return 0;
71
72 updated = realloc(*data, need);
73
74 if (!updated) {
75#ifndef __GLIBC__
76 /* realloc(3) on glibc sets errno, so we don't need to bother */
77 __set_errno(ENOMEM);
78#endif
79 return -1;
80 }
81
82#if defined(__GLIBC__) && defined(_LIBC)
83 if (need >= sizeof(struct crypt_data))
84 ((struct crypt_data *)updated)->initialized = 0;
85#endif
86
87 *data = updated;
88 *size = need;
89
90 return 0;
91}
92
93static char *_crypt_retval_magic(char *retval, __CONST char *setting,
94 char *output)
95{
96 if (retval) return retval;
97
98 output[0] = '*';
99 output[1] = '0';
100 output[2] = '\0';
101
102 if (setting[0] == '*' && setting[1] == '0')
103 output[1] = '1';
104
105 return output;
106}
107
108#if defined(__GLIBC__) && defined(_LIBC)
109/*
110 * Applications may re-use the same instance of struct crypt_data without
111 * resetting the initialized field in order to let crypt_r() skip some of
112 * its initialization code. Thus, it is important that our multiple hashing
113 * algorithms either don't conflict with each other in their use of the
114 * data area or reset the initialized field themselves whenever required.
115 * Currently, the hashing algorithms simply have no conflicts: the first
116 * field of struct crypt_data is the 128-byte large DES key schedule which
117 * __des_crypt_r() calculates each time it is called while the two other
118 * hashing algorithms use less than 128 bytes of the data area.
119 */
120
121char *__crypt_rn(__const char *key, __const char *setting,
122 void *data, int size)
123{
124 if (setting[0] == '$' && setting[1] == '2')
125 return _crypt_blowfish_rn(key, setting, (char *)data, size);
126 if (setting[0] == '$' && setting[1] == '1')
127 return __md5_crypt_r(key, setting, (char *)data, size);
128 if (setting[0] == '$' || setting[0] == '_') {
129 __set_errno(EINVAL);
130 return NULL;
131 }
132 if (size >= sizeof(struct crypt_data))
133 return __des_crypt_r(key, setting, (struct crypt_data *)data);
134 __set_errno(ERANGE);
135 return NULL;
136}
137
138char *__crypt_ra(__const char *key, __const char *setting,
139 void **data, int *size)
140{
141 if (setting[0] == '$' && setting[1] == '2') {
142 if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
143 return NULL;
144 return _crypt_blowfish_rn(key, setting, (char *)*data, *size);
145 }
146 if (setting[0] == '$' && setting[1] == '1') {
147 if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
148 return NULL;
149 return __md5_crypt_r(key, setting, (char *)*data, *size);
150 }
151 if (setting[0] == '$' || setting[0] == '_') {
152 __set_errno(EINVAL);
153 return NULL;
154 }
155 if (_crypt_data_alloc(data, size, sizeof(struct crypt_data)))
156 return NULL;
157 return __des_crypt_r(key, setting, (struct crypt_data *)*data);
158}
159
160char *__crypt_r(__const char *key, __const char *setting,
161 struct crypt_data *data)
162{
163 return _crypt_retval_magic(
164 __crypt_rn(key, setting, data, sizeof(*data)),
165 setting, (char *)data);
166}
167
168char *__crypt(__const char *key, __const char *setting)
169{
170 return _crypt_retval_magic(
171 __crypt_rn(key, setting, &_ufc_foobar, sizeof(_ufc_foobar)),
172 setting, (char *)&_ufc_foobar);
173}
174#else
175char *crypt_rn(__CONST char *key, __CONST char *setting, void *data, int size)
176{
177 return _crypt_blowfish_rn(key, setting, (char *)data, size);
178}
179
180char *crypt_ra(__CONST char *key, __CONST char *setting,
181 void **data, int *size)
182{
183 if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
184 return NULL;
185 return _crypt_blowfish_rn(key, setting, (char *)*data, *size);
186}
187
188char *crypt_r(__CONST char *key, __CONST char *setting, void *data)
189{
190 return _crypt_retval_magic(
191 crypt_rn(key, setting, data, CRYPT_OUTPUT_SIZE),
192 setting, (char *)data);
193}
194
195#define __crypt_gensalt_rn crypt_gensalt_rn
196#define __crypt_gensalt_ra crypt_gensalt_ra
197#define __crypt_gensalt crypt_gensalt
198#endif
199
200char *__crypt_gensalt_rn(__CONST char *prefix, unsigned long count,
201 __CONST char *input, int size, char *output, int output_size)
202{
203 char *(*use)(unsigned long count,
204 __CONST char *input, int size, char *output, int output_size);
205
206 /* This may be supported on some platforms in the future */
207 if (!input) {
208 __set_errno(EINVAL);
209 return NULL;
210 }
211
212 if (!strncmp(prefix, "$2a$", 4))
213 use = _crypt_gensalt_blowfish_rn;
214 else
215 if (!strncmp(prefix, "$1$", 3))
216 use = _crypt_gensalt_md5_rn;
217 else
218 if (prefix[0] == '_')
219 use = _crypt_gensalt_extended_rn;
220 else
221 if (!prefix[0] ||
222 (prefix[0] && prefix[1] &&
223 memchr(_crypt_itoa64, prefix[0], 64) &&
224 memchr(_crypt_itoa64, prefix[1], 64)))
225 use = _crypt_gensalt_traditional_rn;
226 else {
227 __set_errno(EINVAL);
228 return NULL;
229 }
230
231 return use(count, input, size, output, output_size);
232}
233
234char *__crypt_gensalt_ra(__CONST char *prefix, unsigned long count,
235 __CONST char *input, int size)
236{
237 char output[CRYPT_GENSALT_OUTPUT_SIZE];
238 char *retval;
239
240 retval = __crypt_gensalt_rn(prefix, count,
241 input, size, output, sizeof(output));
242
243 if (retval) {
244 retval = ruby_strdup(retval);
245#ifndef __GLIBC__
246 /* strdup(3) on glibc sets errno, so we don't need to bother */
247 if (!retval)
248 __set_errno(ENOMEM);
249#endif
250 }
251
252 return retval;
253}
254
255char *__crypt_gensalt(__CONST char *prefix, unsigned long count,
256 __CONST char *input, int size)
257{
258 static char output[CRYPT_GENSALT_OUTPUT_SIZE];
259
260 return __crypt_gensalt_rn(prefix, count,
261 input, size, output, sizeof(output));
262}
263

Built with git-ssb-web