@newrelic/security-agent 0.1.2 → 0.2.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.
- package/CHANGELOG.md +15 -0
- package/THIRD_PARTY_NOTICES.md +17 -28
- package/lib/instrumentation-security/core/constants.js +0 -1
- package/lib/instrumentation-security/hooks/fs/nr-fs.js +6 -5
- package/lib/instrumentation-security/hooks/http/nr-http.js +2 -2
- package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +16 -0
- package/lib/instrumentation-security/hooks/native/nr-childProcess.js +1 -1
- package/lib/instrumentation-security/hooks/require/nr-require.js +12 -5
- package/lib/nr-security-agent/lib/core/Auth-headers.js +1 -0
- package/lib/nr-security-agent/lib/core/applicationinfo.js +1 -1
- package/lib/nr-security-agent/lib/core/commonUtils.js +12 -12
- package/lib/nr-security-agent/lib/core/connections/websocket/index.js +0 -6
- package/lib/nr-security-agent/lib/core/connections/websocket/response/IASTUtils.js +50 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/collector-policy-handler.js +4 -1
- package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +90 -31
- package/lib/nr-security-agent/lib/core/connections/websocket/response/iast-cool-down.js +15 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/iast-record-deletion.js +19 -0
- package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +17 -5
- package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +23 -61
- package/lib/nr-security-agent/lib/core/logging.js +89 -71
- package/lib/nr-security-agent/lib/core/sec-agent-constants.js +3 -2
- package/lib/nr-security-agent/lib/core/statusUtils.js +1 -1
- package/lib/nr-security-agent/lib/core/websocket-client.js +5 -168
- package/lib/nr-security-agent/lib/core/xss-utils.js +2 -3
- package/lib/nr-security-agent/resources/config.js +2 -2
- package/package.json +11 -11
- package/lib/nr-security-agent/lib/core/worker-entities.js +0 -82
- package/lib/nr-security-agent/lib/core/worker.js +0 -148
package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js
CHANGED
|
@@ -9,19 +9,19 @@ const stringify = require('fast-safe-stringify');
|
|
|
9
9
|
const restClient = require('../../restclient');
|
|
10
10
|
const { Agent } = require('../../../agent');
|
|
11
11
|
const { FuzzFailEvent } = require('../../../FuzzFailEvent');
|
|
12
|
-
const { hasWorker: isWorkerSupported } = require('../../../commonUtils');
|
|
13
12
|
const { CSEC_HOME_TMP, COLON, NR_CSEC_FUZZ_REQUEST_ID, SLASH } = require('../../../sec-agent-constants');
|
|
14
13
|
const LOCALHOST = 'localhost';
|
|
15
14
|
const COLON_SLASH_SLASH = '://';
|
|
16
15
|
const http = require('http');
|
|
17
16
|
const https = require('https');
|
|
17
|
+
const IASTUtil = require('./IASTUtils');
|
|
18
|
+
const CSEC_SEP = ':IAST:';
|
|
19
|
+
|
|
18
20
|
require('dns').setDefaultResultOrder('ipv4first')
|
|
19
21
|
|
|
20
22
|
const {
|
|
21
23
|
IS_LAMBDA_ENV,
|
|
22
|
-
AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER
|
|
23
|
-
CSEC_LAST_FUZZ_REQUEST_TIME
|
|
24
|
-
} = require('../../../sec-agent-constants');
|
|
24
|
+
AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER } = require('../../../sec-agent-constants');
|
|
25
25
|
const statusUtils = require('../../../statusUtils');
|
|
26
26
|
|
|
27
27
|
const find = `${SLASH}{{NR_CSEC_VALIDATOR_HOME_TMP}}`;
|
|
@@ -29,23 +29,71 @@ const CSEC_HOME_TMP_CONST = new RegExp(find, 'g');
|
|
|
29
29
|
|
|
30
30
|
let logger;
|
|
31
31
|
let lastFuzzEventTime = 0;
|
|
32
|
+
let iastIntervalConst;
|
|
33
|
+
let coolDownIntervalConst;
|
|
34
|
+
let additionalCoolDownTime = 0;
|
|
35
|
+
let fuzzedApiIDSet = new Set();
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* utility to start IAST Schedular
|
|
40
|
+
*/
|
|
41
|
+
function startIASTSchedular() {
|
|
42
|
+
Agent.getAgent().client.dispatcher(IASTUtil.generateIASTDataRequest());
|
|
43
|
+
if (iastIntervalConst) {
|
|
44
|
+
clearInterval(iastIntervalConst);
|
|
45
|
+
}
|
|
46
|
+
iastIntervalConst = setInterval(() => {
|
|
47
|
+
let data = IASTUtil.generateIASTDataRequest();
|
|
48
|
+
let currentTime = Date.now();
|
|
49
|
+
let completedListSize = IASTUtil.getCompletedRequestIds().length;
|
|
50
|
+
let timeDiffInSeconds = ((currentTime - lastFuzzEventTime) / 1000);
|
|
51
|
+
logger.trace("Time difference since last fuzz request:", timeDiffInSeconds);
|
|
52
|
+
logger.trace("Completed requests so far:", completedListSize);
|
|
53
|
+
|
|
54
|
+
if (timeDiffInSeconds > 5 && additionalCoolDownTime == 0) {
|
|
55
|
+
Agent.getAgent().client.dispatcher(data);
|
|
56
|
+
}
|
|
57
|
+
}, 5000);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Utility to log scanned apiId
|
|
62
|
+
* @param {*} fuzzHeader
|
|
63
|
+
*/
|
|
64
|
+
function logScannedApiId(fuzzHeader, requestURL) {
|
|
65
|
+
try {
|
|
66
|
+
let apiId = fuzzHeader.split(CSEC_SEP)[0]
|
|
67
|
+
if (apiId && !fuzzedApiIDSet.has(apiId) ) {
|
|
68
|
+
fuzzedApiIDSet.add(apiId);
|
|
69
|
+
logger.info("IAST Scan for API %s with ID : %s started.", requestURL, apiId);
|
|
70
|
+
}
|
|
71
|
+
} catch (error) {
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
}
|
|
32
76
|
|
|
33
77
|
// handler function to parse fuzz event and prepare fuzz request
|
|
34
|
-
function handler
|
|
35
|
-
|
|
78
|
+
function handler(json) {
|
|
79
|
+
setLastFuzzEventTime();
|
|
36
80
|
let rawFuzzRequest = json.arguments[0];
|
|
37
|
-
logger.debug('Fuzz request received::' + rawFuzzRequest);
|
|
38
81
|
rawFuzzRequest = rawFuzzRequest.replace(CSEC_HOME_TMP_CONST, CSEC_HOME_TMP);
|
|
39
82
|
let fuzzRequest;
|
|
40
83
|
try {
|
|
41
84
|
fuzzRequest = JSON.parse(rawFuzzRequest);
|
|
85
|
+
fuzzRequest['id'] = json.id;
|
|
86
|
+
let completedList = IASTUtil.getCompletedRequestIds();
|
|
87
|
+
if (completedList.includes(json.id)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
42
90
|
} catch (error) {
|
|
43
91
|
logger.error('Parsing exeception in fuzz request: ', error);
|
|
44
92
|
}
|
|
45
93
|
if (!fuzzRequest) {
|
|
46
94
|
return;
|
|
47
95
|
}
|
|
48
|
-
|
|
96
|
+
logger.debug('Fuzz request received::' + JSON.stringify(json));
|
|
49
97
|
logger.info('Fuzz request:: Method: ' + fuzzRequest.method);
|
|
50
98
|
logger.info('Fuzz request:: Headers: ' + stringify(fuzzRequest.headers));
|
|
51
99
|
logger.info('Fuzz request:: Data: ' + fuzzRequest.body);
|
|
@@ -61,7 +109,7 @@ function handler (json) {
|
|
|
61
109
|
*
|
|
62
110
|
* @param {Object} fuzzDetails
|
|
63
111
|
*/
|
|
64
|
-
function handleFuzzRequest
|
|
112
|
+
function handleFuzzRequest(fuzzDetails) {
|
|
65
113
|
const { fuzzRequest } = fuzzDetails;
|
|
66
114
|
try {
|
|
67
115
|
if (IS_LAMBDA_ENV) {
|
|
@@ -71,7 +119,7 @@ function handleFuzzRequest (fuzzDetails) {
|
|
|
71
119
|
const ver = process.env[AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER];
|
|
72
120
|
logger.info('Invoking Lambda:: ARN: ' + arn);
|
|
73
121
|
logger.info('Invoking Lambda:: Version: ' + ver);
|
|
74
|
-
|
|
122
|
+
|
|
75
123
|
} else {
|
|
76
124
|
const config = parseAxiosHttpRequestToFuzz(fuzzRequest);
|
|
77
125
|
const type = config.headers['content-type'];
|
|
@@ -81,10 +129,16 @@ function handleFuzzRequest (fuzzDetails) {
|
|
|
81
129
|
config.headers['content-type'] = splitted[0];
|
|
82
130
|
}
|
|
83
131
|
}
|
|
132
|
+
|
|
133
|
+
if(fuzzRequest.headers && fuzzRequest.headers[NR_CSEC_FUZZ_REQUEST_ID]){
|
|
134
|
+
logScannedApiId(fuzzRequest.headers[NR_CSEC_FUZZ_REQUEST_ID], fuzzRequest.requestURI)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
84
138
|
logger.info('Firing http request:: URL: ' + config.url);
|
|
85
139
|
|
|
86
|
-
const
|
|
87
|
-
handleFuzzResponse(
|
|
140
|
+
const response = restClient.fireRequest(config);
|
|
141
|
+
handleFuzzResponse(response, fuzzDetails);
|
|
88
142
|
}
|
|
89
143
|
} catch (err) {
|
|
90
144
|
statusUtils.addErrortoBuffer(err);
|
|
@@ -101,13 +155,14 @@ function handleFuzzRequest (fuzzDetails) {
|
|
|
101
155
|
/**
|
|
102
156
|
* Handles the fuzz response Promise.
|
|
103
157
|
*
|
|
104
|
-
* @param {Promise}
|
|
158
|
+
* @param {Promise} response
|
|
105
159
|
* @param {Object} fuzzDetails
|
|
106
160
|
*/
|
|
107
|
-
function handleFuzzResponse
|
|
161
|
+
function handleFuzzResponse(response, fuzzDetails) {
|
|
108
162
|
const { rawFuzzRequest, fuzzRequest } = fuzzDetails;
|
|
109
|
-
if (
|
|
110
|
-
|
|
163
|
+
if (response) {
|
|
164
|
+
IASTUtil.addRequestId(fuzzRequest.id);
|
|
165
|
+
response.then(() => {
|
|
111
166
|
logger.info('Fuzz success: ' + rawFuzzRequest);
|
|
112
167
|
}).catch(() => {
|
|
113
168
|
logger.debug('Error occured:', fuzzRequest.url, fuzzRequest);
|
|
@@ -121,11 +176,11 @@ function handleFuzzResponse (request, fuzzDetails) {
|
|
|
121
176
|
*
|
|
122
177
|
* @param {JSON} requestObject
|
|
123
178
|
*/
|
|
124
|
-
function parseAxiosHttpRequestToFuzz
|
|
179
|
+
function parseAxiosHttpRequestToFuzz(requestObject) {
|
|
125
180
|
let serverName = requestObject.serverName ? requestObject.serverName : LOCALHOST;
|
|
126
181
|
let host = serverName + COLON + requestObject.serverPort
|
|
127
182
|
return {
|
|
128
|
-
url: requestObject.protocol + COLON_SLASH_SLASH + host
|
|
183
|
+
url: requestObject.protocol + COLON_SLASH_SLASH + host + requestObject.url,
|
|
129
184
|
method: requestObject.method,
|
|
130
185
|
data: requestObject.body,
|
|
131
186
|
headers: requestObject.headers,
|
|
@@ -141,7 +196,7 @@ function parseAxiosHttpRequestToFuzz (requestObject) {
|
|
|
141
196
|
* set the handler logger
|
|
142
197
|
* @param {*} l
|
|
143
198
|
*/
|
|
144
|
-
function setLogger
|
|
199
|
+
function setLogger(l) {
|
|
145
200
|
logger = l;
|
|
146
201
|
};
|
|
147
202
|
|
|
@@ -149,25 +204,29 @@ function setLogger (l) {
|
|
|
149
204
|
* Sets the last fuzz event time epoch
|
|
150
205
|
* @param {Number} time
|
|
151
206
|
*/
|
|
152
|
-
function
|
|
153
|
-
|
|
154
|
-
process.env[CSEC_LAST_FUZZ_REQUEST_TIME] = time;
|
|
155
|
-
} else {
|
|
156
|
-
lastFuzzEventTime = time;
|
|
157
|
-
}
|
|
207
|
+
function setLastFuzzEventTime(time = Date.now()) {
|
|
208
|
+
lastFuzzEventTime = time;
|
|
158
209
|
}
|
|
159
210
|
|
|
211
|
+
|
|
160
212
|
/**
|
|
161
|
-
*
|
|
162
|
-
* @
|
|
213
|
+
* Sets the last fuzz event time epoch
|
|
214
|
+
* @param {Number} time
|
|
163
215
|
*/
|
|
164
|
-
function
|
|
165
|
-
|
|
216
|
+
function setAdditionalCoolDown(timeInSeconds) {
|
|
217
|
+
additionalCoolDownTime = timeInSeconds ? timeInSeconds : 10;
|
|
218
|
+
if (coolDownIntervalConst) {
|
|
219
|
+
clearTimeout(coolDownIntervalConst)
|
|
220
|
+
}
|
|
221
|
+
coolDownIntervalConst = setTimeout(() => {
|
|
222
|
+
additionalCoolDownTime = 0;
|
|
223
|
+
}, timeInSeconds * 1000);
|
|
166
224
|
}
|
|
167
225
|
|
|
168
226
|
module.exports = {
|
|
169
227
|
handler,
|
|
170
228
|
setLogger,
|
|
171
|
-
|
|
172
|
-
|
|
229
|
+
setLastFuzzEventTime,
|
|
230
|
+
startIASTSchedular,
|
|
231
|
+
setAdditionalCoolDown
|
|
173
232
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: New Relic Pre-Release
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let logger;
|
|
7
|
+
|
|
8
|
+
module.exports.handler = function handler (json) {
|
|
9
|
+
logger.debug('IAST cool down command received:', JSON.stringify(json));
|
|
10
|
+
const fuzzRequestHandler = require('./fuzz-request-handler');
|
|
11
|
+
fuzzRequestHandler.setLastFuzzEventTime();
|
|
12
|
+
fuzzRequestHandler.setAdditionalCoolDown(json.data);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports.setLogger = l => { logger = l };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: New Relic Pre-Release
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let logger;
|
|
7
|
+
const IASTUtil = require('./IASTUtils');
|
|
8
|
+
module.exports.handler = function handler (json) {
|
|
9
|
+
let deletionList = json.arguments;
|
|
10
|
+
let count = 0;
|
|
11
|
+
deletionList.forEach(element => {
|
|
12
|
+
count++;
|
|
13
|
+
IASTUtil.removeRequestId(element);
|
|
14
|
+
});
|
|
15
|
+
logger.debug("Purging confirmed %s IAST processed records: ", count, JSON.stringify(deletionList));
|
|
16
|
+
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
module.exports.setLogger = l => { logger = l };
|
|
@@ -13,6 +13,10 @@ const CollectorPolicyHandler = require('./collector-policy-handler');
|
|
|
13
13
|
const CollectorPolicyErrorHandler = require('./collecotor-policy-error-handler');
|
|
14
14
|
const NoOpHandler = require('./no-op-handler');
|
|
15
15
|
const WSReconnect = require('./ws-reconnect');
|
|
16
|
+
const coolDown = require('./iast-cool-down');
|
|
17
|
+
const recordDeletion = require('./iast-record-deletion');
|
|
18
|
+
const logs = require('../../../logging');
|
|
19
|
+
let logger = logs.getLogger();
|
|
16
20
|
|
|
17
21
|
const commandHandlerMap = {
|
|
18
22
|
[SERVER_COMMAND.STARTUP_WELCOME_MSG]: StartupHandshakeHandler,
|
|
@@ -20,15 +24,23 @@ const commandHandlerMap = {
|
|
|
20
24
|
[SERVER_COMMAND.FUZZ_REQUEST]: FuzzRequestHandler,
|
|
21
25
|
[SERVER_COMMAND.COLLECTOR_CONFIG]: CollectorPolicyHandler,
|
|
22
26
|
[SERVER_COMMAND.POLICY_ERROR]: CollectorPolicyErrorHandler,
|
|
23
|
-
[SERVER_COMMAND.OBEY_WS_RECONNECT]: WSReconnect
|
|
27
|
+
[SERVER_COMMAND.OBEY_WS_RECONNECT]: WSReconnect,
|
|
28
|
+
[SERVER_COMMAND.IAST_RECORD_DELETE_CONFIRMATION]:recordDeletion,
|
|
29
|
+
[SERVER_COMMAND.ENTER_IAST_COOLDOWN]:coolDown
|
|
24
30
|
};
|
|
25
31
|
|
|
26
32
|
const handle = function handle (json) {
|
|
27
|
-
|
|
28
|
-
commandHandlerMap[json.controlCommand]
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
try {
|
|
34
|
+
if (json && json.controlCommand && json.arguments && commandHandlerMap[json.controlCommand]) {
|
|
35
|
+
logger.debug("Incoming Control Command:", JSON.stringify(json));
|
|
36
|
+
commandHandlerMap[json.controlCommand].handler.call(this, json);
|
|
37
|
+
} else {
|
|
38
|
+
NoOpHandler.handler.call(this, json);
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
logger.error("Error in handling Control Commnad",error);
|
|
31
42
|
}
|
|
43
|
+
|
|
32
44
|
};
|
|
33
45
|
|
|
34
46
|
const setLogger = function setLogger (logger) {
|
|
@@ -32,8 +32,9 @@ const INIT_PING_RETRY_DELAY_ON_FAIL = 200; // in ms
|
|
|
32
32
|
const RECONNECTION_DELAY = 500; // ms
|
|
33
33
|
const APPLICATION_INFO_JSON_NAME = 'applicationinfo';
|
|
34
34
|
let APP_INFO;
|
|
35
|
+
let CSEC_WS_STATE = '';
|
|
35
36
|
|
|
36
|
-
const queue = new RingBuffer(
|
|
37
|
+
const queue = new RingBuffer(10);
|
|
37
38
|
let logger = logs.getLogger();
|
|
38
39
|
const initLogger = logs.getInitLogger();
|
|
39
40
|
let webSocket;
|
|
@@ -115,6 +116,11 @@ SecWebSocket.prototype.init = function init() {
|
|
|
115
116
|
webSocket.on(WS_ON_ERR, this.errCB);
|
|
116
117
|
webSocket.on(WS_ON_PONG, () => {
|
|
117
118
|
lastPongtime = Date.now();
|
|
119
|
+
commonUtils.setWSHealthStatus('OK');
|
|
120
|
+
logger.debug("Pong received from Validator");
|
|
121
|
+
})
|
|
122
|
+
webSocket.on('close', () => {
|
|
123
|
+
logger.warn("WS connection closed");
|
|
118
124
|
})
|
|
119
125
|
this.instance = webSocket;
|
|
120
126
|
};
|
|
@@ -126,7 +132,7 @@ SecWebSocket.prototype.init = function init() {
|
|
|
126
132
|
SecWebSocket.prototype.reconnect = function reconnect() {
|
|
127
133
|
const { instance } = this;
|
|
128
134
|
if (instance.readyState === WebSocket.CONNECTING &&
|
|
129
|
-
|
|
135
|
+
CSEC_WS_STATE === CONNECTING) {
|
|
130
136
|
return;
|
|
131
137
|
}
|
|
132
138
|
setWebSocketConn();
|
|
@@ -201,19 +207,15 @@ SecWebSocket.prototype.dispatch = async function dispatch(event) {
|
|
|
201
207
|
!this.isICReadyForEvents
|
|
202
208
|
) {
|
|
203
209
|
handleDispatchFailure(this, event, eventStr);
|
|
204
|
-
commonUtils.setWSHealthStatus('Error')
|
|
205
210
|
return;
|
|
206
211
|
}
|
|
207
212
|
try {
|
|
208
|
-
aquireWebSocket();
|
|
209
213
|
await promisify(this.instance, this.instance.send)(eventStr, { mask: true }, () => {
|
|
210
214
|
logger.debug(LOG_MESSAGES.EVENT_SENT + eventStr);
|
|
211
215
|
});
|
|
212
|
-
releaseWebSocket();
|
|
213
216
|
} catch (error) {
|
|
214
217
|
logger.debug(LOG_MESSAGES.ERROR_WHILE_SEND_EVENT, eventStr, error);
|
|
215
218
|
statusUtils.addErrortoBuffer(error);
|
|
216
|
-
commonUtils.setWSHealthStatus('Error')
|
|
217
219
|
handleDispatchFailure(this, event, eventStr);
|
|
218
220
|
}
|
|
219
221
|
};
|
|
@@ -263,7 +265,6 @@ SecWebSocket.prototype.setValidatorNotReadyForEvents = function setValidatorNotR
|
|
|
263
265
|
* recover these events.
|
|
264
266
|
*/
|
|
265
267
|
SecWebSocket.prototype.flushEventQueue = async function flushEventQueue() {
|
|
266
|
-
aquireWebSocket();
|
|
267
268
|
try {
|
|
268
269
|
const sentEvents = [];
|
|
269
270
|
for (let counter = 0; counter < queue.size(); counter += 1) {
|
|
@@ -274,9 +275,7 @@ SecWebSocket.prototype.flushEventQueue = async function flushEventQueue() {
|
|
|
274
275
|
hc.getInstance().registerEventsSent(results.length);
|
|
275
276
|
} catch (err) {
|
|
276
277
|
statusUtils.addErrortoBuffer(err);
|
|
277
|
-
logger.
|
|
278
|
-
} finally {
|
|
279
|
-
releaseWebSocket();
|
|
278
|
+
logger.debug('Flush failed, reception of all events on IC couldn\'t be ensured.');
|
|
280
279
|
}
|
|
281
280
|
};
|
|
282
281
|
|
|
@@ -292,7 +291,6 @@ const handleDispatchFailure = (self, event, eventStr) => {
|
|
|
292
291
|
// so feeding an old applicationinfo JSON would be incorrect
|
|
293
292
|
if (eventStr && event.jsonName !== APPLICATION_INFO_JSON_NAME) {
|
|
294
293
|
hc.getInstance().registerEventDrop();
|
|
295
|
-
queue.enq(eventStr);
|
|
296
294
|
}
|
|
297
295
|
};
|
|
298
296
|
|
|
@@ -311,6 +309,14 @@ const handleDispatchFailure = (self, event, eventStr) => {
|
|
|
311
309
|
const defaultOnOpenCB = () => async function onOpen() {
|
|
312
310
|
const self = this;
|
|
313
311
|
lastPongtime = 0;
|
|
312
|
+
|
|
313
|
+
if (pingIntervalConst) {
|
|
314
|
+
clearInterval(pingIntervalConst);
|
|
315
|
+
}
|
|
316
|
+
pingIntervalConst = setInterval(() => {
|
|
317
|
+
self.pingWS();
|
|
318
|
+
}, 30000)
|
|
319
|
+
|
|
314
320
|
if (self.isICReadyForEvents) {
|
|
315
321
|
return;
|
|
316
322
|
}
|
|
@@ -318,12 +324,7 @@ const defaultOnOpenCB = () => async function onOpen() {
|
|
|
318
324
|
self.reconnect();
|
|
319
325
|
return;
|
|
320
326
|
}
|
|
321
|
-
|
|
322
|
-
clearInterval(pingIntervalConst);
|
|
323
|
-
}
|
|
324
|
-
pingIntervalConst = setInterval(() => {
|
|
325
|
-
self.pingWS();
|
|
326
|
-
}, 30000)
|
|
327
|
+
|
|
327
328
|
const validatorService = commonUtils.getValidatorServiceEndpointURL();
|
|
328
329
|
initLogger.info(`[STEP-4] => Web socket connection to SaaS validator established successfully at ${validatorService}`)
|
|
329
330
|
try {
|
|
@@ -334,13 +335,8 @@ const defaultOnOpenCB = () => async function onOpen() {
|
|
|
334
335
|
const applicationInfo = APP_INFO || Agent.getAgent().applicationInfo;
|
|
335
336
|
await self.dispatchApplicationInfo(applicationInfo);
|
|
336
337
|
|
|
337
|
-
// by now we expect IC to be ready
|
|
338
|
-
aquireWebSocket(true);
|
|
339
338
|
self.setICReadyForEvents();
|
|
340
|
-
|
|
341
|
-
await self.flushEventQueue();
|
|
342
|
-
ResponseHandler.FuzzRequestHandler.setLastFuzzEnventTime();
|
|
343
|
-
releaseWebSocket();
|
|
339
|
+
ResponseHandler.FuzzRequestHandler.setLastFuzzEventTime();
|
|
344
340
|
initLogger.info(LOG_MESSAGES.SENDING_APPINFO_COMPLETE, JSON.stringify(applicationInfo));
|
|
345
341
|
} catch (err) {
|
|
346
342
|
logger.error(`Connection broken: ${err.message}`);
|
|
@@ -379,12 +375,13 @@ const defaultOnErrCB = () => function onClose(error) {
|
|
|
379
375
|
commonUtils.setWSHealthStatus('Error');
|
|
380
376
|
statusUtils.addErrortoBuffer(error);
|
|
381
377
|
const self = this;
|
|
378
|
+
logger.error("Error while connecting to validator:", error.message)
|
|
379
|
+
logger.warn("Security Agent INACTIVE!!!")
|
|
382
380
|
if (error && error.code && (error.code === 'ECONNREFUSED' || error.code === 'EPIPE' || error.code === 'ECONNRESET')) {
|
|
383
381
|
logger.debug("WS Client Error callback called:", error);
|
|
384
382
|
self.obeyReconnect();
|
|
385
383
|
}
|
|
386
384
|
else {
|
|
387
|
-
aquireWebSocket(true);
|
|
388
385
|
self.reconnect();
|
|
389
386
|
}
|
|
390
387
|
};
|
|
@@ -404,52 +401,17 @@ SecWebSocket.PING_MSG = ACK;
|
|
|
404
401
|
SecWebSocket.PING_RETRY_INTERVAL = INIT_PING_RETRY_DELAY_ON_FAIL;
|
|
405
402
|
SecWebSocket.RECONNECTION_DELAY = RECONNECTION_DELAY;
|
|
406
403
|
|
|
407
|
-
/**
|
|
408
|
-
* Checks if the websocket is currently busy
|
|
409
|
-
* by checking on CSEC_WS_STATE
|
|
410
|
-
*
|
|
411
|
-
* @returns {boolean} busy
|
|
412
|
-
*/
|
|
413
|
-
function isWebSocketBusy() {
|
|
414
|
-
return process.env.CSEC_WS_STATE !== IDLE;
|
|
415
|
-
}
|
|
416
404
|
|
|
417
405
|
/**
|
|
418
406
|
* Sets the websocket state as connecting
|
|
419
407
|
*/
|
|
420
408
|
function setWebSocketConn() {
|
|
421
|
-
|
|
422
|
-
process.env.CSEC_WS_STATE = CONNECTING;
|
|
409
|
+
CSEC_WS_STATE = CONNECTING;
|
|
423
410
|
}
|
|
424
411
|
|
|
425
|
-
/**
|
|
426
|
-
* marks the WS being aquired to be used in an operation
|
|
427
|
-
*/
|
|
428
|
-
function aquireWebSocket(forced = false) {
|
|
429
|
-
if (!forced && process.env.CSEC_WS_STATE === CONNECTING) return;
|
|
430
|
-
|
|
431
|
-
let count = Number.parseInt(process.env.CSEC_WS_ACQUIRED_COUNT);
|
|
432
|
-
count += 1;
|
|
433
|
-
process.env.CSEC_WS_ACQUIRED_COUNT = count;
|
|
434
|
-
process.env.CSEC_WS_STATE = BUSY;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* marks the WS being released after use in an operation
|
|
439
|
-
*/
|
|
440
|
-
function releaseWebSocket() {
|
|
441
|
-
const { CSEC_WS_STATE, CSEC_WS_ACQUIRED_COUNT } = process.env;
|
|
442
|
-
let count = Number.parseInt(CSEC_WS_ACQUIRED_COUNT);
|
|
443
|
-
count = count > 0 ? count - 1 : 0;
|
|
444
|
-
process.env.CSEC_WS_ACQUIRED_COUNT = count;
|
|
445
|
-
process.env.CSEC_WS_STATE = count === 0 && CSEC_WS_STATE !== CONNECTING ? CSEC_WS_STATE : IDLE;
|
|
446
|
-
}
|
|
447
412
|
|
|
448
413
|
module.exports = {
|
|
449
414
|
WSCallbacks,
|
|
450
415
|
SecWebSocket,
|
|
451
|
-
|
|
452
|
-
setWebSocketConn,
|
|
453
|
-
aquireWebSocket,
|
|
454
|
-
releaseWebSocket
|
|
416
|
+
setWebSocketConn
|
|
455
417
|
};
|