vaas 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d825f4cbd3edbbdf6d391ad3dcc1257b30c3df7c9a2e53f1caae99bc57036bf3
4
- data.tar.gz: 29ef4d52405ef1381b63a9f68e014446f9fadc58bc16bd810bbea2f75066ccc6
3
+ metadata.gz: a05b70f5292bec90b8e2155e46351bb419e09cfa9c2ab2adc7a9b7518c2461bd
4
+ data.tar.gz: f35d1a3472a24c1361e643d58fafd37b20d2cb9aa3cc37217e650a9e295537d4
5
5
  SHA512:
6
- metadata.gz: fed95ea1cf2622afabbd5d85b9fa884e02a8a4b009f8f04711d70c7a23248fb7598b433341e8f7f997ddecdbdecdbf4802c17eb88bfac27728843e443702a0bd
7
- data.tar.gz: 9a796c1a3c49e384db42d727370caca6fcd8b72f16b5f64fe667fa409f2833695d622949e8c816ce1731e50812116379d14c7c542c29d4be890108eb9ab6b805
6
+ metadata.gz: 86dacfaee9ab76cea8301ebc704a9e6e46001c45c7ac6d9ef8c9b77cf3fcf2b759300087205bfe02ae2952b4bc9ff88858ea68426b7231768a37597fb5b36322
7
+ data.tar.gz: df21c2cfd66cdca06ed715dc89fa4f39d3df1e54685b9f8a86be4ec149b4ee2659dbaf3325ae2bdc7baca15b8e16c6356d6a3637fdfc859be5b0aaafe1dfceb9
data/README.md CHANGED
@@ -54,10 +54,10 @@ token = authenticator.get_token
54
54
  Verdict Request for SHA256:
55
55
  ```ruby
56
56
  Async do
57
- Async { vaas.connect(token) }.wait
57
+ vaas.connect(token)
58
58
  sha256 = "275a021bbfb6489e54d471899f7db9d1663fc695ec2fe2a2c4538aabf651fd0f"
59
- verdict = vaas.for_sha256(sha256)
60
- ensure
59
+ verdict = vaas.for_sha256(sha256) # starts a task
60
+ puts verdict.wait.verdict # await task
61
61
  vaas.close
62
62
  end
63
63
  ```
@@ -65,10 +65,10 @@ end
65
65
  Verdict Request for a file:
66
66
  ```ruby
67
67
  Async do
68
- Async { vaas.connect(token) }.wait
68
+ vaas.connect(token)
69
69
  path = "/path/to/file"
70
- verdict = vaas.for_file(path)
71
- ensure
70
+ verdict = vaas.for_file(path) # starts a task
71
+ puts verdict.wait.verdict # await task
72
72
  vaas.close
73
73
  end
74
74
  ```
@@ -76,10 +76,10 @@ end
76
76
  Verdict Request for a URL:
77
77
  ```ruby
78
78
  Async do
79
- Async { vaas.connect(token) }.wait
79
+ vaas.connect(token)
80
80
  url = "https://www.gdatasoftware.com/oem/verdict-as-a-service"
81
- verdict = vaas.for_url(url)
82
- ensure
81
+ verdict = vaas.for_url(url) # starts a task
82
+ puts verdict.wait.verdict # await task
83
83
  vaas.close
84
84
  end
85
85
  ```
@@ -4,7 +4,7 @@ require 'vaas/vaas_main'
4
4
 
5
5
  CLIENT_ID = ENV.fetch('CLIENT_ID')
6
6
  CLIENT_SECRET = ENV.fetch('CLIENT_SECRET')
7
- PATH = ENV.fetch('PATH')
7
+ URL = ENV.fetch('URL')
8
8
 
9
9
  def main
10
10
  authenticator = VAAS::ClientCredentialsGrantAuthenticator.new(
@@ -18,21 +18,18 @@ def main
18
18
  token = authenticator.get_token
19
19
 
20
20
  Async do
21
- # wait to connect and authenticate
22
- Async { vaas.connect(token) }.wait
21
+ vaas.connect(token)
23
22
 
24
23
  # reconnect if connection closed
25
24
  begin
26
- verdict = vaas.for_file(PATH)
25
+ verdict = vaas.for_url(URL)
27
26
  rescue VAAS::VaasConnectionClosedError
28
27
  token = authenticator.get_token
29
- Async { vaas.connect(token) }.wait
28
+ vaas.connect(token)
30
29
  retry
31
30
  end
31
+ puts "Verdict #{verdict.wait.sha256} is detected as #{verdict.wait.verdict}"
32
32
 
33
- puts "Verdict #{verdict.sha256} is detected as #{verdict.verdict}"
34
-
35
- ensure
36
33
  vaas.close
37
34
  end
38
35
  end
@@ -4,7 +4,7 @@ require 'vaas/vaas_main'
4
4
 
5
5
  CLIENT_ID = ENV.fetch('CLIENT_ID')
6
6
  CLIENT_SECRET = ENV.fetch('CLIENT_SECRET')
7
- PATH = ENV.fetch('PATH')
7
+ URL = ENV.fetch('URL')
8
8
 
9
9
  def main
10
10
  authenticator = VAAS::ClientCredentialsGrantAuthenticator.new(
@@ -18,15 +18,11 @@ def main
18
18
  token = authenticator.get_token
19
19
 
20
20
  Async do
21
- # wait to connect and authenticate
22
- Async { vaas.connect(token) }.wait
21
+ vaas.connect(token)
23
22
 
24
- # simple method to get the verdict of a file
25
- verdict = vaas.for_file(PATH)
23
+ verdict = vaas.for_url(URL)
24
+ puts "Verdict #{verdict.wait.sha256} is detected as #{verdict.wait.verdict}"
26
25
 
27
- puts "Verdict #{verdict.sha256} is detected as #{verdict.verdict}"
28
-
29
- ensure
30
26
  vaas.close
31
27
  end
32
28
  end
@@ -14,125 +14,174 @@ require_relative 'vaas_errors'
14
14
  module VAAS
15
15
  class VaasMain
16
16
 
17
- attr_accessor :session_id, :websocket, :url
18
-
19
- def initialize(url="wss://gateway-vaas.gdatasecurity.de")
17
+ def initialize(url = "wss://gateway-vaas.gdatasecurity.de", timeout = 600)
20
18
  @url = url
19
+ @timeout = timeout
20
+ @requests = {}
21
21
  end
22
22
 
23
23
  def connect(token)
24
24
  # connect to endpoint
25
- endpoint = Async::HTTP::Endpoint.parse(url, alpn_protocols: Async::HTTP::Protocol::HTTP1.names)
26
- self.websocket = Async::WebSocket::Client.connect(endpoint)
25
+ endpoint = Async::HTTP::Endpoint.parse(@url, alpn_protocols: Async::HTTP::Protocol::HTTP1.names)
26
+ @websocket = Async::WebSocket::Client.connect(endpoint)
27
+
28
+ read_messages
29
+ keep_alive
27
30
 
28
31
  # send authentication request
29
- auth_request = JSON.generate({:kind => "AuthRequest", :token => token})
30
- websocket.write(auth_request)
31
-
32
- # receive authentication message
33
- while message = websocket.read
34
- message = JSON.parse(message)
35
- if message['success'] == true
36
- self.session_id = message['session_id']
37
- break
38
- else
39
- raise VaasAuthenticationError
32
+ auth_task = Async do |task|
33
+ task.with_timeout(@timeout) do
34
+ @auth_notification = Async::Notification.new
35
+ auth_request = JSON.generate({:kind => "AuthRequest", :token => token})
36
+ @websocket.write(auth_request)
37
+ @websocket.flush
38
+ @auth_notification.wait
39
+ rescue Async::TimeoutError
40
+ close
41
+ raise VaasTimeoutError
40
42
  end
41
43
  end
42
- end
43
44
 
44
- def get_authenticated_websocket
45
- raise VaasInvalidStateError unless websocket
46
- raise VaasInvalidStateError, "connect() was not awaited" unless session_id
47
- raise VaasConnectionClosedError if websocket.closed?
48
- websocket
45
+ message = auth_task.wait
46
+ raise VaasAuthenticationError if message['success'] == false
47
+ @session_id = message['session_id']
49
48
  end
50
49
 
51
- def close
52
- websocket&.close
50
+ def keep_alive
51
+ @keep_alive_task = Async do
52
+ until @websocket.closed?
53
+ sleep 10
54
+ @websocket.send_ping
55
+ @websocket.flush
56
+ end
57
+ end
53
58
  end
54
59
 
55
- def __for_sha256(sha256, guid)
56
- # send verdict request with sha256
57
- websocket = get_authenticated_websocket
58
- guid = guid || SecureRandom.uuid.to_s
59
- verdict_request = JSON.generate({:kind => "VerdictRequest",
60
- :session_id => session_id,
61
- :sha256 => sha256,
62
- :guid => guid})
63
- websocket.write(verdict_request)
64
-
65
- # receive verdict message
66
- while message = websocket.read
67
- message = JSON.parse(message)
68
- if message['kind'] == "VerdictResponse"
69
- return message
60
+ def read_messages
61
+ @read_task = Async do |task|
62
+ task.with_timeout(@timeout) do
63
+ while message = @websocket.read
64
+ message = JSON.parse(message)
65
+ if message['kind'] == "AuthResponse"
66
+ @auth_notification.signal(message)
67
+ elsif message['kind'] == "VerdictResponse"
68
+ @requests[message['guid']].signal(message)
69
+ end
70
+ end
71
+ rescue Async::TimeoutError
72
+ close
73
+ raise VaasTimeoutError
70
74
  end
71
75
  end
72
76
  end
73
77
 
74
- def for_sha256(sha256, guid = nil)
75
- response = __for_sha256(sha256, guid)
76
- VaasVerdict.new(response)
78
+ def get_authenticated_websocket
79
+ raise VaasInvalidStateError unless @websocket
80
+ raise VaasInvalidStateError, "connect() was not awaited" unless @session_id
81
+ raise VaasConnectionClosedError if @websocket.closed?
82
+ @websocket
77
83
  end
78
84
 
79
- def for_file(path, guid = nil)
80
- # get sha256 of file and send verdict request
81
- sha256 = Digest::SHA256.file(path).hexdigest
82
- response = __for_sha256(sha256, guid)
85
+ def close
86
+ @keep_alive_task&.stop
87
+ @read_task&.stop
88
+ @websocket&.close
89
+ end
83
90
 
84
- # upload file if verdict is unknown
85
- if response['verdict'] == 'Unknown'
86
- upload(response, path)
87
- else
88
- return VaasVerdict.new(response)
91
+ def for_sha256(sha256)
92
+ Async do |task|
93
+ task.with_timeout(@timeout) do
94
+ verdict_notification = Async::Notification.new
95
+ guid = SecureRandom.uuid.to_s
96
+ websocket = get_authenticated_websocket
97
+ verdict_request = JSON.generate({:kind => "VerdictRequest",
98
+ :session_id => @session_id,
99
+ :sha256 => sha256,
100
+ :guid => guid})
101
+ @requests[guid] = verdict_notification
102
+ websocket.write(verdict_request)
103
+ websocket.flush
104
+ VaasVerdict.new(verdict_notification.wait)
105
+ rescue Async::TimeoutError
106
+ close
107
+ raise VaasTimeoutError
108
+ end
89
109
  end
110
+ end
90
111
 
91
- # receive verdict message of uploaded file
92
- while message = websocket.read
93
- message = JSON.parse(message)
94
- if message['kind'] == "VerdictResponse" && message['verdict'] != "Unknown"
95
- return VaasVerdict.new(message)
112
+ def for_url(url)
113
+ Async do |task|
114
+ task.with_timeout(@timeout) do
115
+ verdict_notification = Async::Notification.new
116
+ guid = SecureRandom.uuid.to_s
117
+ websocket = get_authenticated_websocket
118
+ verdict_request = JSON.generate({:kind => "VerdictRequestForUrl",
119
+ :session_id => @session_id,
120
+ :url => url,
121
+ :guid => guid})
122
+ @requests[guid] = verdict_notification
123
+ websocket.write(verdict_request)
124
+ websocket.flush
125
+ VaasVerdict.new(verdict_notification.wait)
126
+ rescue Async::TimeoutError
127
+ close
128
+ raise VaasTimeoutError
96
129
  end
97
130
  end
98
131
  end
99
132
 
100
- def for_url(url, guid = nil)
101
- #send verdict request with url
102
- websocket = get_authenticated_websocket
103
- guid = guid || SecureRandom.uuid.to_s
104
- url = URI(url).to_s
105
- verdict_request = JSON.generate({:kind => "VerdictRequestForUrl",
106
- :session_id => session_id,
107
- :guid => guid,
108
- :url => url})
109
- websocket.write(verdict_request)
110
-
111
- # receive verdict message
112
- while message = websocket.read
113
- message = JSON.parse(message)
114
- if message['kind'] == "VerdictResponse"
115
- return VaasVerdict.new(message)
133
+ def for_file(path)
134
+ Async do |task|
135
+ task.with_timeout(@timeout) do
136
+ sha256 = Digest::SHA256.file(path).hexdigest
137
+ verdict_notification = Async::Notification.new
138
+ guid = SecureRandom.uuid.to_s
139
+ websocket = get_authenticated_websocket
140
+ verdict_request = JSON.generate({:kind => "VerdictRequest",
141
+ :session_id => @session_id,
142
+ :sha256 => sha256,
143
+ :guid => guid})
144
+ @requests[guid] = verdict_notification
145
+ websocket.write(verdict_request)
146
+ websocket.flush
147
+ message = verdict_notification.wait
148
+
149
+ if message['verdict'] == "Unknown"
150
+ upload_notification = Async::Notification.new
151
+ @requests[guid] = upload_notification
152
+ upload(message, path)
153
+ VaasVerdict.new(upload_notification.wait)
154
+ else
155
+ VaasVerdict.new(message)
156
+ end
157
+ rescue Async::TimeoutError
158
+ close
159
+ raise VaasTimeoutError
116
160
  end
117
161
  end
118
162
  end
119
163
 
120
- def upload (message, path)
121
- token = message['upload_token']
122
- url = message['url']
164
+ def upload(message, path)
165
+ Async do |task|
166
+ task.with_timeout(@timeout) do
167
+ token = message['upload_token']
168
+ url = message['url']
123
169
 
124
- Async do
125
- client = Async::HTTP::Internet.new
170
+ client = Async::HTTP::Internet.new
126
171
 
127
- header = [['authorization', token]]
128
- body = Protocol::HTTP::Body::File.open(File.join(path))
172
+ header = [['authorization', token]]
173
+ body = Protocol::HTTP::Body::File.open(File.join(path))
129
174
 
130
- client.put(url, header, body).read
175
+ response = client.put(url, header, body)
176
+ response.read
131
177
 
132
- rescue => e
133
- raise VaasUploadError, e
134
- ensure
135
- client&.close
178
+ raise VaasUploadError, "Upload failed with code: #{response.status}" if response.status != 200
179
+ rescue Async::TimeoutError
180
+ close
181
+ raise VaasTimeoutError, "Upload timed out"
182
+ ensure
183
+ client&.close
184
+ end
136
185
  end
137
186
  end
138
187
  end
data/lib/vaas/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module VAAS
2
- VERSION = '1.0.1'
2
+ VERSION = '2.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vaas
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Allie Weitenkamp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-19 00:00:00.000000000 Z
11
+ date: 2023-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -91,7 +91,6 @@ files:
91
91
  - ".vscode/launch.json"
92
92
  - Gemfile
93
93
  - README.md
94
- - examples/example_with_lists.rb
95
94
  - examples/example_with_reconnect.rb
96
95
  - examples/simple_example.rb
97
96
  - lib/vaas.rb
@@ -1,37 +0,0 @@
1
- require 'async'
2
- require 'vaas/client_credentials_grant_authenticator'
3
- require 'vaas/vaas_main'
4
-
5
- CLIENT_ID = ENV.fetch('CLIENT_ID')
6
- CLIENT_SECRET = ENV.fetch('CLIENT_SECRET')
7
- PATHS = ENV.fetch('PATHS')
8
-
9
- def main
10
- authenticator = VAAS::ClientCredentialsGrantAuthenticator.new(
11
- CLIENT_ID,
12
- CLIENT_SECRET,
13
- "https://keycloak-vaas.gdatasecurity.de/realms/vaas/protocol/openid-connect/token"
14
- )
15
-
16
- # create a vaas object and get a token to authenticate
17
- vaas = VAAS::VaasMain.new
18
- token = authenticator.get_token
19
-
20
- Async do
21
- # wait to connect and authenticate
22
- Async { vaas.connect(token) }.wait
23
-
24
- # simple loop to get the verdict of a list of files
25
- PATHS.each do |file|
26
- verdict = vaas.for_file(file)
27
- puts "Verdict #{verdict.sha256} is detected as #{verdict.verdict}"
28
- end
29
-
30
- ensure
31
- vaas.close
32
- end
33
- end
34
-
35
- if __FILE__ == $0
36
- main
37
- end