cztop 0.8.0 → 0.9.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
  SHA1:
3
- metadata.gz: 2d264ee06de06bac407c3d7e06c7e70c140ccb22
4
- data.tar.gz: 078a0a7b26a80c8d43e94e5d606acc3772599369
3
+ metadata.gz: d8c82a0f35f091e2d464beabb00adaf5ad0f0b35
4
+ data.tar.gz: aa92e0a78ca5ca7dcc00441d16e004085024a60a
5
5
  SHA512:
6
- metadata.gz: b3baaa8210899a4c87e39731bc9273e77745758057bebc1e01abad0872f3b0c088466a195f8c1ee92401f98571fbb8c1805c9f8e2c017d3abeadc2a88fe54d92
7
- data.tar.gz: 39179480f025cc1d7c36cf5cd394f8dfb4be3a0a3d178463a136fc2e8d287ff696f37ad39a2423cdb35681a7d171a671a9bc9b5b751f3e11667182f892a7cd75
6
+ metadata.gz: 792e7990a6451bd7f02b638e02c782c95c9d54cbc009aa371de33234ed84b06d88737f830406363e96b44425f643c051948a57aa81719e9059627c48252a308b
7
+ data.tar.gz: 1af4724a36e2959e1e94f552c9289e51f98aa5565df5bb6c14cc8a99130401fd4713fa3f75090e2dcdc9cc466521d7e2a51bea756df20d34a10767767d3822d8
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.9.0 (10/20/2016)
2
+ -----
3
+ * add CertStore interface to zcertstore
4
+ * add ability to pass an existing CertStore to Authenticator
5
+ * add ZAP Request/Response classes (useful for testing)
6
+
1
7
  0.8.0 (09/25/2016)
2
8
  -----
3
9
  * update dependency of czmq-ffi-gen to "~> 0.10.0"
data/README.md CHANGED
@@ -97,6 +97,7 @@ Here's an overview of the core classes:
97
97
  * [Z85](http://www.rubydoc.info/gems/cztop/CZTop/Z85)
98
98
  * [Padded](http://www.rubydoc.info/gems/cztop/CZTop/Z85/Padded) < Z85
99
99
  * [Pipe](http://www.rubydoc.info/gems/cztop/CZTop/Z85/Pipe)
100
+ * [ZAP](http://www.rubydoc.info/gems/cztop/CZTop/ZAP)
100
101
 
101
102
  More information in the [API documentation](http://www.rubydoc.info/github/paddor/cztop).
102
103
 
@@ -18,8 +18,18 @@ module CZTop
18
18
  # This installs authentication on all {Socket}s and {Actor}s. Until you
19
19
  # add policies, all incoming _NULL_ connections are allowed,
20
20
  # and all _PLAIN_ and _CURVE_ connections are denied.
21
- def initialize
22
- @actor = Actor.new(ZAUTH_FPTR)
21
+ #
22
+ # @param cert_store [CertStore] a custom certificate store
23
+ # @note If you pass a {CertStore}, its native object will be owned by the
24
+ # actor (and freed by it when the actor terminates). That means you MUST
25
+ # disale auto free in the CertStore object.
26
+ def initialize(cert_store = nil)
27
+ if cert_store
28
+ raise ArgumentError unless cert_store.is_a?(CertStore)
29
+ cert_store = cert_store.ffi_delegate
30
+ cert_store.__undef_finalizer # native object is now owned by zauth() actor
31
+ end
32
+ @actor = Actor.new(ZAUTH_FPTR, cert_store)
23
33
  end
24
34
 
25
35
  # @return [Actor] the actor behind this authenticator
@@ -72,17 +82,17 @@ module CZTop
72
82
  @actor.wait
73
83
  end
74
84
 
75
- ANY_CERTIFICATE = "*"
85
+ # used to allow any CURVE client
86
+ ALLOW_ANY = "*"
76
87
 
77
88
  # Configure CURVE authentication, using a directory that holds all public
78
89
  # client certificates, i.e. their public keys. The certificates must have been
79
90
  # created using {Certificate#save}/{Certificate#save_public}. You can add
80
91
  # and remove certificates in that directory at any time.
81
92
  #
82
- # @param directory [String] the directory to take the keys from (the
83
- # default value will allow any certificate)
93
+ # @param directory [String] the directory to take the keys from
84
94
  # @return [void]
85
- def curve(directory = ANY_CERTIFICATE)
95
+ def curve(directory = ALLOW_ANY)
86
96
  @actor << ["CURVE", directory]
87
97
  @actor.wait
88
98
  end
@@ -0,0 +1,42 @@
1
+ module CZTop
2
+
3
+ # A store for CURVE security certificates, either backed by files on disk or
4
+ # in-memory.
5
+ #
6
+ # @see http://api.zeromq.org/czmq3-0:zcertstore
7
+ class CertStore
8
+ include ::CZMQ::FFI
9
+ include HasFFIDelegate
10
+ extend CZTop::HasFFIDelegate::ClassMethods
11
+
12
+ # Initializes a new certificate store.
13
+ #
14
+ # @param location [String, #to_s, nil] location the path to the
15
+ # directories to load certificates from, or nil if no certificates need
16
+ # to be loaded from the disk
17
+ def initialize(location = nil)
18
+ location = location.to_s if location
19
+ attach_ffi_delegate(Zcertstore.new(location))
20
+ end
21
+
22
+ # Looks up a certificate in the store by its public key.
23
+ #
24
+ # @param pubkey [String] the public key in question, in Z85 format
25
+ # @return [Certificate] the matching certificate, if found
26
+ # @return [nil] if no matching certificate was found
27
+ def lookup(pubkey)
28
+ ptr = ffi_delegate.lookup(pubkey)
29
+ return nil if ptr.null?
30
+ Certificate.from_ffi_delegate(ptr)
31
+ end
32
+
33
+ # Inserts a new certificate into the store.
34
+ #
35
+ # @param cert [Certificate] the certificate to insert
36
+ # @return [void]
37
+ def insert(cert)
38
+ raise ArgumentError unless cert.is_a?(Certificate)
39
+ ffi_delegate.insert(cert.ffi_delegate)
40
+ end
41
+ end
42
+ end
data/lib/cztop/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module CZTop
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
data/lib/cztop/zap.rb ADDED
@@ -0,0 +1,234 @@
1
+ module CZTop
2
+ # This module provides two classes useful when implementing your own ZAP
3
+ # authentication handler or when directly communicating with one. Within
4
+ # CZTop, it's merely used for testing.
5
+ #
6
+ # Some of the features:
7
+ # * useful for both sides of the ZAP communication, i.e. useful for testing
8
+ # * security mechanism agnostic
9
+ # * protocol errors, version mismatches, and internal errors as exceptions
10
+ # * useful to implement your own ZAP handler
11
+ #
12
+ # @note This is not needed to be able to use {CZTop::Authenticator}!
13
+ # @see https://rfc.zeromq.org/spec:27/ZAP
14
+ module ZAP
15
+ # the endpoint a ZAP authenticator has bound to
16
+ ENDPOINT = "inproc://zeromq.zap.01"
17
+
18
+ # the ZAP version supported by this code
19
+ VERSION = "1.0"
20
+
21
+ # superclass for ZAP errors
22
+ class Error < StandardError
23
+ end
24
+
25
+ # used when the response contains an unsupported version
26
+ class VersionMismatch < Error
27
+ end
28
+
29
+ # security mechanisms mentioned in ZeroMQ RFC 27.
30
+ module Mechanisms
31
+ NULL = "NULL"
32
+ PLAIN = "PLAIN"
33
+ CURVE = "CURVE"
34
+ end
35
+
36
+ # Represents a ZAP request.
37
+ class Request
38
+ # Crafts a new {Request} from a message.
39
+ #
40
+ # @param msg [CZTop::message] the message
41
+ # @return [Request] the request
42
+ # @raise [VersionMismatch] if the message contains an unsupported version
43
+ def self.from_message(msg)
44
+ version, # The version frame, which SHALL contain the three octets "1.0".
45
+ request_id, # The request id, which MAY contain an opaque binary blob.
46
+ domain, # The domain, which SHALL contain a string.
47
+ address, # The address, the origin network IP address.
48
+ identity, # The identity, the connection Identity, if any.
49
+ mechanism, # The mechanism, which SHALL contain a string.
50
+ *credentials = # The credentials, which SHALL be zero or more opaque frames.
51
+ msg.to_a
52
+
53
+ raise VersionMismatch if version != VERSION
54
+
55
+ new(domain, credentials, mechanism: mechanism).tap do |r|
56
+ r.version = version
57
+ r.request_id = request_id
58
+ r.address = address
59
+ r.identity = identity
60
+ end
61
+ end
62
+
63
+ # @return [String] ZAP version
64
+ attr_accessor :version
65
+
66
+ # @return [String, #to_s] the authentication domain
67
+ attr_accessor :domain
68
+
69
+ # @return [Array<String, #to_s>] the credentials, 0 or more
70
+ attr_accessor :credentials
71
+
72
+ # @return [String, #to_s]
73
+ attr_accessor :request_id
74
+
75
+ # @return [String, #to_s]
76
+ attr_accessor :address
77
+
78
+ # @return [String, #to_s] the connection identity
79
+ attr_accessor :identity
80
+
81
+ # @see Mechanisms
82
+ # @return [String, #to_s] the security mechanism to be used
83
+ attr_accessor :mechanism
84
+
85
+ # Initializes a new ZAP request. The security mechanism is set to
86
+ # CURVE (can be changed later).
87
+ #
88
+ # @param domain [String] the domain within to authenticate
89
+ # @param credentials [Array<String>] the credentials of the user,
90
+ # depending on the security mechanism used
91
+ def initialize(domain, credentials = [], mechanism: Mechanisms::CURVE)
92
+ @domain = domain
93
+ @credentials = credentials
94
+ @mechanism = mechanism
95
+ @version = VERSION
96
+ end
97
+
98
+ # Creates a sendable message from this {Request}.
99
+ # @return [CZTop::Message} this request packed into a message
100
+ def to_msg
101
+ fields = [ @version, @request_id, @domain, @address,
102
+ @identity, @mechanism, @credentials].flatten.map(&:to_s)
103
+
104
+ CZTop::Message.new(fields)
105
+ end
106
+ end
107
+
108
+ # Represents a ZAP response.
109
+ class Response
110
+
111
+ # used to indicate a temporary error
112
+ class TemporaryError < Error
113
+ end
114
+
115
+ # used to indicate an internal error of the authenticator
116
+ class InternalError < Error
117
+ end
118
+
119
+ # Status codes of ZAP responses.
120
+ module StatusCodes
121
+ SUCCESS = "200"
122
+ TEMPORARY_ERROR = "300"
123
+ AUTHENTICATION_FAILURE = "400"
124
+ INTERNAL_ERROR = "500"
125
+
126
+ ALL = [
127
+ SUCCESS,
128
+ TEMPORARY_ERROR,
129
+ AUTHENTICATION_FAILURE,
130
+ INTERNAL_ERROR
131
+ ]
132
+ end
133
+
134
+ include StatusCodes
135
+
136
+ # Crafts a new {Response} from a message.
137
+ #
138
+ # @param msg [CZTop::message] the message
139
+ # @return [Response] the response
140
+ # @raise [VersionMismatch] if the message contains an unsupported version
141
+ # @raise [TemporaryError] if the status code indicates a temporary error
142
+ # @raise [InternalError] if the status code indicates an internal error,
143
+ # or the status code is invalid
144
+ def self.from_message(msg)
145
+ version, # The version frame, which SHALL contain the three octets "1.0".
146
+ request_id, # The request id, which MAY contain an opaque binary blob.
147
+ status_code, # The status code, which SHALL contain a string.
148
+ status_text, # The status text, which MAY contain a string.
149
+ user_id, # The user id, which SHALL contain a string.
150
+ meta_data = # The meta data, which MAY contain a blob.
151
+ msg.to_a
152
+
153
+ raise VersionMismatch if version != VERSION
154
+
155
+ case status_code
156
+ when SUCCESS, AUTHENTICATION_FAILURE
157
+ # valid codes, nothing to do
158
+ when TEMPORARY_ERROR
159
+ raise TemporaryError, status_text
160
+ when INTERNAL_ERROR
161
+ raise InternalError, status_text
162
+ else
163
+ raise InternalError, "invalid status code"
164
+ end
165
+
166
+ new(status_code).tap do |r|
167
+ r.version = version
168
+ r.request_id = request_id
169
+ r.status_code = status_code
170
+ r.status_text = status_text
171
+ r.user_id = user_id
172
+ r.meta_data = meta_data
173
+ end
174
+ end
175
+
176
+ # @return [String] ZAP version
177
+ attr_accessor :version
178
+
179
+ # @return [String] the original request ID
180
+ attr_accessor :request_id
181
+
182
+ # @return [String] status code
183
+ # @see StatusCodes
184
+ attr_accessor :status_code
185
+
186
+ # @return [String] status explanation
187
+ attr_accessor :status_text
188
+
189
+ # @return [String] meta data in ZMTP 3.0 format
190
+ attr_writer :meta_data
191
+
192
+ # @return [String] the user ID
193
+ attr_writer :user_id
194
+
195
+ # Initializes a new response.
196
+ #
197
+ # @param status_code [String, #to_s] ZAP status code
198
+ def initialize(status_code)
199
+ @status_code = status_code.to_s
200
+ raise ArgumentError unless ALL.include?(@status_code)
201
+ @version = VERSION
202
+ end
203
+
204
+ # @return [Boolean] whether the authentication was successful
205
+ def success?
206
+ @status_code == SUCCESS
207
+ end
208
+
209
+ # Returns the user ID, if authentication was successful.
210
+ # @return [String] the user ID of the authenticated user
211
+ # @return [nil] if authentication was unsuccessful
212
+ def user_id
213
+ return nil unless success?
214
+ @user_id
215
+ end
216
+
217
+ # Returns the meta data, if authentication was successful.
218
+ # @return [String] the meta data for the authenticated user
219
+ # @return [nil] if authentication was unsuccessful
220
+ def meta_data
221
+ return nil unless success?
222
+ @meta_data
223
+ end
224
+
225
+ # Creates a sendable message from this {Response}.
226
+ # @return [CZTop::Message} this request packed into a message
227
+ def to_msg
228
+ fields = [@version, @request_id, @status_code,
229
+ @status_text, @user_id, @meta_data].map(&:to_s)
230
+ CZTop::Message.new(fields)
231
+ end
232
+ end
233
+ end
234
+ end
@@ -64,7 +64,7 @@ module CZTop
64
64
 
65
65
  # @!endgroup
66
66
 
67
- # @!group (CURVE) Security
67
+ # @!group Security Mechanisms
68
68
 
69
69
  # @return [Boolean] whether this zocket is a CURVE server
70
70
  def CURVE_server?() Zsock.curve_server(@zocket) > 0 end
data/lib/cztop.rb CHANGED
@@ -16,6 +16,7 @@ require_relative 'cztop/actor'
16
16
  require_relative 'cztop/authenticator'
17
17
  require_relative 'cztop/beacon'
18
18
  require_relative 'cztop/certificate'
19
+ require_relative 'cztop/cert_store'
19
20
  require_relative 'cztop/config'
20
21
  require_relative 'cztop/frame'
21
22
  require_relative 'cztop/message'
@@ -33,6 +34,7 @@ require_relative 'cztop/message/frames'
33
34
  require_relative 'cztop/socket/types'
34
35
  require_relative 'cztop/z85/padded'
35
36
  require_relative 'cztop/z85/pipe'
37
+ require_relative 'cztop/zap'
36
38
 
37
39
 
38
40
  # make Ctrl-C work in case a low-level call hangs
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cztop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-25 00:00:00.000000000 Z
11
+ date: 2016-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: czmq-ffi-gen
@@ -251,6 +251,7 @@ files:
251
251
  - lib/cztop/actor.rb
252
252
  - lib/cztop/authenticator.rb
253
253
  - lib/cztop/beacon.rb
254
+ - lib/cztop/cert_store.rb
254
255
  - lib/cztop/certificate.rb
255
256
  - lib/cztop/config.rb
256
257
  - lib/cztop/config/comments.rb
@@ -271,6 +272,7 @@ files:
271
272
  - lib/cztop/z85.rb
272
273
  - lib/cztop/z85/padded.rb
273
274
  - lib/cztop/z85/pipe.rb
275
+ - lib/cztop/zap.rb
274
276
  - lib/cztop/zsock_options.rb
275
277
  - perf/README.md
276
278
  - perf/inproc_lat.rb