Skip to content

Commit 850d986

Browse files
committed
Add support for TLS external passwordless authentication
1 parent 0e400b9 commit 850d986

File tree

13 files changed

+621
-100
lines changed

13 files changed

+621
-100
lines changed

doc/src/release_notes.rst

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

31+
#) Added support for External Authentication using Transport Layer Security(TLS).
32+
3133
#) Fixed issue that does not throw Authentication error for FastAuth
3234
when invalid token is used with external authentication.
3335

lib/errors.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
2-
32
//-----------------------------------------------------------------------------
43
//
54
// This software is dual-licensed to you under the Universal Permissive License
@@ -204,6 +203,9 @@ const ERR_AZURE_VAULT_AUTH_FAILED = 527;
204203
const ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED = 528;
205204
const ERR_WALLET_TYPE_NOT_SUPPORTED = 529;
206205
const ERR_HOST_NOT_FOUND = 530;
206+
const ERR_ANO_PACKET = 531;
207+
const ERR_ANO_STATUS = 532;
208+
const ERR_ANO_NEGOTIATION = 533;
207209

208210
// Oracle SUCCESS_WITH_INFO warning start from 700
209211
const WRN_COMPILATION_CREATE = 700;
@@ -540,23 +542,29 @@ messages.set(ERR_AZURE_CONFIG_PROVIDER_AUTH_FAILED, // NJS-522
540542
'Azure Authentication Failed: The authentication parameter value %s may be incorrect');
541543
messages.set(ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG, // NJS-523
542544
'Failed to retrieve configuration from Centralized Configuration Provider:\n %s');
543-
messages.set(ERR_CONFIG_PROVIDER_NOT_SUPPORTED, // NJS-524
545+
messages.set(ERR_CONFIG_PROVIDER_NOT_SUPPORTED, // NJS-524
544546
'Configuration Provider not supported: %s');
545-
messages.set(ERR_CONFIG_PROVIDER_LOAD_FAILED, // NJS-525
547+
messages.set(ERR_CONFIG_PROVIDER_LOAD_FAILED, // NJS-525
546548
'Centralized Config Provider failed to load required libraries. Please install the required libraries.\n %s');
547-
messages.set(ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED, // NJS-526
549+
messages.set(ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED, // NJS-526
548550
'OCI authentication failed: The authentication parameter value %s may be incorrect');
549-
messages.set(ERR_AZURE_VAULT_AUTH_FAILED, // NJS-527
551+
messages.set(ERR_AZURE_VAULT_AUTH_FAILED, // NJS-527
550552
'Azure Vault: Provide correct Azure Vault authentication details');
551-
messages.set(ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED, // NJS-528
553+
messages.set(ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED, // NJS-528
552554
'Azure service principal authentication requires either a client certificate path or a client secret string');
553-
messages.set(ERR_WALLET_TYPE_NOT_SUPPORTED, // NJS-529
555+
messages.set(ERR_WALLET_TYPE_NOT_SUPPORTED, // NJS-529
554556
'Invalid wallet content format. Supported format is PEM');
555-
messages.set(ERR_HOST_NOT_FOUND, // NJS-530
557+
messages.set(ERR_HOST_NOT_FOUND, // NJS-530
556558
'The host addresses or URLs provided by the connect string are incorrect or unresolvable in your network.');
559+
messages.set(ERR_ANO_PACKET, // NJS-531
560+
'Error in Advanced Networking Option packet received from the server');
561+
messages.set(ERR_ANO_STATUS, // NJS-532
562+
'%s service recieved status failure');
563+
messages.set(ERR_ANO_NEGOTIATION, // NJS-533
564+
'Advanced Networking Option service negotiation failed. Native Network Encryption and DataIntegrity only supported in node-oracledb thick mode.\nCause: ORA-%s');
557565

558566
// Oracle SUCCESS_WITH_INFO warning
559-
messages.set(WRN_COMPILATION_CREATE, // NJS-700
567+
messages.set(WRN_COMPILATION_CREATE, // NJS-700
560568
'creation succeeded with compilation errors');
561569

562570
//-----------------------------------------------------------------------------
@@ -721,6 +729,14 @@ function throwErr() {
721729
throw (getErr(...arguments));
722730
}
723731

732+
function throwErrWithORAError() {
733+
const err = (getErr(...arguments));
734+
const pos = err.message.indexOf("ORA-");
735+
const oraError = err.message.substring(pos + 4, pos + 9);
736+
err.message = err.message + '\nHelp: https://docs.oracle.com/error-help/db/ora-' + oraError;
737+
throw err;
738+
}
739+
724740
//-----------------------------------------------------------------------------
725741
// throwNotImplemented()
726742
//
@@ -730,6 +746,7 @@ function throwNotImplemented(feature) {
730746
throwErr(ERR_NOT_IMPLEMENTED, feature);
731747
}
732748

749+
733750
//-----------------------------------------------------------------------------
734751
// transformErr()
735752
//
@@ -872,6 +889,9 @@ module.exports = {
872889
ERR_CONFIG_PROVIDER_LOAD_FAILED,
873890
ERR_WALLET_TYPE_NOT_SUPPORTED,
874891
ERR_HOST_NOT_FOUND,
892+
ERR_ANO_PACKET,
893+
ERR_ANO_STATUS,
894+
ERR_ANO_NEGOTIATION,
875895
ERR_INVALID_BIND_NAME,
876896
ERR_WRONG_NUMBER_OF_BINDS,
877897
ERR_BUFFER_LENGTH_INSUFFICIENT,
@@ -955,6 +975,7 @@ module.exports = {
955975
assertPropValue,
956976
getErr,
957977
throwErr,
978+
throwErrWithORAError,
958979
throwNotImplemented,
959980
transformErr
960981
};

lib/thin/connection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ class ThinConnectionImpl extends ConnectionImpl {
839839
this.nscon.endOfRequestSupport = endOfRequestSupport;
840840
await this._protocol._processMessage(authMessage);
841841
}
842-
if (!params.token) { // non-token Authentication
842+
if (!params.externalAuth) { // non-token Authentication
843843
await this._protocol._processMessage(authMessage); // OAUTH
844844
}
845845
} catch (err) {

lib/thin/protocol/messages/auth.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,10 @@ class AuthMessage extends Message {
9494
this.userByteLen = 0;
9595
}
9696
this.token = config.token;
97-
if (this.token)
97+
if (config.externalAuth) {
9898
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
99+
this.externalAuth = true;
100+
}
99101
this.privateKey = config.privateKey;
100102
if (this.privateKey) {
101103
this.privateKey = util.normalizePrivateKey(this.privateKey);
@@ -146,7 +148,7 @@ class AuthMessage extends Message {
146148
if (this.newPassword) {
147149
this.authMode |= constants.TNS_AUTH_MODE_CHANGE_PASSWORD;
148150
}
149-
if (!this.token) {
151+
if (!config.externalAuth) {
150152
this.authMode |= constants.TNS_AUTH_MODE_WITH_PASSWORD;
151153
}
152154
}
@@ -204,8 +206,10 @@ class AuthMessage extends Message {
204206
numPairs = 2;
205207
} else {
206208
numPairs = 4;
207-
if (this.token) {
208-
numPairs += 1;
209+
if (this.externalAuth) {
210+
numPairs += 5;
211+
if (this.token)
212+
numPairs += 1;
209213
} else {
210214
numPairs += 2;
211215
if (this.verifierType === constants.TNS_VERIFIER_TYPE_11G_1 ||
@@ -254,10 +258,17 @@ class AuthMessage extends Message {
254258
buf.writeUInt8(1);
255259
if (this.userByteLen > 0)
256260
buf.writeBytesWithLength(Buffer.from(this.username));
261+
if (this.externalAuth) {
262+
buf.writeKeyValue("AUTH_TERMINAL", this.terminal ?? cInfo.terminal);
263+
buf.writeKeyValue("AUTH_PROGRAM_NM", this.program ?? cInfo.program);
264+
buf.writeKeyValue("AUTH_MACHINE", this.machine ?? cInfo.hostName);
265+
buf.writeKeyValue("AUTH_PID", cInfo.pid);
266+
buf.writeKeyValue("AUTH_SID", this.osUser ?? cInfo.userName);
267+
}
257268
if (this.token) {
258269
buf.writeKeyValue("AUTH_TOKEN", this.token);
259270
} else {
260-
if (!this.changePassword) {
271+
if (!this.changePassword && !this.externalAuth) {
261272
buf.writeKeyValue("AUTH_SESSKEY", this.sessionKey, 1);
262273
if (!verifier11G) {
263274
buf.writeKeyValue("AUTH_PBKDF2_SPEEDY_KEY", this.speedyKey);

0 commit comments

Comments
 (0)