@@ -4,10 +4,8 @@ import (
4
4
"bytes"
5
5
"compress/gzip"
6
6
"context"
7
- "crypto/sha256"
8
7
"crypto/tls"
9
8
"crypto/x509"
10
- "encoding/hex"
11
9
"encoding/json"
12
10
"fmt"
13
11
"io"
@@ -81,7 +79,7 @@ func (cc *ClientConfig) Transport() http.RoundTripper {
81
79
return c , err
82
80
}
83
81
}
84
- return c , fmt .Errorf ("Server fingerprint not verified" )
82
+ return c , fmt .Errorf ("server fingerprint not verified" )
85
83
},
86
84
MaxIdleConns : 100 ,
87
85
IdleConnTimeout : 90 * time .Second ,
@@ -92,18 +90,17 @@ func (cc *ClientConfig) Transport() http.RoundTripper {
92
90
93
91
// ManagerClient structure definition
94
92
type ManagerClient struct {
95
- httpClient http.Client
96
- config ClientConfig
97
- managerIP net.IP
93
+ config ClientConfig
94
+ ManagerIP net.IP
95
+
96
+ HTTPClient http.Client
98
97
}
99
98
100
99
const (
101
100
// UserAgent used by the client
102
101
UserAgent = "Whids-API-Client/1.0"
103
102
// Mega byte size
104
103
Mega = 1 << 20
105
- // DefaultMaxUploadSize default maximum upload size
106
- DefaultMaxUploadSize = 100 * Mega
107
104
)
108
105
109
106
var (
@@ -115,34 +112,25 @@ func init() {
115
112
var err error
116
113
Hostname , err = os .Hostname ()
117
114
if err != nil {
118
- id := data .Md5 ([]byte (fmt . Sprintf ( "%s" , time .Now ().Format (time .RFC3339Nano ) )))
115
+ id := data .Md5 ([]byte (time .Now ().Format (time .RFC3339Nano )))
119
116
Hostname = fmt .Sprintf ("HOST-%s" , id )
120
117
}
121
118
}
122
119
123
- // Sha256StringArray utility
124
- func Sha256StringArray (array []string ) string {
125
- sha256 := sha256 .New ()
126
- for _ , e := range array {
127
- sha256 .Write ([]byte (e ))
128
- }
129
- return hex .EncodeToString (sha256 .Sum (nil ))
130
- }
131
-
132
120
// NewManagerClient creates a new Client to interface with the manager
133
121
func NewManagerClient (c * ClientConfig ) (* ManagerClient , error ) {
134
122
135
123
tpt := c .Transport ()
136
124
137
125
mc := & ManagerClient {
138
- httpClient : http.Client {Transport : tpt },
126
+ HTTPClient : http.Client {Transport : tpt },
139
127
config : * c ,
140
- managerIP : c .ManagerIP (),
128
+ ManagerIP : c .ManagerIP (),
141
129
}
142
130
143
131
// host
144
132
if mc .config .Host == "" {
145
- return nil , fmt .Errorf ("Field \" host\" is missing from configuration" )
133
+ return nil , fmt .Errorf ("field \" host\" is missing from configuration" )
146
134
}
147
135
// protocol
148
136
if mc .config .Proto == "" {
@@ -152,12 +140,12 @@ func NewManagerClient(c *ClientConfig) (*ManagerClient, error) {
152
140
switch mc .config .Proto {
153
141
case "http" , "https" :
154
142
default :
155
- return nil , fmt .Errorf ("Protocol not supported (only http(s))" )
143
+ return nil , fmt .Errorf ("protocol not supported (only http(s))" )
156
144
}
157
145
158
146
// key
159
147
if mc .config .Key == "" {
160
- return nil , fmt .Errorf ("Field \" key\" is missing from configuration" )
148
+ return nil , fmt .Errorf ("field \" key\" is missing from configuration" )
161
149
}
162
150
163
151
return mc , nil
@@ -208,7 +196,7 @@ func (m *ManagerClient) IsServerUp() bool {
208
196
log .Errorf ("IsServerUp cannot create server key request: %s" , err )
209
197
return false
210
198
}
211
- resp , err := m .httpClient .Do (get )
199
+ resp , err := m .HTTPClient .Do (get )
212
200
if err != nil {
213
201
log .Errorf ("IsServerUp cannot issue server key request: %s" , err )
214
202
return false
@@ -229,7 +217,7 @@ func (m *ManagerClient) IsServerAuthenticated() (auth bool, up bool) {
229
217
log .Errorf ("IsServerAuthenticated cannot create server key request: %s" , err )
230
218
return false , false
231
219
}
232
- resp , err := m .httpClient .Do (get )
220
+ resp , err := m .HTTPClient .Do (get )
233
221
if err != nil {
234
222
log .Errorf ("IsServerAuthenticated cannot issue server key request: %s" , err )
235
223
return false , false
@@ -266,15 +254,15 @@ func (m *ManagerClient) GetRulesSha256() (string, error) {
266
254
return "" , fmt .Errorf ("GetRulesSha256 failed to prepare request: %s" , err )
267
255
}
268
256
269
- resp , err := m .httpClient .Do (req )
257
+ resp , err := m .HTTPClient .Do (req )
270
258
if err != nil {
271
- return "" , fmt .Errorf ("GetRulesSha256 failed to issue HTTP request: %s" , err )
259
+ return "" , fmt .Errorf ("SetRulesSha256 failed to issue HTTP request: %s" , err )
272
260
}
273
261
274
262
if resp != nil {
275
263
defer resp .Body .Close ()
276
264
if resp .StatusCode != 200 {
277
- return "" , fmt .Errorf ("Failed to retrieve rules sha256, unexpected HTTP status code %d" , resp .StatusCode )
265
+ return "" , fmt .Errorf ("failed to retrieve rules sha256, unexpected HTTP status code %d" , resp .StatusCode )
278
266
}
279
267
sha256 , err := ioutil .ReadAll (resp .Body )
280
268
if err != nil {
@@ -296,15 +284,15 @@ func (m *ManagerClient) GetContainer(name string) ([]string, error) {
296
284
return ctn , fmt .Errorf ("GetContainer failed to prepare request: %s" , err )
297
285
}
298
286
299
- resp , err := m .httpClient .Do (req )
287
+ resp , err := m .HTTPClient .Do (req )
300
288
if err != nil {
301
289
return ctn , fmt .Errorf ("GetContainer failed to issue HTTP request: %s" , err )
302
290
}
303
291
304
292
if resp != nil {
305
293
defer resp .Body .Close ()
306
294
if resp .StatusCode != 200 {
307
- return ctn , fmt .Errorf ("Failed to retrieve container, unexpected HTTP status code %d" , resp .StatusCode )
295
+ return ctn , fmt .Errorf ("failed to retrieve container, unexpected HTTP status code %d" , resp .StatusCode )
308
296
}
309
297
dec := json .NewDecoder (resp .Body )
310
298
if err = dec .Decode (& ctn ); err != nil {
@@ -325,15 +313,15 @@ func (m *ManagerClient) GetContainersList() ([]string, error) {
325
313
return ctn , fmt .Errorf ("GetContainersList failed to prepare request: %s" , err )
326
314
}
327
315
328
- resp , err := m .httpClient .Do (req )
316
+ resp , err := m .HTTPClient .Do (req )
329
317
if err != nil {
330
318
return ctn , fmt .Errorf ("GetContainersList failed to issue HTTP request: %s" , err )
331
319
}
332
320
333
321
if resp != nil {
334
322
defer resp .Body .Close ()
335
323
if resp .StatusCode != 200 {
336
- return ctn , fmt .Errorf ("Failed to retrieve containers list, unexpected HTTP status code %d" , resp .StatusCode )
324
+ return ctn , fmt .Errorf ("failed to retrieve containers list, unexpected HTTP status code %d" , resp .StatusCode )
337
325
}
338
326
dec := json .NewDecoder (resp .Body )
339
327
if err = dec .Decode (& ctn ); err != nil {
@@ -353,15 +341,15 @@ func (m *ManagerClient) GetContainerSha256(name string) (string, error) {
353
341
return "" , fmt .Errorf ("GetContainerSha256 failed to prepare request: %s" , err )
354
342
}
355
343
356
- resp , err := m .httpClient .Do (req )
344
+ resp , err := m .HTTPClient .Do (req )
357
345
if err != nil {
358
346
return "" , fmt .Errorf ("GetContainerSha256 failed to issue HTTP request: %s" , err )
359
347
}
360
348
361
349
if resp != nil {
362
350
defer resp .Body .Close ()
363
351
if resp .StatusCode != 200 {
364
- return "" , fmt .Errorf ("Failed to retrieve container sha256, unexpected HTTP status code %d" , resp .StatusCode )
352
+ return "" , fmt .Errorf ("failed to retrieve container sha256, unexpected HTTP status code %d" , resp .StatusCode )
365
353
}
366
354
sha256 , err := ioutil .ReadAll (resp .Body )
367
355
if err != nil {
@@ -381,7 +369,7 @@ func (m *ManagerClient) GetRules() (string, error) {
381
369
return "" , fmt .Errorf ("GetRules failed to prepare request: %s" , err )
382
370
}
383
371
384
- resp , err := m .httpClient .Do (req )
372
+ resp , err := m .HTTPClient .Do (req )
385
373
if err != nil {
386
374
return "" , fmt .Errorf ("GetRules failed to issue HTTP request: %s" , err )
387
375
}
@@ -416,7 +404,7 @@ func (m *ManagerClient) PrepareFileUpload(path, guid, evthash, filename string)
416
404
}
417
405
return & fu , nil
418
406
}
419
- return & fu , fmt .Errorf ("Dump size above limit" )
407
+ return & fu , fmt .Errorf ("dump size above limit" )
420
408
}
421
409
return & fu , os .ErrNotExist
422
410
}
@@ -446,7 +434,7 @@ func (m *ManagerClient) PostDump(f *FileUpload) error {
446
434
return fmt .Errorf ("PostDump failed to prepare request: %s" , err )
447
435
}
448
436
449
- resp , err := m .httpClient .Do (req )
437
+ resp , err := m .HTTPClient .Do (req )
450
438
if err != nil {
451
439
return fmt .Errorf ("PostDump failed to issue HTTP request: %s" , err )
452
440
}
@@ -475,7 +463,7 @@ func (m *ManagerClient) PostLogs(r io.Reader) error {
475
463
return fmt .Errorf ("PostLogs failed to prepare request: %s" , err )
476
464
}
477
465
478
- resp , err := m .httpClient .Do (req )
466
+ resp , err := m .HTTPClient .Do (req )
479
467
if err != nil {
480
468
return fmt .Errorf ("PostLogs failed to issue HTTP request: %s" , err )
481
469
}
@@ -494,79 +482,80 @@ func (m *ManagerClient) PostLogs(r io.Reader) error {
494
482
return fmt .Errorf ("PostLogs failed, server cannot be authenticated" )
495
483
}
496
484
497
- // ExecuteCommand executes a Command on the endpoint and return the result
498
- // to the manager. NB: this method is blocking due to Command.Run function call
499
- func (m * ManagerClient ) ExecuteCommand () error {
485
+ var (
486
+ ErrNothingToDo = fmt .Errorf ("nothing to do" )
487
+ )
488
+
489
+ func (m * ManagerClient ) PostCommand (command * Command ) error {
500
490
if auth , _ := m .IsServerAuthenticated (); auth {
501
- env := AliasEnv { m . managerIP }
502
- command := NewCommandWithEnv ( & env )
491
+ // stripping unecessary content to send back the command
492
+ command . Strip ( )
503
493
504
- // getting command to be executed
505
- req , err := m . Prepare ( "GET" , EptAPICommandPath , nil )
494
+ // command should now contain stdout and stderr
495
+ jsonCommand , err := json . Marshal ( command )
506
496
if err != nil {
507
- return fmt .Errorf ("ExecuteCommand failed to prepare request: %s" , err )
497
+ return fmt .Errorf ("PostCommand failed to marshal command" )
508
498
}
509
499
510
- resp , err := m .httpClient .Do (req )
500
+ // send back the response
501
+ req , err := m .PrepareGzip ("POST" , EptAPICommandPath , bytes .NewBuffer (jsonCommand ))
511
502
if err != nil {
512
- return fmt .Errorf ("ExecuteCommand failed to issue HTTP request: %s" , err )
503
+ return fmt .Errorf ("PostCommand failed to prepare POST request" )
513
504
}
514
505
515
- // if there is no command to execute, the server replies with this status code
516
- if resp .StatusCode == http .StatusNoContent {
517
- // nothing else to do
518
- return nil
519
- }
520
-
521
- jsonCommand , err := ioutil .ReadAll (resp .Body )
506
+ resp , err := m .HTTPClient .Do (req )
522
507
if err != nil {
523
- return fmt .Errorf ("ExecuteCommand failed to read HTTP response body : %s" , err )
508
+ return fmt .Errorf ("PostCommand failed to issue HTTP request : %s" , err )
524
509
}
525
510
526
- // unmarshal command to be executed
527
- if err := json .Unmarshal (jsonCommand , & command ); err != nil {
528
- return fmt .Errorf ("ExecuteCommand failed to unmarshal command: %s" , err )
511
+ if resp != nil {
512
+ defer resp .Body .Close ()
513
+ if resp .StatusCode != 200 {
514
+ return fmt .Errorf ("PostCommand failed to send command results, unexpected HTTP status code %d" , resp .StatusCode )
515
+ }
529
516
}
517
+ return nil
518
+ }
519
+ return fmt .Errorf ("PostCommand failed, server cannot be authenticated" )
530
520
531
- // running the command, this is a blocking function, it waits the command to finish
532
- if err := command .Run (); err != nil {
533
- log .Errorf ("ExecuteCommand failed to run command \" %s\" : %s" , command , err )
534
- }
521
+ }
535
522
536
- // stripping unecessary content to send back the command
537
- command .Strip ()
538
- for fn , ff := range command .Fetch {
539
- log .Infof ("file: %s len: %d error: %s" , fn , len (ff .Data ), ff .Error )
540
- }
541
- // command should now contain stdout and stderr
542
- jsonCommand , err = json .Marshal (command )
523
+ func (m * ManagerClient ) FetchCommand () (* Command , error ) {
524
+ command := NewCommand ()
525
+ if auth , _ := m .IsServerAuthenticated (); auth {
526
+ // getting command to be executed
527
+ req , err := m .Prepare ("GET" , EptAPICommandPath , nil )
543
528
if err != nil {
544
- return fmt .Errorf ("ExecuteCommand failed to marshal command" )
529
+ return command , fmt .Errorf ("FetchCommand failed to prepare request: %s" , err )
545
530
}
546
531
547
- // send back the response
548
- req , err = m .PrepareGzip ("POST" , EptAPICommandPath , bytes .NewBuffer (jsonCommand ))
532
+ resp , err := m .HTTPClient .Do (req )
549
533
if err != nil {
550
- return fmt .Errorf ("ExecuteCommand failed to prepare POST request" )
534
+ return command , fmt .Errorf ("FetchCommand failed to issue HTTP request: %s" , err )
551
535
}
552
536
553
- resp , err = m .httpClient .Do (req )
537
+ // if there is no command to execute, the server replies with this status code
538
+ if resp .StatusCode == http .StatusNoContent {
539
+ // nothing else to do
540
+ return command , ErrNothingToDo
541
+ }
542
+
543
+ jsonCommand , err := ioutil .ReadAll (resp .Body )
554
544
if err != nil {
555
- return fmt .Errorf ("ExecuteCommand failed to issue HTTP request : %s" , err )
545
+ return command , fmt .Errorf ("FetchCommand failed to read HTTP response body : %s" , err )
556
546
}
557
547
558
- if resp != nil {
559
- defer resp .Body .Close ()
560
- if resp .StatusCode != 200 {
561
- return fmt .Errorf ("ExecuteCommand failed to send command results, unexpected HTTP status code %d" , resp .StatusCode )
562
- }
548
+ // unmarshal command to be executed
549
+ if err := json .Unmarshal (jsonCommand , & command ); err != nil {
550
+ return command , fmt .Errorf ("FetchCommand failed to unmarshal command: %s" , err )
563
551
}
564
- return nil
552
+
553
+ return command , nil
565
554
}
566
- return fmt .Errorf ("ExecuteCommand failed, server cannot be authenticated" )
555
+ return command , fmt .Errorf ("FetchCommand failed, server cannot be authenticated" )
567
556
}
568
557
569
558
// Close closes idle connections from underlying transport
570
559
func (m * ManagerClient ) Close () {
571
- m .httpClient .CloseIdleConnections ()
560
+ m .HTTPClient .CloseIdleConnections ()
572
561
}
0 commit comments