zyre 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2cbe25941f3013a68fa6da8ddfdcb97d7169ad8b488d2ffae453138514ed0e5c
4
- data.tar.gz: c8089b759367a8e753503f937ad6b1fd4288cdf2268a4e299c6d65dcee169dc2
3
+ metadata.gz: e56e2efba36769885761b0e4eca374ee1a2a8b1d9ce453ae84c388218ffed962
4
+ data.tar.gz: 8cd9af854d199c9529df5f6b048d64c60d7737d99297025ad8f0b00d1621e831
5
5
  SHA512:
6
- metadata.gz: 16325060cb3bf2e1409fc116d3ac9a9f5249d7400b809787a3c04e6aa97965fa9b672d809580220653f2c938076f9f7499343e9aaf69806b8277f6d48d7ab446
7
- data.tar.gz: 744b233d8d57b22d805d1a6393d73373a5a6545a299eb9287eae25f73f63bf6c4d94ce0c63387923496c2d090a3264bf0d8ca556a07eece991281bd3d239ac3e
6
+ metadata.gz: 73cc151bd63a418aa8a88e0a75816e95ad651babc58fbe72b07ca2842ef67bdfb8b257c6ca31982b44772054606dec060f75db97ecb234a8a1f867a50de6c3d8
7
+ data.tar.gz: 5a43c47fe85eb3ca1748e7c1808d1a458fe5b0321d29f32ad4fd3ef0e7e42fce7bf44a6d1b950bf836e1023a239c4455bcbbee73cf437d82a381fd9d82c8ec38
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/Authentication.md ADDED
@@ -0,0 +1,30 @@
1
+ # Authenticated \Zyre
2
+
3
+ Note that authentication requires API that is still in Draft, so it requires
4
+ that your libzyre be built with --enable-drafts. Also, since draft APIs are
5
+ subject to change, this documentation may be out of date. A good place to check
6
+ for the latest info is the built-in test suites in the Zyre source itself.
7
+
8
+ Authentication isn't done yet, but when it is it'll look something like:
9
+
10
+ cert = Zyre::Cert.new
11
+ cert.save( "/usr/local/var/certs/server" )
12
+
13
+ Zyre.allow( "127.0.0.1", "10.0.12.2" )
14
+ Zyre.start_authenticator( :CURVE, "/usr/local/var/certs" )
15
+
16
+ node = Zyre::Node.new
17
+ node.zap_domain = 'application_name'
18
+ node.zcert = cert
19
+ node.start
20
+
21
+ # later...
22
+
23
+ node.stop
24
+ Zyre.stop_authenticator
25
+
26
+
27
+ ## References
28
+
29
+ - ZAP (ZeroMQ Authentication Protocol) - https://rfc.zeromq.org/spec/27/
30
+ - Using ZeroMQ Security (Part 2) - https://jaxenter.com/using-zeromq-security-part-2-119353.html
data/History.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Release History for zyre
2
2
 
3
3
  ---
4
+ ## v0.4.0 [2021-02-19] Michael Granger <ged@faeriemud.org>
5
+
6
+ Improvements:
7
+
8
+ - Add partial support for draft APIs
9
+ - Add a singleton method for disabling CZMQ's default SIGINT/TERM handler.
10
+
4
11
 
5
12
  ## v0.3.1 [2020-11-23] Michael Granger <ged@faeriemud.org>
6
13
 
data/README.md CHANGED
@@ -135,7 +135,7 @@ development.
135
135
 
136
136
  ## License
137
137
 
138
- Copyright (c) 2020, Ravn Group
138
+ Copyright (c) 2020-2021, Ravn Group
139
139
  All rights reserved.
140
140
 
141
141
  Redistribution and use in source and binary forms, with or without
@@ -0,0 +1,504 @@
1
+ /*
2
+ * cert.c - A curve certificate for use with Zyre.
3
+ * $Id$
4
+ *
5
+ * Authors:
6
+ * * Michael Granger <ged@FaerieMUD.org>
7
+ *
8
+ */
9
+
10
+ #include "zyre_ext.h"
11
+
12
+ VALUE rzyre_cZyreCert;
13
+
14
+ // Forward declarations
15
+ static void rzyre_cert_free( void *ptr );
16
+
17
+
18
+ static const rb_data_type_t rzyre_cert_t = {
19
+ .wrap_struct_name = "Zyre::Cert",
20
+ .function = {
21
+ .dmark = NULL,
22
+ .dfree = rzyre_cert_free,
23
+ },
24
+ .data = NULL,
25
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
26
+ };
27
+
28
+
29
+ /*
30
+ * Free function
31
+ */
32
+ static void
33
+ rzyre_cert_free( void *ptr )
34
+ {
35
+ if ( ptr ) {
36
+ zcert_destroy( (zcert_t **)&ptr );
37
+ }
38
+ }
39
+
40
+
41
+ /*
42
+ * Alloc function
43
+ */
44
+ static VALUE
45
+ rzyre_cert_alloc( VALUE klass )
46
+ {
47
+ return TypedData_Wrap_Struct( klass, &rzyre_cert_t, NULL );
48
+ }
49
+
50
+
51
+ /*
52
+ * Fetch the data pointer and check it for sanity.
53
+ */
54
+ inline zcert_t *
55
+ rzyre_get_cert( VALUE self )
56
+ {
57
+ zcert_t *ptr;
58
+
59
+ if ( !IsZyreCert(self) ) {
60
+ rb_raise( rb_eTypeError, "wrong argument type %s (expected Zyre::Cert)",
61
+ rb_class2name(CLASS_OF( self )) );
62
+ }
63
+
64
+ ptr = DATA_PTR( self );
65
+ assert( ptr );
66
+
67
+ return ptr;
68
+ }
69
+
70
+
71
+ /*
72
+ * call-seq:
73
+ * Zyre::Cert.from( public_key, secret_key ) -> cert
74
+ *
75
+ * Create a certificate from the +public_key+ and +secret_key+.
76
+ *
77
+ */
78
+ static VALUE
79
+ rzyre_cert_s_from( VALUE class, VALUE public_key, VALUE secret_key )
80
+ {
81
+ VALUE self = rzyre_cert_alloc( class );
82
+ zcert_t *ptr = NULL;
83
+ const char *pub_str = StringValuePtr( public_key ),
84
+ *sec_str = StringValuePtr( secret_key );
85
+
86
+ if ( RSTRING_LEN(public_key) == 32 && RSTRING_LEN(secret_key) == 32 ) {
87
+ ptr = zcert_new_from( (const byte *)pub_str, (const byte *)sec_str );
88
+ } else if ( RSTRING_LEN(public_key) == 40 && RSTRING_LEN(secret_key) == 40 ) {
89
+ #ifdef CZMQ_BUILD_DRAFT_API
90
+ ptr = zcert_new_from_txt( pub_str, sec_str );
91
+ #else
92
+ rb_raise( rb_eNotImpError,
93
+ "can't create a key from encoded keys: Czmq was not built with Draft APIs!" );
94
+ #endif
95
+ }
96
+
97
+ if ( !ptr ) {
98
+ rb_raise( rb_eArgError, "invalid key pair" );
99
+ }
100
+
101
+ RTYPEDDATA_DATA( self ) = ptr;
102
+
103
+ return self;
104
+ }
105
+
106
+
107
+ /*
108
+ * call-seq:
109
+ * Zyre::Cert.load( filename ) -> cert
110
+ *
111
+ * Create a certificate from a saved certificate in the specified
112
+ * +filename+.
113
+ *
114
+ */
115
+ static VALUE
116
+ rzyre_cert_s_load( VALUE class, VALUE filename )
117
+ {
118
+ VALUE self = rzyre_cert_alloc( class );
119
+ zcert_t *ptr = zcert_load( StringValueCStr(filename) );
120
+
121
+ if ( !ptr ) {
122
+ rb_raise( rb_eArgError, "failed to load cert from %s", RSTRING_PTR(filename) );
123
+ }
124
+
125
+ RTYPEDDATA_DATA( self ) = ptr;
126
+
127
+ return self;
128
+ }
129
+
130
+
131
+ /*
132
+ * call-seq:
133
+ * Zyre::Cert.new -> cert
134
+ *
135
+ * Create a new certificate.
136
+ *
137
+ */
138
+ static VALUE
139
+ rzyre_cert_initialize( VALUE self )
140
+ {
141
+ zcert_t *ptr;
142
+
143
+ TypedData_Get_Struct( self, zcert_t, &rzyre_cert_t, ptr );
144
+ if ( !ptr ) {
145
+ RTYPEDDATA_DATA( self ) = ptr = zcert_new();
146
+ assert( ptr );
147
+ }
148
+
149
+ return self;
150
+ }
151
+
152
+
153
+ /*
154
+ * call-seq:
155
+ * cert.public_key -> key_data
156
+ *
157
+ * Return public part of key pair as 32-byte binary string
158
+ *
159
+ */
160
+ static VALUE
161
+ rzyre_cert_public_key( VALUE self )
162
+ {
163
+ zcert_t *ptr = rzyre_get_cert( self );
164
+ const byte *key = zcert_public_key( ptr );
165
+ VALUE rval = rb_enc_str_new( (const char *)key, 32, rb_ascii8bit_encoding() );
166
+
167
+ return rval;
168
+ }
169
+
170
+
171
+ /*
172
+ * call-seq:
173
+ * cert.secret_key -> key_data
174
+ *
175
+ * Return secret part of key pair as 32-byte binary string
176
+ *
177
+ */
178
+ static VALUE
179
+ rzyre_cert_secret_key( VALUE self )
180
+ {
181
+ zcert_t *ptr = rzyre_get_cert( self );
182
+ const byte *key = zcert_secret_key( ptr );
183
+ VALUE rval = rb_enc_str_new( (const char *)key, 32, rb_ascii8bit_encoding() );
184
+
185
+ return rval;
186
+ }
187
+
188
+
189
+ /*
190
+ * call-seq:
191
+ * cert.public_txt -> key_text
192
+ *
193
+ * Return public part of key pair as Z85 armored string
194
+ *
195
+ */
196
+ static VALUE
197
+ rzyre_cert_public_txt( VALUE self )
198
+ {
199
+ zcert_t *ptr = rzyre_get_cert( self );
200
+ const char *key = zcert_public_txt( ptr );
201
+ VALUE rval = rb_usascii_str_new( key, 40 );
202
+
203
+ return rval;
204
+ }
205
+
206
+
207
+ /*
208
+ * call-seq:
209
+ * cert.secret_txt -> key_text
210
+ *
211
+ * Return secret part of key pair as Z85 armored string
212
+ *
213
+ */
214
+ static VALUE
215
+ rzyre_cert_secret_txt( VALUE self )
216
+ {
217
+ zcert_t *ptr = rzyre_get_cert( self );
218
+ const char *key = zcert_secret_txt( ptr );
219
+ VALUE rval = rb_usascii_str_new( key, 40 );
220
+
221
+ return rval;
222
+ }
223
+
224
+
225
+ /*
226
+ * call-seq:
227
+ * cert.set_meta( name, value )
228
+ *
229
+ * Set certificate metadata +name+ to +value+.
230
+ *
231
+ */
232
+ static VALUE
233
+ rzyre_cert_set_meta( VALUE self, VALUE name, VALUE val )
234
+ {
235
+ zcert_t *ptr = rzyre_get_cert( self );
236
+ const char *key_str = StringValueCStr( name ),
237
+ *val_str = StringValueCStr( val );
238
+
239
+ #ifdef CZMQ_BUILD_DRAFT_API
240
+ zcert_unset_meta( ptr, key_str );
241
+ #endif
242
+
243
+ zcert_set_meta( ptr, key_str, "%s", val_str );
244
+
245
+ return val;
246
+ }
247
+
248
+
249
+ /*
250
+ * call-seq:
251
+ * cert.meta( name ) -> string
252
+ *
253
+ * Return the metadata value for +name+ from certificate; if the metadata
254
+ * value doesn't exist, returns +nil+.
255
+ *
256
+ */
257
+ static VALUE
258
+ rzyre_cert_meta( VALUE self, VALUE name )
259
+ {
260
+ zcert_t *ptr = rzyre_get_cert( self );
261
+ VALUE rval = Qnil;
262
+ const char *name_str = StringValuePtr( name );
263
+ const char *value = zcert_meta( ptr, name_str );
264
+
265
+ if ( value ) rval = rb_str_new_cstr( value );
266
+
267
+ return rval;
268
+ }
269
+
270
+
271
+ /*
272
+ * call-seq:
273
+ * cert.keys -> array
274
+ *
275
+ * Return an Array of metadata field names that belong to the receiver.
276
+ *
277
+ */
278
+ static VALUE
279
+ rzyre_cert_meta_keys( VALUE self )
280
+ {
281
+ zcert_t *ptr = rzyre_get_cert( self );
282
+ zlist_t *keys = zcert_meta_keys( ptr );
283
+ VALUE rary = rb_ary_new();
284
+ char *item;
285
+
286
+ assert( keys );
287
+
288
+ item = zlist_first( keys );
289
+ while ( item ) {
290
+ rb_ary_push( rary, rb_str_new_cstr(item) );
291
+ item = zlist_next( keys );
292
+ }
293
+
294
+ zlist_destroy( &keys );
295
+
296
+ return rary;
297
+ }
298
+
299
+
300
+ /*
301
+ * call-seq:
302
+ * cert.unset_meta( name )
303
+ *
304
+ * Unset certificate metadata value for the given +name.
305
+ *
306
+ * Note: this is a draft method for development use, may change without warning.
307
+ *
308
+ */
309
+ static VALUE
310
+ rzyre_cert_unset_meta( VALUE self, VALUE name )
311
+ {
312
+ #ifdef CZMQ_BUILD_DRAFT_API
313
+ zcert_t *ptr = rzyre_get_cert( self );
314
+ const char *name_str = StringValueCStr( name );
315
+
316
+ zcert_unset_meta( ptr, name_str );
317
+
318
+ return Qtrue;
319
+ #else
320
+ rb_raise( rb_eNotImpError, "Czmq was not built with Draft APIs!" );
321
+ #endif // CZMQ_BUILD_DRAFT_API
322
+ }
323
+
324
+
325
+ /*
326
+ * call-seq:
327
+ * cert.save( filename )
328
+ *
329
+ * Save the full certificate (public + secret) to the specified +filename+.
330
+ * This creates one public file and one secret file (filename + "_secret").
331
+ *
332
+ */
333
+ static VALUE
334
+ rzyre_cert_save( VALUE self, VALUE filename )
335
+ {
336
+ zcert_t *ptr = rzyre_get_cert( self );
337
+ const char *filename_str = StringValueCStr( filename );
338
+ int result;
339
+
340
+ result = zcert_save( ptr, filename_str );
341
+
342
+ if ( result != 0 )
343
+ rb_raise( rb_eRuntimeError, "failed to save cert to %s", filename_str );
344
+
345
+ return Qtrue;
346
+ }
347
+
348
+
349
+ /*
350
+ * call-seq:
351
+ * cert.save_public( filename )
352
+ *
353
+ * Save the public certificate only to the specified +filename+.
354
+ *
355
+ */
356
+ static VALUE
357
+ rzyre_cert_save_public( VALUE self, VALUE filename )
358
+ {
359
+ zcert_t *ptr = rzyre_get_cert( self );
360
+ const char *filename_str = StringValueCStr( filename );
361
+ int result;
362
+
363
+ result = zcert_save_public( ptr, filename_str );
364
+
365
+ if ( result != 0 )
366
+ rb_raise( rb_eRuntimeError, "failed to save public cert to %s", filename_str );
367
+
368
+ return Qtrue;
369
+ }
370
+
371
+
372
+ /*
373
+ * call-seq:
374
+ * cert.save_secret( filename )
375
+ *
376
+ * Save the secret certificate only to the specified +filename+.
377
+ *
378
+ */
379
+ static VALUE
380
+ rzyre_cert_save_secret( VALUE self, VALUE filename )
381
+ {
382
+ zcert_t *ptr = rzyre_get_cert( self );
383
+ const char *filename_str = StringValueCStr( filename );
384
+ int result;
385
+
386
+ result = zcert_save_secret( ptr, filename_str );
387
+
388
+ if ( result != 0 )
389
+ rb_raise( rb_eRuntimeError, "failed to save secret cert to %s", filename_str );
390
+
391
+ return Qtrue;
392
+ }
393
+
394
+
395
+ /*
396
+ * call-seq:
397
+ * cert.dup -> cert
398
+ *
399
+ * Return a copy of the certificate.
400
+ *
401
+ */
402
+ static VALUE
403
+ rzyre_cert_dup( VALUE self )
404
+ {
405
+ zcert_t *ptr = rzyre_get_cert( self );
406
+ zcert_t *other_ptr;
407
+ VALUE other = rb_call_super( 0, NULL );
408
+
409
+ RTYPEDDATA_DATA( other ) = other_ptr = zcert_dup( ptr );
410
+
411
+ if ( !other_ptr )
412
+ rb_raise( rb_eRuntimeError, "couldn't duplicate the cert" );
413
+
414
+ return other;
415
+ }
416
+
417
+
418
+ /*
419
+ * call-seq:
420
+ * cert.eql?( other_cert ) -> true or false
421
+ *
422
+ * Return true if the +other_cert+ has the same keys.
423
+ *
424
+ */
425
+ static VALUE
426
+ rzyre_cert_eql_p( VALUE self, VALUE other )
427
+ {
428
+ zcert_t *ptr = rzyre_get_cert( self ),
429
+ *other_ptr = rzyre_get_cert( other );
430
+ bool equal = zcert_eq( ptr, other_ptr );
431
+
432
+ return equal ? Qtrue : Qfalse;
433
+ }
434
+
435
+
436
+ /*
437
+ * call-seq:
438
+ * cert.print
439
+ *
440
+ * Print certificate contents to stdout.
441
+ *
442
+ */
443
+ static VALUE
444
+ rzyre_cert_print( VALUE self )
445
+ {
446
+ zcert_t *ptr = rzyre_get_cert( self );
447
+
448
+ zcert_print( ptr );
449
+
450
+ return Qtrue;
451
+ }
452
+
453
+
454
+
455
+ /*
456
+ * Initialize the Cert class.
457
+ */
458
+ void
459
+ rzyre_init_cert( void ) {
460
+
461
+ #ifdef FOR_RDOC
462
+ rb_cData = rb_define_class( "Data" );
463
+ rzyre_mZyre = rb_define_module( "Zyre" );
464
+ #endif
465
+
466
+ /*
467
+ * Document-class: Zyre::Cert
468
+ *
469
+ * A certificate for Zyre curve authentication.
470
+ *
471
+ * Refs:
472
+ * - http://api.zeromq.org/czmq4-0:zcert
473
+ *
474
+ */
475
+ rzyre_cZyreCert = rb_define_class_under( rzyre_mZyre, "Cert", rb_cObject );
476
+
477
+ rb_define_alloc_func( rzyre_cZyreCert, rzyre_cert_alloc );
478
+
479
+ rb_define_singleton_method( rzyre_cZyreCert, "from", rzyre_cert_s_from, 2 );
480
+ rb_define_singleton_method( rzyre_cZyreCert, "load", rzyre_cert_s_load, 1 );
481
+
482
+ rb_define_protected_method( rzyre_cZyreCert, "initialize", rzyre_cert_initialize, 0 );
483
+
484
+ rb_define_method( rzyre_cZyreCert, "public_key", rzyre_cert_public_key, 0 );
485
+ rb_define_method( rzyre_cZyreCert, "secret_key", rzyre_cert_secret_key, 0 );
486
+ rb_define_method( rzyre_cZyreCert, "public_txt", rzyre_cert_public_txt, 0 );
487
+ rb_define_method( rzyre_cZyreCert, "secret_txt", rzyre_cert_secret_txt, 0 );
488
+
489
+ rb_define_method( rzyre_cZyreCert, "set_meta", rzyre_cert_set_meta, 2 );
490
+ rb_define_method( rzyre_cZyreCert, "meta", rzyre_cert_meta, 1 );
491
+ rb_define_method( rzyre_cZyreCert, "meta_keys", rzyre_cert_meta_keys, 0 );
492
+ rb_define_method( rzyre_cZyreCert, "unset_meta", rzyre_cert_unset_meta, 1 ); // DRAFT
493
+
494
+ rb_define_method( rzyre_cZyreCert, "save", rzyre_cert_save, 1 );
495
+ rb_define_method( rzyre_cZyreCert, "save_public", rzyre_cert_save_public, 1 );
496
+ rb_define_method( rzyre_cZyreCert, "save_secret", rzyre_cert_save_secret, 1 );
497
+
498
+ rb_define_method( rzyre_cZyreCert, "dup", rzyre_cert_dup, 0 );
499
+ rb_define_method( rzyre_cZyreCert, "eql?", rzyre_cert_eql_p, 1 );
500
+ rb_define_method( rzyre_cZyreCert, "print", rzyre_cert_print, 0 );
501
+
502
+ rb_require( "zyre/cert" );
503
+ }
504
+