Skip to content

Commit 9aaacd5

Browse files
weigondahlerlend
authored andcommitted
Bug#33357723 Oracle Analytic Cloud connection failure
Issue ===== The mysql protocol implementation used by OAC sends a client greeting which announces: capabilities: - WITH_SCHEMA - PLUGIN_AUTH - no CONNECT_ATTRibutes which according to the spec should lead to: - caps - max-packet-size - collation - 23-bytes of 0 - username - auth-data - schema - auth-name But the payload that's sent stops right after the "schema" part: ...mysql\0 It is accepted like that by the server, but the router is strict according to the spec. Change ====== - accept client::Greeting messages which announce PLUGIN_AUTH, but don't send a plugin name - fixed error-msg if decoding client greeting failed. RB: 27018
1 parent d7a6bf9 commit 9aaacd5

File tree

3 files changed

+62
-21
lines changed

3 files changed

+62
-21
lines changed

router/src/mysql_protocol/include/mysqlrouter/classic_protocol_codec_message.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,12 +2432,23 @@ class Codec<message::client::Greeting>
24322432
accu.step(wire::NulTermString(v_.schema()));
24332433
}
24342434

2435-
if (shared_caps[classic_protocol::capabilities::pos::plugin_auth]) {
2436-
accu.step(wire::NulTermString(v_.auth_method_name()));
2437-
}
2438-
2439-
if (shared_caps
2435+
if (!shared_caps
24402436
[classic_protocol::capabilities::pos::connect_attributes]) {
2437+
// special handling for off-spec client/server implimentations.
2438+
//
2439+
// 1. older clients may set ::plugin_auth, but
2440+
// ::connection_attributes which means nothing follows the
2441+
// "auth-method-name" field
2442+
// 2. auth-method-name is empty, it MAY be skipped.
2443+
if (shared_caps[classic_protocol::capabilities::pos::plugin_auth] &&
2444+
!v_.auth_method_name().empty()) {
2445+
accu.step(wire::NulTermString(v_.auth_method_name()));
2446+
}
2447+
} else {
2448+
if (shared_caps[classic_protocol::capabilities::pos::plugin_auth]) {
2449+
accu.step(wire::NulTermString(v_.auth_method_name()));
2450+
}
2451+
24412452
accu.step(wire::VarString(v_.attributes()));
24422453
}
24432454
}
@@ -2556,7 +2567,13 @@ class Codec<message::client::Greeting>
25562567
stdx::expected<wire::NulTermString, std::error_code> auth_method_res;
25572568
if (shared_capabilities
25582569
[classic_protocol::capabilities::pos::plugin_auth]) {
2559-
auth_method_res = accu.template step<wire::NulTermString>();
2570+
if (net::buffer_size(buffers) == accu.result().value()) {
2571+
// even with plugin_auth set, the server is fine, if no
2572+
// auth_method_name is sent.
2573+
auth_method_res = wire::NulTermString{};
2574+
} else {
2575+
auth_method_res = accu.template step<wire::NulTermString>();
2576+
}
25602577
}
25612578
if (!auth_method_res)
25622579
return stdx::make_unexpected(auth_method_res.error());

router/src/mysql_protocol/tests/test_classic_protocol_message.cc

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,9 +1181,7 @@ INSTANTIATE_TEST_SUITE_P(Spec, CodecMessageClientStmtFetchTest,
11811181

11821182
// client::Greeting
11831183

1184-
namespace classic_protocol {
1185-
namespace message {
1186-
namespace client {
1184+
namespace classic_protocol::message::client {
11871185
std::ostream &operator<<(std::ostream &os, const Greeting &v) {
11881186
os << "Greeting: "
11891187
<< "\n";
@@ -1195,9 +1193,7 @@ std::ostream &operator<<(std::ostream &os, const Greeting &v) {
11951193

11961194
return os;
11971195
}
1198-
} // namespace client
1199-
} // namespace message
1200-
} // namespace classic_protocol
1196+
} // namespace classic_protocol::message::client
12011197

12021198
using CodecMessageClientGreetingTest =
12031199
CodecTest<classic_protocol::message::client::Greeting>;
@@ -1369,6 +1365,38 @@ const CodecParam<classic_protocol::message::client::Greeting>
13691365
0x00, 0x00, 0x00, 0x00, //
13701366
0x00, 0x00, 0x00 //
13711367
}},
1368+
{
1369+
"choma",
1370+
{
1371+
0b1011'1010'0010'0000'1111, // caps:
1372+
// long-pass
1373+
// found-rows
1374+
// long-flag
1375+
// connect-with-schema
1376+
// protocol_41
1377+
// transactions
1378+
// secure_connections
1379+
// plugin_auth (set, but then
1380+
// not used)
1381+
(1 << 24) - 1, // max-packet-size
1382+
0xff, // collation
1383+
"myroot", // user
1384+
"\x14\xa5\xed\xe0\xdf\x96\x9d\x5e"
1385+
"\xca\xa3\x45\xc3\x93\x55\xfe\x22"
1386+
"\x99\x62\xc9\xed", // authdata
1387+
"mysql", // schema
1388+
"", // authmethod
1389+
{} // attributes
1390+
}, // client::Greeting
1391+
0xffffffff, // server-caps
1392+
{0x0f, 0xa2, 0x0b, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00,
1393+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1394+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1395+
0x00, 0x00, 0x6d, 0x79, 0x72, 0x6f, 0x6f, 0x74, 0x00, 0x14,
1396+
0x14, 0xa5, 0xed, 0xe0, 0xdf, 0x96, 0x9d, 0x5e, 0xca, 0xa3,
1397+
0x45, 0xc3, 0x93, 0x55, 0xfe, 0x22, 0x99, 0x62, 0xc9, 0xed,
1398+
0x6d, 0x79, 0x73, 0x71, 0x6c, 0x00} // bytes
1399+
},
13721400
};
13731401

13741402
INSTANTIATE_TEST_SUITE_P(
@@ -1380,9 +1408,7 @@ INSTANTIATE_TEST_SUITE_P(
13801408

13811409
// client::ChangeUser
13821410

1383-
namespace classic_protocol {
1384-
namespace message {
1385-
namespace client {
1411+
namespace classic_protocol::message::client {
13861412
std::ostream &operator<<(std::ostream &os, const ChangeUser &v) {
13871413
os << "ChangeUser: "
13881414
<< "\n";
@@ -1392,9 +1418,7 @@ std::ostream &operator<<(std::ostream &os, const ChangeUser &v) {
13921418

13931419
return os;
13941420
}
1395-
} // namespace client
1396-
} // namespace message
1397-
} // namespace classic_protocol
1421+
} // namespace classic_protocol::message::client
13981422

13991423
using CodecMessageClientChangeUserTest =
14001424
CodecTest<classic_protocol::message::client::ChangeUser>;

router/src/routing/src/classic_protocol_splicer.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ BasicSplicer::State ClassicProtocolSplicer::client_greeting() {
370370
return state();
371371
}
372372

373-
log_debug("decoding server greeting failed: %s",
373+
log_debug("decoding client greeting failed: %s",
374374
header_decode_res.error().message().c_str());
375375

376376
return State::FINISH;
@@ -406,7 +406,7 @@ BasicSplicer::State ClassicProtocolSplicer::client_greeting() {
406406
return state();
407407
}
408408

409-
log_debug("decoding server greeting failed: %s",
409+
log_debug("decoding client greeting failed: %s",
410410
payload_decode_res.error().message().c_str());
411411

412412
return State::FINISH;
@@ -647,7 +647,7 @@ BasicSplicer::State ClassicProtocolSplicer::tls_client_greeting() {
647647
return state();
648648
}
649649

650-
log_debug("decoding server greeting failed: %s",
650+
log_debug("decoding client greeting after TLS failed: %s",
651651
decode_res.error().message().c_str());
652652

653653
return State::FINISH;

0 commit comments

Comments
 (0)