bcrypt 3.1.7 → 3.1.20

Sign up to get free protection for your applications and to get access to all the features.
data/ext/mri/bcrypt_ext.c CHANGED
@@ -1,53 +1,110 @@
1
1
  #include <ruby.h>
2
2
  #include <ow-crypt.h>
3
3
 
4
+ #ifdef HAVE_RUBY_THREAD_H
5
+ #include <ruby/thread.h>
6
+ #endif
7
+
4
8
  static VALUE mBCrypt;
5
9
  static VALUE cBCryptEngine;
6
10
 
11
+ struct bc_salt_args {
12
+ const char * prefix;
13
+ unsigned long count;
14
+ const char * input;
15
+ int size;
16
+ };
17
+
18
+ static void * bc_salt_nogvl(void * ptr) {
19
+ struct bc_salt_args * args = ptr;
20
+
21
+ return crypt_gensalt_ra(args->prefix, args->count, args->input, args->size);
22
+ }
23
+
7
24
  /* Given a logarithmic cost parameter, generates a salt for use with +bc_crypt+.
8
25
  */
9
26
  static VALUE bc_salt(VALUE self, VALUE prefix, VALUE count, VALUE input) {
10
27
  char * salt;
11
28
  VALUE str_salt;
12
-
13
- salt = crypt_gensalt_ra(
14
- StringValuePtr(prefix),
15
- NUM2ULONG(count),
16
- NIL_P(input) ? NULL : StringValuePtr(input),
17
- NIL_P(input) ? 0 : RSTRING_LEN(input));
29
+ struct bc_salt_args args;
30
+
31
+ /* duplicate the parameters for thread safety. If another thread has a
32
+ * reference to the parameters and mutates them while we are working,
33
+ * that would be very bad. Duping the strings means that the reference
34
+ * isn't shared. */
35
+ prefix = rb_str_new_frozen(prefix);
36
+ input = rb_str_new_frozen(input);
37
+
38
+ args.prefix = StringValueCStr(prefix);
39
+ args.count = NUM2ULONG(count);
40
+ args.input = NIL_P(input) ? NULL : StringValuePtr(input);
41
+ args.size = NIL_P(input) ? 0 : RSTRING_LEN(input);
42
+
43
+ #ifdef HAVE_RUBY_THREAD_H
44
+ salt = rb_thread_call_without_gvl(bc_salt_nogvl, &args, NULL, NULL);
45
+ #else
46
+ salt = bc_salt_nogvl((void *)&args);
47
+ #endif
18
48
 
19
49
  if(!salt) return Qnil;
20
50
 
21
51
  str_salt = rb_str_new2(salt);
22
- xfree(salt);
52
+
53
+ RB_GC_GUARD(prefix);
54
+ RB_GC_GUARD(input);
55
+ free(salt);
23
56
 
24
57
  return str_salt;
25
58
  }
26
59
 
60
+ struct bc_crypt_args {
61
+ const char * key;
62
+ const char * setting;
63
+ void * data;
64
+ int size;
65
+ };
66
+
67
+ static void * bc_crypt_nogvl(void * ptr) {
68
+ struct bc_crypt_args * args = ptr;
69
+
70
+ return crypt_ra(args->key, args->setting, &args->data, &args->size);
71
+ }
72
+
27
73
  /* Given a secret and a salt, generates a salted hash (which you can then store safely).
28
74
  */
29
75
  static VALUE bc_crypt(VALUE self, VALUE key, VALUE setting) {
30
76
  char * value;
31
- void * data;
32
- int size;
33
77
  VALUE out;
34
78
 
35
- data = NULL;
36
- size = 0xDEADBEEF;
79
+ struct bc_crypt_args args;
37
80
 
38
81
  if(NIL_P(key) || NIL_P(setting)) return Qnil;
39
82
 
40
- value = crypt_ra(
41
- NIL_P(key) ? NULL : StringValuePtr(key),
42
- NIL_P(setting) ? NULL : StringValuePtr(setting),
43
- &data,
44
- &size);
83
+ /* duplicate the parameters for thread safety. If another thread has a
84
+ * reference to the parameters and mutates them while we are working,
85
+ * that would be very bad. Duping the strings means that the reference
86
+ * isn't shared. */
87
+ key = rb_str_new_frozen(key);
88
+ setting = rb_str_new_frozen(setting);
89
+
90
+ args.data = NULL;
91
+ args.size = 0xDEADBEEF;
92
+ args.key = NIL_P(key) ? NULL : StringValueCStr(key);
93
+ args.setting = NIL_P(setting) ? NULL : StringValueCStr(setting);
94
+
95
+ #ifdef HAVE_RUBY_THREAD_H
96
+ value = rb_thread_call_without_gvl(bc_crypt_nogvl, &args, NULL, NULL);
97
+ #else
98
+ value = bc_crypt_nogvl((void *)&args);
99
+ #endif
45
100
 
46
- if(!value) return Qnil;
101
+ if(!value || !args.data) return Qnil;
47
102
 
48
- out = rb_str_new(data, size - 1);
103
+ out = rb_str_new2(value);
49
104
 
50
- xfree(data);
105
+ RB_GC_GUARD(key);
106
+ RB_GC_GUARD(setting);
107
+ free(args.data);
51
108
 
52
109
  return out;
53
110
  }
data/ext/mri/crypt.h CHANGED
@@ -1,5 +1,16 @@
1
1
  /*
2
- * Written by Solar Designer and placed in the public domain.
2
+ * Written by Solar Designer <solar at openwall.com> in 2000-2002.
3
+ * No copyright is claimed, and the software is hereby placed in the public
4
+ * domain. In case this attempt to disclaim copyright and place the software
5
+ * in the public domain is deemed null and void, then the software is
6
+ * Copyright (c) 2000-2002 Solar Designer and it is hereby released to the
7
+ * general public under the following terms:
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted.
11
+ *
12
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
13
+ *
3
14
  * See crypt_blowfish.c for more information.
4
15
  */
5
16