@tachybase/module-multi-app 1.6.0 → 1.6.2
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/README.md +34 -34
- package/README.zh-CN.md +34 -34
- package/client.d.ts +1 -1
- package/client.js +1 -1
- package/dist/externalVersion.js +5 -5
- package/dist/locale/en-US.json +48 -48
- package/dist/locale/es-ES.json +9 -9
- package/dist/locale/ko_KR.json +11 -11
- package/dist/locale/pt-BR.json +9 -9
- package/dist/locale/zh-CN.json +58 -58
- package/dist/node_modules/mariadb/callback.js +43 -8
- package/dist/node_modules/mariadb/check-node.js +30 -0
- package/dist/node_modules/mariadb/lib/cluster-callback.js +84 -0
- package/dist/node_modules/mariadb/lib/cluster.js +446 -0
- package/dist/node_modules/mariadb/lib/cmd/batch-bulk.js +576 -177
- package/dist/node_modules/mariadb/lib/cmd/change-user.js +54 -44
- package/dist/node_modules/mariadb/lib/cmd/class/ok-packet.js +3 -2
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-cache-wrapper.js +46 -0
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-result-packet.js +141 -0
- package/dist/node_modules/mariadb/lib/cmd/class/prepare-wrapper.js +70 -0
- package/dist/node_modules/mariadb/lib/cmd/close-prepare.js +38 -0
- package/dist/node_modules/mariadb/lib/cmd/column-definition.js +145 -47
- package/dist/node_modules/mariadb/lib/cmd/command.js +41 -75
- package/dist/node_modules/mariadb/lib/cmd/decoder/binary-decoder.js +282 -0
- package/dist/node_modules/mariadb/lib/cmd/decoder/text-decoder.js +210 -0
- package/dist/node_modules/mariadb/lib/cmd/{common-binary-cmd.js → encoder/binary-encoder.js} +34 -77
- package/dist/node_modules/mariadb/lib/cmd/encoder/text-encoder.js +311 -0
- package/dist/node_modules/mariadb/lib/cmd/execute-stream.js +61 -0
- package/dist/node_modules/mariadb/lib/cmd/execute.js +338 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/caching-sha2-password-auth.js +25 -62
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/clear-password-auth.js +39 -6
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/ed25519-password-auth.js +48 -16
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/handshake.js +198 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/{initial-handshake.js → auth/initial-handshake.js} +10 -8
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/native-password-auth.js +22 -9
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/pam-password-auth.js +9 -4
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/parsec-auth.js +115 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/plugin-auth.js +12 -5
- package/dist/node_modules/mariadb/lib/cmd/handshake/auth/sha256-password-auth.js +44 -33
- package/dist/node_modules/mariadb/lib/cmd/handshake/authentication.js +335 -0
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-capabilities.js +20 -19
- package/dist/node_modules/mariadb/lib/cmd/handshake/ssl-request.js +6 -3
- package/dist/node_modules/mariadb/lib/cmd/parser.js +861 -0
- package/dist/node_modules/mariadb/lib/cmd/ping.js +17 -18
- package/dist/node_modules/mariadb/lib/cmd/prepare.js +170 -0
- package/dist/node_modules/mariadb/lib/cmd/query.js +281 -144
- package/dist/node_modules/mariadb/lib/cmd/quit.js +9 -6
- package/dist/node_modules/mariadb/lib/cmd/reset.js +15 -19
- package/dist/node_modules/mariadb/lib/cmd/stream.js +21 -6
- package/dist/node_modules/mariadb/lib/config/cluster-options.js +23 -0
- package/dist/node_modules/mariadb/lib/config/connection-options.js +196 -132
- package/dist/node_modules/mariadb/lib/config/pool-options.js +27 -19
- package/dist/node_modules/mariadb/lib/connection-callback.js +492 -120
- package/dist/node_modules/mariadb/lib/connection-promise.js +372 -0
- package/dist/node_modules/mariadb/lib/connection.js +1739 -1016
- package/dist/node_modules/mariadb/lib/const/capabilities.js +36 -30
- package/dist/node_modules/mariadb/lib/const/collations.js +972 -36
- package/dist/node_modules/mariadb/lib/const/connection_status.js +3 -0
- package/dist/node_modules/mariadb/lib/const/error-code.js +35 -11
- package/dist/node_modules/mariadb/lib/const/field-detail.js +3 -0
- package/dist/node_modules/mariadb/lib/const/field-type.js +7 -4
- package/dist/node_modules/mariadb/lib/const/server-status.js +4 -1
- package/dist/node_modules/mariadb/lib/const/state-change.js +3 -0
- package/dist/node_modules/mariadb/lib/filtered-cluster-callback.js +136 -0
- package/dist/node_modules/mariadb/lib/filtered-cluster.js +118 -0
- package/dist/node_modules/mariadb/lib/io/compression-input-stream.js +14 -13
- package/dist/node_modules/mariadb/lib/io/compression-output-stream.js +21 -18
- package/dist/node_modules/mariadb/lib/io/packet-input-stream.js +75 -64
- package/dist/node_modules/mariadb/lib/io/packet-node-encoded.js +13 -9
- package/dist/node_modules/mariadb/lib/io/packet-node-iconv.js +12 -10
- package/dist/node_modules/mariadb/lib/io/packet-output-stream.js +402 -134
- package/dist/node_modules/mariadb/lib/io/packet.js +287 -202
- package/dist/node_modules/mariadb/lib/lru-prepare-cache.js +84 -0
- package/dist/node_modules/mariadb/lib/misc/connection-information.js +15 -32
- package/dist/node_modules/mariadb/lib/misc/errors.js +68 -25
- package/dist/node_modules/mariadb/lib/misc/parse.js +207 -711
- package/dist/node_modules/mariadb/lib/misc/utils.js +34 -62
- package/dist/node_modules/mariadb/lib/pool-callback.js +213 -174
- package/dist/node_modules/mariadb/lib/pool-promise.js +228 -94
- package/dist/node_modules/mariadb/lib/pool.js +951 -0
- package/dist/node_modules/mariadb/package.json +1 -1
- package/dist/node_modules/mariadb/promise.js +1 -34
- package/dist/node_modules/mariadb/types/callback.d.ts +207 -0
- package/dist/node_modules/mariadb/types/index.d.ts +94 -674
- package/dist/node_modules/mariadb/types/share.d.ts +804 -0
- package/dist/node_modules/qs/package.json +1 -1
- package/dist/server/actions/apps.js +2 -2
- package/dist/server/app-lifecycle.d.ts +1 -1
- package/dist/server/app-lifecycle.js +4 -4
- package/dist/server/models/application.d.ts +1 -1
- package/package.json +7 -7
- package/server.d.ts +2 -2
- package/server.js +1 -1
- package/dist/node_modules/mariadb/lib/cmd/batch-rewrite.js +0 -372
- package/dist/node_modules/mariadb/lib/cmd/common-text-cmd.js +0 -427
- package/dist/node_modules/mariadb/lib/cmd/handshake/client-handshake-response.js +0 -126
- package/dist/node_modules/mariadb/lib/cmd/handshake/handshake.js +0 -292
- package/dist/node_modules/mariadb/lib/cmd/resultset.js +0 -607
- package/dist/node_modules/mariadb/lib/config/pool-cluster-options.js +0 -19
- package/dist/node_modules/mariadb/lib/filtered-pool-cluster.js +0 -81
- package/dist/node_modules/mariadb/lib/io/bulk-packet.js +0 -590
- package/dist/node_modules/mariadb/lib/io/rewrite-packet.js +0 -481
- package/dist/node_modules/mariadb/lib/pool-base.js +0 -611
- package/dist/node_modules/mariadb/lib/pool-cluster-callback.js +0 -66
- package/dist/node_modules/mariadb/lib/pool-cluster.js +0 -407
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
|
3
|
+
|
|
1
4
|
const PluginAuth = require('./plugin-auth');
|
|
2
5
|
const fs = require('fs');
|
|
3
|
-
const crypto = require('crypto');
|
|
4
6
|
const Errors = require('../../../misc/errors');
|
|
5
|
-
const NativePasswordAuth = require('./native-password-auth');
|
|
6
7
|
const Sha256PasswordAuth = require('./sha256-password-auth');
|
|
7
8
|
|
|
8
9
|
const State = {
|
|
@@ -16,10 +17,12 @@ const State = {
|
|
|
16
17
|
* Use caching Sha2 password authentication
|
|
17
18
|
*/
|
|
18
19
|
class CachingSha2PasswordAuth extends PluginAuth {
|
|
19
|
-
constructor(packSeq, compressPackSeq, pluginData,
|
|
20
|
-
super(
|
|
20
|
+
constructor(packSeq, compressPackSeq, pluginData, cmdParam, reject, multiAuthResolver) {
|
|
21
|
+
super(cmdParam, multiAuthResolver, reject);
|
|
22
|
+
this.multiAuthResolver = multiAuthResolver;
|
|
21
23
|
this.pluginData = pluginData;
|
|
22
24
|
this.sequenceNo = packSeq;
|
|
25
|
+
this.compressSequenceNo = compressPackSeq;
|
|
23
26
|
this.counter = 0;
|
|
24
27
|
this.state = State.INIT;
|
|
25
28
|
}
|
|
@@ -29,15 +32,15 @@ class CachingSha2PasswordAuth extends PluginAuth {
|
|
|
29
32
|
this.onPacketReceive = this.response;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
exchange(
|
|
35
|
+
exchange(packet, out, opts, info) {
|
|
33
36
|
switch (this.state) {
|
|
34
37
|
case State.INIT:
|
|
35
38
|
const truncatedSeed = this.pluginData.slice(0, this.pluginData.length - 1);
|
|
36
|
-
const encPwd =
|
|
39
|
+
const encPwd = Sha256PasswordAuth.encryptSha256Password(opts.password, truncatedSeed);
|
|
37
40
|
out.startPacket(this);
|
|
38
41
|
if (encPwd.length > 0) {
|
|
39
42
|
out.writeBuffer(encPwd, 0, encPwd.length);
|
|
40
|
-
out.
|
|
43
|
+
out.flushPacket();
|
|
41
44
|
} else {
|
|
42
45
|
out.writeEmptyPacket(true);
|
|
43
46
|
}
|
|
@@ -46,12 +49,12 @@ class CachingSha2PasswordAuth extends PluginAuth {
|
|
|
46
49
|
|
|
47
50
|
case State.FAST_AUTH_RESULT:
|
|
48
51
|
// length encoded numeric : 0x01 0x03/0x04
|
|
49
|
-
const fastAuthResult =
|
|
52
|
+
const fastAuthResult = packet[1];
|
|
50
53
|
switch (fastAuthResult) {
|
|
51
54
|
case 0x03:
|
|
52
55
|
// success authentication
|
|
53
|
-
|
|
54
|
-
return
|
|
56
|
+
// an OK_Packet will follow
|
|
57
|
+
return;
|
|
55
58
|
|
|
56
59
|
case 0x04:
|
|
57
60
|
if (opts.ssl) {
|
|
@@ -59,7 +62,7 @@ class CachingSha2PasswordAuth extends PluginAuth {
|
|
|
59
62
|
out.startPacket(this);
|
|
60
63
|
out.writeString(opts.password);
|
|
61
64
|
out.writeInt8(0);
|
|
62
|
-
out.
|
|
65
|
+
out.flushPacket();
|
|
63
66
|
return;
|
|
64
67
|
}
|
|
65
68
|
|
|
@@ -71,29 +74,20 @@ class CachingSha2PasswordAuth extends PluginAuth {
|
|
|
71
74
|
// rsaPublicKey contain path
|
|
72
75
|
key = fs.readFileSync(key, 'utf8');
|
|
73
76
|
}
|
|
74
|
-
this.publicKey = Sha256PasswordAuth.
|
|
77
|
+
this.publicKey = Sha256PasswordAuth.retrievePublicKey(key);
|
|
75
78
|
} catch (err) {
|
|
76
79
|
return this.throwError(err, info);
|
|
77
80
|
}
|
|
78
81
|
// send Sha256Password Packet
|
|
79
|
-
Sha256PasswordAuth.sendSha256PwdPacket(
|
|
80
|
-
this,
|
|
81
|
-
this.pluginData,
|
|
82
|
-
this.publicKey,
|
|
83
|
-
opts.password,
|
|
84
|
-
out
|
|
85
|
-
);
|
|
82
|
+
Sha256PasswordAuth.sendSha256PwdPacket(this, this.pluginData, this.publicKey, opts.password, out);
|
|
86
83
|
} else {
|
|
87
84
|
if (!opts.allowPublicKeyRetrieval) {
|
|
88
85
|
return this.throwError(
|
|
89
|
-
Errors.
|
|
86
|
+
Errors.createFatalError(
|
|
90
87
|
'RSA public key is not available client side. Either set option `cachingRsaPublicKey` to indicate' +
|
|
91
88
|
' public key path, or allow public key retrieval with option `allowPublicKeyRetrieval`',
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
info,
|
|
95
|
-
'08S01',
|
|
96
|
-
Errors.ER_CANNOT_RETRIEVE_RSA_KEY
|
|
89
|
+
Errors.ER_CANNOT_RETRIEVE_RSA_KEY,
|
|
90
|
+
info
|
|
97
91
|
),
|
|
98
92
|
info
|
|
99
93
|
);
|
|
@@ -102,48 +96,17 @@ class CachingSha2PasswordAuth extends PluginAuth {
|
|
|
102
96
|
// ask caching public Key Retrieval
|
|
103
97
|
out.startPacket(this);
|
|
104
98
|
out.writeInt8(0x02);
|
|
105
|
-
out.
|
|
99
|
+
out.flushPacket();
|
|
106
100
|
}
|
|
107
|
-
return;
|
|
108
101
|
}
|
|
102
|
+
return;
|
|
109
103
|
|
|
110
104
|
case State.REQUEST_SERVER_KEY:
|
|
111
|
-
this.publicKey = Sha256PasswordAuth.
|
|
105
|
+
this.publicKey = Sha256PasswordAuth.retrievePublicKey(packet.toString(undefined, 1));
|
|
112
106
|
this.state = State.SEND_AUTH;
|
|
113
|
-
Sha256PasswordAuth.sendSha256PwdPacket(
|
|
114
|
-
|
|
115
|
-
this.pluginData,
|
|
116
|
-
this.publicKey,
|
|
117
|
-
opts.password,
|
|
118
|
-
out
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
static retreivePublicKey(key) {
|
|
124
|
-
return key.replace('(-+BEGIN PUBLIC KEY-+\\r?\\n|\\n?-+END PUBLIC KEY-+\\r?\\n?)', '');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
static sendSha256PwdPacket(cmd, pluginData, publicKey, password, out) {
|
|
128
|
-
const truncatedSeed = pluginData.slice(0, pluginData.length - 1);
|
|
129
|
-
out.startPacket(cmd);
|
|
130
|
-
const enc = Sha256PasswordAuth.encrypt(truncatedSeed, password, publicKey);
|
|
131
|
-
out.writeBuffer(enc, 0, enc.length);
|
|
132
|
-
out.flushBuffer(cmd);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// encrypt password with public key
|
|
136
|
-
static encrypt(seed, password, publicKey) {
|
|
137
|
-
const nullFinishedPwd = Buffer.from(password + '\0');
|
|
138
|
-
const xorBytes = Buffer.allocUnsafe(nullFinishedPwd.length);
|
|
139
|
-
const seedLength = seed.length;
|
|
140
|
-
for (let i = 0; i < xorBytes.length; i++) {
|
|
141
|
-
xorBytes[i] = nullFinishedPwd[i] ^ seed[i % seedLength];
|
|
107
|
+
Sha256PasswordAuth.sendSha256PwdPacket(this, this.pluginData, this.publicKey, opts.password, out);
|
|
108
|
+
return;
|
|
142
109
|
}
|
|
143
|
-
return crypto.publicEncrypt(
|
|
144
|
-
{ key: publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
|
|
145
|
-
xorBytes
|
|
146
|
-
);
|
|
147
110
|
}
|
|
148
111
|
|
|
149
112
|
response(packet, out, opts, info) {
|
|
@@ -155,7 +118,7 @@ class CachingSha2PasswordAuth extends PluginAuth {
|
|
|
155
118
|
case 0x00:
|
|
156
119
|
case 0xff:
|
|
157
120
|
this.emit('send_end');
|
|
158
|
-
return this.
|
|
121
|
+
return this.multiAuthResolver(packet, out, opts, info);
|
|
159
122
|
|
|
160
123
|
default:
|
|
161
124
|
let promptData = packet.readBufferRemaining();
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
|
3
|
+
|
|
1
4
|
const PluginAuth = require('./plugin-auth');
|
|
2
5
|
|
|
3
6
|
/**
|
|
@@ -5,18 +8,48 @@ const PluginAuth = require('./plugin-auth');
|
|
|
5
8
|
* (used only when SSL is active)
|
|
6
9
|
*/
|
|
7
10
|
class ClearPasswordAuth extends PluginAuth {
|
|
8
|
-
constructor(packSeq, compressPackSeq, pluginData,
|
|
9
|
-
super(
|
|
11
|
+
constructor(packSeq, compressPackSeq, pluginData, cmdParam, reject, multiAuthResolver) {
|
|
12
|
+
super(cmdParam, multiAuthResolver, reject);
|
|
10
13
|
this.sequenceNo = packSeq;
|
|
14
|
+
this.compressSequenceNo = compressPackSeq;
|
|
15
|
+
this.counter = 0;
|
|
16
|
+
this.multiAuthResolver = multiAuthResolver;
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
start(out, opts, info) {
|
|
14
20
|
out.startPacket(this);
|
|
15
|
-
|
|
21
|
+
const pwd = opts.password;
|
|
22
|
+
if (pwd) {
|
|
23
|
+
if (Array.isArray(pwd)) {
|
|
24
|
+
out.writeString(pwd[this.counter++]);
|
|
25
|
+
} else {
|
|
26
|
+
out.writeString(pwd);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
16
29
|
out.writeInt8(0);
|
|
17
|
-
out.
|
|
18
|
-
this.
|
|
19
|
-
|
|
30
|
+
out.flushPacket();
|
|
31
|
+
this.onPacketReceive = this.response;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
response(packet, out, opts, info) {
|
|
35
|
+
const marker = packet.peek();
|
|
36
|
+
switch (marker) {
|
|
37
|
+
//*********************************************************************************************************
|
|
38
|
+
//* OK_Packet and Err_Packet ending packet
|
|
39
|
+
//*********************************************************************************************************
|
|
40
|
+
case 0x00:
|
|
41
|
+
case 0xff:
|
|
42
|
+
this.emit('send_end');
|
|
43
|
+
return this.multiAuthResolver(packet, out, opts, info);
|
|
44
|
+
|
|
45
|
+
default:
|
|
46
|
+
packet.readBuffer(); // prompt
|
|
47
|
+
out.startPacket(this);
|
|
48
|
+
|
|
49
|
+
out.writeString('password');
|
|
50
|
+
out.writeInt8(0);
|
|
51
|
+
out.flushPacket();
|
|
52
|
+
}
|
|
20
53
|
}
|
|
21
54
|
}
|
|
22
55
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
|
3
|
+
|
|
1
4
|
'use strict';
|
|
2
5
|
|
|
3
6
|
const PluginAuth = require('./plugin-auth');
|
|
@@ -7,10 +10,11 @@ const Crypto = require('crypto');
|
|
|
7
10
|
* Standard authentication plugin
|
|
8
11
|
*/
|
|
9
12
|
class Ed25519PasswordAuth extends PluginAuth {
|
|
10
|
-
constructor(packSeq, compressPackSeq, pluginData,
|
|
11
|
-
super(
|
|
13
|
+
constructor(packSeq, compressPackSeq, pluginData, cmdParam, reject, multiAuthResolver) {
|
|
14
|
+
super(cmdParam, multiAuthResolver, reject);
|
|
12
15
|
this.pluginData = pluginData;
|
|
13
16
|
this.sequenceNo = packSeq;
|
|
17
|
+
this.compressSequenceNo = compressPackSeq;
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
start(out, opts, info) {
|
|
@@ -20,9 +24,8 @@ class Ed25519PasswordAuth extends PluginAuth {
|
|
|
20
24
|
const sign = Ed25519PasswordAuth.encryptPassword(opts.password, data);
|
|
21
25
|
out.startPacket(this);
|
|
22
26
|
out.writeBuffer(sign, 0, sign.length);
|
|
23
|
-
out.
|
|
27
|
+
out.flushPacket();
|
|
24
28
|
this.emit('send_end');
|
|
25
|
-
this.onPacketReceive = this.successSend;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
static encryptPassword(password, seed) {
|
|
@@ -43,7 +46,7 @@ class Ed25519PasswordAuth extends PluginAuth {
|
|
|
43
46
|
for (i = 0; i < 32; i++) signedMsg[32 + i] = d[32 + i];
|
|
44
47
|
|
|
45
48
|
hash = Crypto.createHash('sha512');
|
|
46
|
-
const r = hash.update(signedMsg.
|
|
49
|
+
const r = hash.update(signedMsg.subarray(32, 96)).digest();
|
|
47
50
|
|
|
48
51
|
reduce(r);
|
|
49
52
|
scalarbase(p, r);
|
|
@@ -73,14 +76,43 @@ class Ed25519PasswordAuth extends PluginAuth {
|
|
|
73
76
|
|
|
74
77
|
modL(signedMsg.subarray(32), x);
|
|
75
78
|
|
|
76
|
-
return signedMsg.
|
|
79
|
+
return signedMsg.subarray(0, 64);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
permitHash() {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
hash(conf) {
|
|
87
|
+
let i;
|
|
88
|
+
let p = [gf(), gf(), gf(), gf()];
|
|
89
|
+
const signedMsg = Buffer.alloc(96);
|
|
90
|
+
const bytePwd = Buffer.from(conf.password);
|
|
91
|
+
|
|
92
|
+
let hash = Crypto.createHash('sha512');
|
|
93
|
+
const d = hash.update(bytePwd).digest();
|
|
94
|
+
d[0] &= 248;
|
|
95
|
+
d[31] &= 127;
|
|
96
|
+
d[31] |= 64;
|
|
97
|
+
|
|
98
|
+
for (i = 0; i < 32; i++) signedMsg[64 + i] = seed[i];
|
|
99
|
+
for (i = 0; i < 32; i++) signedMsg[32 + i] = d[32 + i];
|
|
100
|
+
|
|
101
|
+
hash = Crypto.createHash('sha512');
|
|
102
|
+
const r = hash.update(signedMsg.subarray(32, 96)).digest();
|
|
103
|
+
|
|
104
|
+
reduce(r);
|
|
105
|
+
scalarbase(p, r);
|
|
106
|
+
return r;
|
|
77
107
|
}
|
|
78
108
|
}
|
|
79
109
|
|
|
80
110
|
/*******************************************************
|
|
81
111
|
*
|
|
82
|
-
* This plugin uses the following public domain tweetnacl-js code by Dmitry Chestnykh
|
|
83
|
-
*
|
|
112
|
+
* This plugin uses the following public domain tweetnacl-js code by Dmitry Chestnykh
|
|
113
|
+
* (from https://github.com/dchest/tweetnacl-js/blob/master/nacl-fast.js).
|
|
114
|
+
* tweetnacl cannot be used directly (secret key mandatory size is 32 in nacl + implementation differ :
|
|
115
|
+
* second scalarbase use hash of secret key, not secret key).
|
|
84
116
|
*
|
|
85
117
|
*******************************************************/
|
|
86
118
|
|
|
@@ -93,21 +125,21 @@ const gf = function (init) {
|
|
|
93
125
|
const gf0 = gf(),
|
|
94
126
|
gf1 = gf([1]),
|
|
95
127
|
D2 = gf([
|
|
96
|
-
0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e,
|
|
97
|
-
|
|
128
|
+
0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df,
|
|
129
|
+
0xd9dc, 0x2406
|
|
98
130
|
]),
|
|
99
131
|
X = gf([
|
|
100
|
-
0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4,
|
|
101
|
-
|
|
132
|
+
0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e,
|
|
133
|
+
0x36d3, 0x2169
|
|
102
134
|
]),
|
|
103
135
|
Y = gf([
|
|
104
|
-
0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
|
|
105
|
-
0x6666, 0x6666
|
|
136
|
+
0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
|
|
137
|
+
0x6666, 0x6666
|
|
106
138
|
]);
|
|
107
139
|
|
|
108
140
|
const L = new Float64Array([
|
|
109
|
-
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0,
|
|
110
|
-
0, 0, 0, 0, 0, 0, 0, 0,
|
|
141
|
+
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0,
|
|
142
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0x10
|
|
111
143
|
]);
|
|
112
144
|
|
|
113
145
|
function reduce(r) {
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
|
3
|
+
|
|
4
|
+
const PluginAuth = require('./plugin-auth');
|
|
5
|
+
const InitialHandshake = require('./initial-handshake');
|
|
6
|
+
const ClientCapabilities = require('../client-capabilities');
|
|
7
|
+
const Capabilities = require('../../../const/capabilities');
|
|
8
|
+
const SslRequest = require('../ssl-request');
|
|
9
|
+
const Errors = require('../../../misc/errors');
|
|
10
|
+
const NativePasswordAuth = require('./native-password-auth');
|
|
11
|
+
const os = require('os');
|
|
12
|
+
const Iconv = require('iconv-lite');
|
|
13
|
+
const Crypto = require('crypto');
|
|
14
|
+
const driverVersion = require('../../../../package.json').version;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Handshake response
|
|
18
|
+
*/
|
|
19
|
+
class Handshake extends PluginAuth {
|
|
20
|
+
constructor(auth, getSocket, multiAuthResolver, reject) {
|
|
21
|
+
super(null, multiAuthResolver, reject);
|
|
22
|
+
this.sequenceNo = 0;
|
|
23
|
+
this.compressSequenceNo = 0;
|
|
24
|
+
this.auth = auth;
|
|
25
|
+
this.getSocket = getSocket;
|
|
26
|
+
this.counter = 0;
|
|
27
|
+
this.onPacketReceive = this.parseHandshakeInit;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
start(out, opts, info) {}
|
|
31
|
+
|
|
32
|
+
parseHandshakeInit(packet, out, opts, info) {
|
|
33
|
+
if (packet.peek() === 0xff) {
|
|
34
|
+
//in case that some host is not permit to connect server
|
|
35
|
+
const authErr = packet.readError(info);
|
|
36
|
+
authErr.fatal = true;
|
|
37
|
+
return this.throwError(authErr, info);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let handshake = new InitialHandshake(packet, info);
|
|
41
|
+
ClientCapabilities.init(opts, info);
|
|
42
|
+
this.pluginName = handshake.pluginName;
|
|
43
|
+
if (opts.ssl) {
|
|
44
|
+
if (info.serverCapabilities & Capabilities.SSL) {
|
|
45
|
+
info.clientCapabilities |= Capabilities.SSL;
|
|
46
|
+
SslRequest.send(this, out, info, opts);
|
|
47
|
+
this.auth._createSecureContext(info, () => {
|
|
48
|
+
// mark self-signed error only if was not explicitly forced
|
|
49
|
+
const secureSocket = this.getSocket();
|
|
50
|
+
info.selfSignedCertificate = !secureSocket.authorized;
|
|
51
|
+
info.tlsAuthorizationError = secureSocket.authorizationError;
|
|
52
|
+
const serverCert = secureSocket.getPeerCertificate(false);
|
|
53
|
+
info.tlsCert = serverCert;
|
|
54
|
+
info.tlsFingerprint = serverCert ? serverCert.fingerprint256.replace(/:/gi, '').toLowerCase() : null;
|
|
55
|
+
Handshake.send.call(this, this, out, opts, handshake.pluginName, info);
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
return this.throwNewError(
|
|
59
|
+
'Trying to connect with ssl, but ssl not enabled in the server',
|
|
60
|
+
true,
|
|
61
|
+
info,
|
|
62
|
+
'08S01',
|
|
63
|
+
Errors.ER_SERVER_SSL_DISABLED
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
Handshake.send(this, out, opts, handshake.pluginName, info);
|
|
68
|
+
}
|
|
69
|
+
this.onPacketReceive = this.auth.handshakeResult.bind(this.auth);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
permitHash() {
|
|
73
|
+
return this.pluginName !== 'mysql_clear_password';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
hash(conf) {
|
|
77
|
+
// mysql_native_password hash
|
|
78
|
+
let hash = Crypto.createHash('sha1');
|
|
79
|
+
let stage1 = hash.update(conf.password, 'utf8').digest();
|
|
80
|
+
hash = Crypto.createHash('sha1');
|
|
81
|
+
return hash.update(stage1).digest();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Send Handshake response packet
|
|
86
|
+
* see https://mariadb.com/kb/en/library/1-connecting-connecting/#handshake-response-packet
|
|
87
|
+
*
|
|
88
|
+
* @param cmd current handshake command
|
|
89
|
+
* @param out output writer
|
|
90
|
+
* @param opts connection options
|
|
91
|
+
* @param pluginName plugin name
|
|
92
|
+
* @param info connection information
|
|
93
|
+
*/
|
|
94
|
+
static send(cmd, out, opts, pluginName, info) {
|
|
95
|
+
out.startPacket(cmd);
|
|
96
|
+
info.defaultPluginName = pluginName;
|
|
97
|
+
const pwd = Array.isArray(opts.password) ? opts.password[0] : opts.password;
|
|
98
|
+
let authToken;
|
|
99
|
+
let authPlugin;
|
|
100
|
+
switch (pluginName) {
|
|
101
|
+
case 'mysql_clear_password':
|
|
102
|
+
authToken = Buffer.from(pwd);
|
|
103
|
+
authPlugin = 'mysql_clear_password';
|
|
104
|
+
break;
|
|
105
|
+
|
|
106
|
+
default:
|
|
107
|
+
authToken = NativePasswordAuth.encryptSha1Password(pwd, info.seed);
|
|
108
|
+
authPlugin = 'mysql_native_password';
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
out.writeInt32(Number(info.clientCapabilities & BigInt(0xffffffff)));
|
|
112
|
+
out.writeInt32(1024 * 1024 * 1024); // max packet size
|
|
113
|
+
|
|
114
|
+
// if collation and id < 255, set it directly
|
|
115
|
+
// is not, additional command SET NAMES xx [COLLATE yy] will be issued
|
|
116
|
+
out.writeInt8(opts.collation && opts.collation.index <= 255 ? opts.collation.index : 224);
|
|
117
|
+
for (let i = 0; i < 19; i++) {
|
|
118
|
+
out.writeInt8(0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
out.writeInt32(Number(info.clientCapabilities >> 32n));
|
|
122
|
+
|
|
123
|
+
//null encoded user
|
|
124
|
+
out.writeString(opts.user || '');
|
|
125
|
+
out.writeInt8(0);
|
|
126
|
+
|
|
127
|
+
if (info.serverCapabilities & Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA) {
|
|
128
|
+
out.writeLengthCoded(authToken.length);
|
|
129
|
+
out.writeBuffer(authToken, 0, authToken.length);
|
|
130
|
+
} else if (info.serverCapabilities & Capabilities.SECURE_CONNECTION) {
|
|
131
|
+
out.writeInt8(authToken.length);
|
|
132
|
+
out.writeBuffer(authToken, 0, authToken.length);
|
|
133
|
+
} else {
|
|
134
|
+
out.writeBuffer(authToken, 0, authToken.length);
|
|
135
|
+
out.writeInt8(0);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (info.clientCapabilities & Capabilities.CONNECT_WITH_DB) {
|
|
139
|
+
out.writeString(opts.database);
|
|
140
|
+
out.writeInt8(0);
|
|
141
|
+
info.database = opts.database;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
|
|
145
|
+
out.writeString(authPlugin);
|
|
146
|
+
out.writeInt8(0);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (info.clientCapabilities & Capabilities.CONNECT_ATTRS) {
|
|
150
|
+
out.writeInt8(0xfc);
|
|
151
|
+
let initPos = out.pos; //save position, assuming connection attributes length will be less than 2 bytes length
|
|
152
|
+
out.writeInt16(0);
|
|
153
|
+
const encoding = info.collation ? info.collation.charset : 'utf8';
|
|
154
|
+
|
|
155
|
+
Handshake.writeAttribute(out, '_client_name', encoding);
|
|
156
|
+
Handshake.writeAttribute(out, 'MariaDB connector/Node', encoding);
|
|
157
|
+
|
|
158
|
+
Handshake.writeAttribute(out, '_client_version', encoding);
|
|
159
|
+
Handshake.writeAttribute(out, driverVersion, encoding);
|
|
160
|
+
|
|
161
|
+
const address = cmd.getSocket().address().address;
|
|
162
|
+
if (address) {
|
|
163
|
+
Handshake.writeAttribute(out, '_server_host', encoding);
|
|
164
|
+
Handshake.writeAttribute(out, address, encoding);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
Handshake.writeAttribute(out, '_os', encoding);
|
|
168
|
+
Handshake.writeAttribute(out, process.platform, encoding);
|
|
169
|
+
|
|
170
|
+
Handshake.writeAttribute(out, '_client_host', encoding);
|
|
171
|
+
Handshake.writeAttribute(out, os.hostname(), encoding);
|
|
172
|
+
|
|
173
|
+
Handshake.writeAttribute(out, '_node_version', encoding);
|
|
174
|
+
Handshake.writeAttribute(out, process.versions.node, encoding);
|
|
175
|
+
|
|
176
|
+
if (opts.connectAttributes !== true) {
|
|
177
|
+
let attrNames = Object.keys(opts.connectAttributes);
|
|
178
|
+
for (let k = 0; k < attrNames.length; ++k) {
|
|
179
|
+
Handshake.writeAttribute(out, attrNames[k], encoding);
|
|
180
|
+
Handshake.writeAttribute(out, opts.connectAttributes[attrNames[k]], encoding);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
//write end size
|
|
185
|
+
out.writeInt16AtPos(initPos);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
out.flushPacket();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
static writeAttribute(out, val, encoding) {
|
|
192
|
+
let param = Buffer.isEncoding(encoding) ? Buffer.from(val, encoding) : Iconv.encode(val, encoding);
|
|
193
|
+
out.writeLengthCoded(param.length);
|
|
194
|
+
out.writeBuffer(param, 0, param.length);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
module.exports = Handshake;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
|
3
|
+
|
|
1
4
|
'use strict';
|
|
2
5
|
|
|
3
|
-
const Capabilities = require('
|
|
4
|
-
const
|
|
6
|
+
const Capabilities = require('../../../const/capabilities');
|
|
7
|
+
const Collations = require('../../../const/collations');
|
|
8
|
+
const ConnectionInformation = require('../../../misc/connection-information');
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* Parser server initial handshake.
|
|
@@ -19,10 +23,9 @@ class InitialHandshake {
|
|
|
19
23
|
packet.skip(1); //reserved byte
|
|
20
24
|
|
|
21
25
|
let serverCapabilities = BigInt(packet.readUInt16());
|
|
22
|
-
|
|
23
|
-
packet.skip(1);
|
|
26
|
+
info.collation = Collations.fromIndex(packet.readUInt8());
|
|
24
27
|
info.status = packet.readUInt16();
|
|
25
|
-
serverCapabilities += BigInt(packet.readUInt16()) <<
|
|
28
|
+
serverCapabilities += BigInt(packet.readUInt16()) << 16n;
|
|
26
29
|
|
|
27
30
|
let saltLength = 0;
|
|
28
31
|
if (serverCapabilities & Capabilities.PLUGIN_AUTH) {
|
|
@@ -34,7 +37,7 @@ class InitialHandshake {
|
|
|
34
37
|
packet.skip(10);
|
|
35
38
|
} else {
|
|
36
39
|
packet.skip(6);
|
|
37
|
-
serverCapabilities += BigInt(packet.readUInt32()) <<
|
|
40
|
+
serverCapabilities += BigInt(packet.readUInt32()) << 32n;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
if (serverCapabilities & Capabilities.SECURE_CONNECTION) {
|
|
@@ -58,8 +61,7 @@ class InitialHandshake {
|
|
|
58
61
|
} else {
|
|
59
62
|
//Support for MDEV-7780 faking server version
|
|
60
63
|
info.serverVersion.mariaDb =
|
|
61
|
-
info.serverVersion.raw.includes('MariaDB') ||
|
|
62
|
-
(serverCapabilities & Capabilities.MYSQL) === BigInt(0);
|
|
64
|
+
info.serverVersion.raw.includes('MariaDB') || (serverCapabilities & Capabilities.MYSQL) === 0n;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
if (serverCapabilities & Capabilities.PLUGIN_AUTH) {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
|
3
|
+
|
|
1
4
|
'use strict';
|
|
2
5
|
|
|
3
6
|
const PluginAuth = require('./plugin-auth');
|
|
@@ -7,8 +10,8 @@ const Crypto = require('crypto');
|
|
|
7
10
|
* Standard authentication plugin
|
|
8
11
|
*/
|
|
9
12
|
class NativePasswordAuth extends PluginAuth {
|
|
10
|
-
constructor(packSeq, compressPackSeq, pluginData,
|
|
11
|
-
super(
|
|
13
|
+
constructor(packSeq, compressPackSeq, pluginData, cmdParam, reject, multiAuthResolver) {
|
|
14
|
+
super(cmdParam, multiAuthResolver, reject);
|
|
12
15
|
this.pluginData = pluginData;
|
|
13
16
|
this.sequenceNo = packSeq;
|
|
14
17
|
this.compressSequenceNo = compressPackSeq;
|
|
@@ -17,28 +20,27 @@ class NativePasswordAuth extends PluginAuth {
|
|
|
17
20
|
start(out, opts, info) {
|
|
18
21
|
//seed is ended with a null byte value.
|
|
19
22
|
const data = this.pluginData.slice(0, 20);
|
|
20
|
-
let authToken = NativePasswordAuth.
|
|
23
|
+
let authToken = NativePasswordAuth.encryptSha1Password(opts.password, data);
|
|
21
24
|
|
|
22
25
|
out.startPacket(this);
|
|
23
26
|
if (authToken.length > 0) {
|
|
24
27
|
out.writeBuffer(authToken, 0, authToken.length);
|
|
25
|
-
out.
|
|
28
|
+
out.flushPacket();
|
|
26
29
|
} else {
|
|
27
30
|
out.writeEmptyPacket(true);
|
|
28
31
|
}
|
|
29
32
|
this.emit('send_end');
|
|
30
|
-
this.onPacketReceive = this.successSend;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
static
|
|
35
|
+
static encryptSha1Password(password, seed) {
|
|
34
36
|
if (!password) return Buffer.alloc(0);
|
|
35
37
|
|
|
36
|
-
let hash = Crypto.createHash(
|
|
38
|
+
let hash = Crypto.createHash('sha1');
|
|
37
39
|
let stage1 = hash.update(password, 'utf8').digest();
|
|
38
|
-
hash = Crypto.createHash(
|
|
40
|
+
hash = Crypto.createHash('sha1');
|
|
39
41
|
|
|
40
42
|
let stage2 = hash.update(stage1).digest();
|
|
41
|
-
hash = Crypto.createHash(
|
|
43
|
+
hash = Crypto.createHash('sha1');
|
|
42
44
|
|
|
43
45
|
hash.update(seed);
|
|
44
46
|
hash.update(stage2);
|
|
@@ -50,6 +52,17 @@ class NativePasswordAuth extends PluginAuth {
|
|
|
50
52
|
}
|
|
51
53
|
return returnBytes;
|
|
52
54
|
}
|
|
55
|
+
|
|
56
|
+
permitHash() {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
hash(conf) {
|
|
61
|
+
let hash = Crypto.createHash('sha1');
|
|
62
|
+
let stage1 = hash.update(conf.password, 'utf8').digest();
|
|
63
|
+
hash = Crypto.createHash('sha1');
|
|
64
|
+
return hash.update(stage1).digest();
|
|
65
|
+
}
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
module.exports = NativePasswordAuth;
|