Skip to content

Commit 8c86df4

Browse files
committed
Fixed bug validating the database host during connection
1 parent 3b1238b commit 8c86df4

File tree

7 files changed

+54
-30
lines changed

7 files changed

+54
-30
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Common Changes
2929
Thin Mode Changes
3030
+++++++++++++++++
3131

32+
#) Fixed bug validating the database host during connection.
33+
3234
#) Enabled proxy user to be passed with :ref:`external authentication <extauth>`
3335
in :meth:`oracledb.createPool()` for Thin mode.
3436
See `Issue #1743 <https://github.com/oracle/node-oracledb/issues/1743>`__.

lib/errors.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ const ERR_CALLOUT_FN = 169;
178178
const ERR_SESSIONLESS_DIFFERING_METHODS = 170;
179179
const ERR_SESSIONLESS_ALREADY_ACTIVE = 171;
180180
const ERR_SESSIONLESS_INACTIVE = 172;
181+
const ERR_INVALID_SERVER_RESPONSE = 173;
181182

182183
// Oracle Net layer errors start from 500
183184
const ERR_CONNECTION_CLOSED = 500;
@@ -539,6 +540,8 @@ messages.set(ERR_SESSIONLESS_ALREADY_ACTIVE, //NJS-171
539540
'Suspend, commit or rollback the currently active sessionless transaction before beginning or resuming another one.');
540541
messages.set(ERR_SESSIONLESS_INACTIVE, //NJS-172
541542
'No sessionless transaction is active');
543+
messages.set(ERR_INVALID_SERVER_RESPONSE, //NJS-173
544+
'Invalid server response to connection request');
542545

543546
// Oracle Net layer errors
544547

@@ -999,6 +1002,7 @@ module.exports = {
9991002
ERR_SESSIONLESS_DIFFERING_METHODS,
10001003
ERR_SESSIONLESS_ALREADY_ACTIVE,
10011004
ERR_SESSIONLESS_INACTIVE,
1005+
ERR_INVALID_SERVER_RESPONSE,
10021006
ERR_CONNECTION_CLOSED_CODE: `${ERR_PREFIX}-${ERR_CONNECTION_CLOSED}`,
10031007
ERR_OPERATION_NOT_SUPPORTED_ON_BFILE,
10041008
ERR_OPERATION_ONLY_SUPPORTED_ON_BFILE,

lib/thin/connection.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,36 @@ class ThinConnectionImpl extends ConnectionImpl {
781781
return (this._pool) ? true : false;
782782
}
783783

784+
_postConnect(authMessage) {
785+
let releaseNum;
786+
let updateNum;
787+
let portReleaseNum;
788+
let portUpdateNum;
789+
790+
this.dbDomain = authMessage.sessionData['AUTH_SC_DB_DOMAIN'];
791+
this.dbName = authMessage.sessionData['AUTH_DBNAME'];
792+
this.maxOpenCursors = Number(authMessage.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
793+
this.serviceName = authMessage.sessionData['AUTH_SC_SERVICE_NAME'];
794+
this.instanceName = authMessage.sessionData['AUTH_INSTANCENAME'];
795+
this.maxIdentifierLength = Number(authMessage.sessionData['AUTH_MAX_IDEN_LENGTH'] || 30);
796+
const fullVersionNum = Number(authMessage.sessionData['AUTH_VERSION_NO']);
797+
const versionNum = (fullVersionNum >> 24) & 0xFF;
798+
this.warning = authMessage.warning;
799+
if (this._protocol.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
800+
releaseNum = (fullVersionNum >> 16) & 0xFF;
801+
updateNum = (fullVersionNum >> 12) & 0x0F;
802+
portReleaseNum = (fullVersionNum >> 4) & 0xFF;
803+
portUpdateNum = fullVersionNum & 0x0F;
804+
} else {
805+
releaseNum = (fullVersionNum >> 20) & 0x0F;
806+
updateNum = (fullVersionNum >> 12) & 0xFF;
807+
portReleaseNum = (fullVersionNum >> 8) & 0x0F;
808+
portUpdateNum = fullVersionNum & 0xFF;
809+
}
810+
this.serverVersionString = versionNum + '.' + releaseNum + '.' + updateNum + '.' + portReleaseNum + '.' + portUpdateNum;
811+
this.serverVersion = versionNum * 100000000 + releaseNum * 1000000 + updateNum * 10000 + portReleaseNum * 100 + portUpdateNum * 1;
812+
}
813+
784814
/**
785815
*
786816
* @param {object} params Configuration of the connection
@@ -895,6 +925,7 @@ class ThinConnectionImpl extends ConnectionImpl {
895925
if (!params.externalAuth) { // non-token Authentication
896926
await this._protocol._processMessage(authMessage); // OAUTH
897927
}
928+
this._postConnect(authMessage);
898929
} catch (err) {
899930
this.nscon.disconnect();
900931
throw err;

lib/thin/protocol/capabilities.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ class Capabilities {
118118
this.compileCaps[constants.TNS_CCAP_TTC4] |= constants.TNS_CCAP_END_OF_REQUEST;
119119
}
120120
this.compileCaps[constants.TNS_CCAP_CTB_FEATURE_BACKPORT] =
121-
constants.TNS_CCAP_CTB_IMPLICIT_POOL;
121+
constants.TNS_CCAP_CTB_IMPLICIT_POOL |
122+
constants.TNS_CCAP_CTB_OAUTH_MSG_ON_ERR;
122123
this.compileCaps[constants.TNS_CCAP_TTC5] =
123124
constants.TNS_CCAP_VECTOR_SUPPORT |
124125
constants.TNS_CCAP_TTC5_SESSIONLESS_TXNS;

lib/thin/protocol/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ module.exports = {
648648
TNS_CCAP_LOB2_QUASI: 0x01,
649649
TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
650650
TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
651+
TNS_CCAP_CTB_OAUTH_MSG_ON_ERR: 0x10,
651652
TNS_CCAP_VECTOR_SUPPORT: 0x08,
652653
TNS_CCAP_VECTOR_FEATURE_BINARY: 0x01,
653654
TNS_CCAP_VECTOR_FEATURE_SPARSE: 0x02,

lib/thin/protocol/encryptDecrypt.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class EncryptDecrypt {
4040

4141
// Key length is dependent on the algorithm. In this case for aes192, it is
4242
// 24 bytes (192 bits).
43-
_decrypt(key, val) {
43+
decrypt(key, val) {
4444
const iv = Buffer.alloc(16, 0); // Initialization vector, same is used in server
4545
const decipher = crypto.createDecipheriv(algorithm, key, iv);
4646
decipher.setAutoPadding(false);
@@ -138,7 +138,7 @@ class EncryptDecrypt {
138138
if (newPassword) {
139139
newPasswordBytes = Buffer.from(newPassword, 'utf8');
140140
}
141-
const sessionKeyParta = this._decrypt(passwordHash, encodedServerKey);
141+
const sessionKeyParta = this.decrypt(passwordHash, encodedServerKey);
142142
const sessionKeyPartb = Buffer.alloc(sessionKeyParta.length);
143143
crypto.randomFillSync(sessionKeyPartb);
144144
const encodedClientKey = this._encrypt(passwordHash, sessionKeyPartb);

lib/thin/protocol/messages/auth.js

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -355,34 +355,19 @@ class AuthMessage extends Message {
355355
}
356356
if (this.functionCode === constants.TNS_FUNC_AUTH_PHASE_ONE) {
357357
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
358-
} else {
359-
let releaseNum;
360-
let updateNum;
361-
let portReleaseNum;
362-
let portUpdateNum;
363-
364-
this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'];
365-
this.conn.dbName = this.sessionData['AUTH_DBNAME'];
366-
this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
367-
this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
368-
this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
369-
this.conn.maxIdentifierLength = Number(this.sessionData['AUTH_MAX_IDEN_LENGTH'] || 30);
370-
const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
371-
const versionNum = (fullVersionNum >> 24) & 0xFF;
372-
this.conn.warning = this.warning;
373-
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
374-
releaseNum = (fullVersionNum >> 16) & 0xFF;
375-
updateNum = (fullVersionNum >> 12) & 0x0F;
376-
portReleaseNum = (fullVersionNum >> 4) & 0xFF;
377-
portUpdateNum = fullVersionNum & 0x0F;
378-
} else {
379-
releaseNum = (fullVersionNum >> 20) & 0x0F;
380-
updateNum = (fullVersionNum >> 12) & 0xFF;
381-
portReleaseNum = (fullVersionNum >> 8) & 0x0F;
382-
portUpdateNum = fullVersionNum & 0xFF;
358+
} else if (!this.changePassword && this.comboKey) {
359+
const value = this.sessionData.AUTH_SVR_RESPONSE;
360+
let response;
361+
if (value) {
362+
const encodedResponse = Buffer.from(value, "hex");
363+
response = ED.decrypt(this.comboKey, encodedResponse);
364+
}
365+
if (
366+
!response ||
367+
!response.subarray(16, 32).equals(Buffer.from("SERVER_TO_CLIENT"))
368+
) {
369+
errors.throwErr(errors.ERR_INVALID_SERVER_RESPONSE);
383370
}
384-
this.conn.serverVersionString = versionNum + '.' + releaseNum + '.' + updateNum + '.' + portReleaseNum + '.' + portUpdateNum;
385-
this.conn.serverVersion = versionNum * 100000000 + releaseNum * 1000000 + updateNum * 10000 + portReleaseNum * 100 + portUpdateNum * 1;
386371
}
387372
}
388373

0 commit comments

Comments
 (0)