Skip to content

Commit

Permalink
Implement caching_sha2_password for mysql 8+
Browse files Browse the repository at this point in the history
This PR implements caching_sha2_password for mysql 8. Note that we have
chosen on purpose to only implement the path where TSL is used. We will
not be implementing the non-TSL path.

Co-authored-by: John Hawthorn <john@hawthorn.email>
Aaron Patterson (tenderlove) <tenderlove@ruby-lang.org>
  • Loading branch information
eileencodes committed Mar 13, 2024
1 parent 6b41af0 commit 5417986
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
3 changes: 3 additions & 0 deletions inc/trilogy/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ typedef enum {
// Typical response packet types
typedef enum {
TRILOGY_PACKET_OK = 0x0,
TRILOGY_PACKET_AUTH_MORE_DATA = 0x01,
TRILOGY_PACKET_EOF = 0xfe,
TRILOGY_PACKET_ERR = 0xff,
TRILOGY_PACKET_UNKNOWN
Expand Down Expand Up @@ -1035,4 +1036,6 @@ int trilogy_parse_stmt_ok_packet(const uint8_t *buff, size_t len, trilogy_stmt_o
int trilogy_parse_stmt_row_packet(const uint8_t *buff, size_t len, trilogy_column_packet_t *columns,
uint64_t column_count, trilogy_binary_value_t *out_values);

int trilogy_build_auth_clear_password(trilogy_builder_t *builder, const char *pass, size_t pass_len);

#endif
54 changes: 54 additions & 0 deletions src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,9 @@ void trilogy_auth_clear_password(trilogy_conn_t *conn)
}
}

#define FAST_AUTH_OK 3
#define FAST_AUTH_FAIL 4

int trilogy_auth_recv(trilogy_conn_t *conn, trilogy_handshake_t *handshake)
{
int rc = read_packet(conn);
Expand All @@ -416,6 +419,57 @@ int trilogy_auth_recv(trilogy_conn_t *conn, trilogy_handshake_t *handshake)
trilogy_auth_clear_password(conn);
return read_ok_packet(conn);

case TRILOGY_PACKET_AUTH_MORE_DATA: {
uint8_t byte = conn->packet_buffer.buff[1];
switch (byte) {
case FAST_AUTH_OK:
break;
case FAST_AUTH_FAIL:
{
trilogy_builder_t builder;
int err = begin_command_phase(&builder, conn, conn->packet_parser.sequence_number);

if (err < 0) {
return err;
}

err = trilogy_build_auth_clear_password(&builder, conn->socket->opts.password, conn->socket->opts.password_len);

if (err < 0) {
return err;
}

int rc = begin_write(conn);

while (rc == TRILOGY_AGAIN) {
rc = trilogy_sock_wait_write(conn->socket);
if (rc != TRILOGY_OK) {
return rc;
}

rc = trilogy_flush_writes(conn);
}

break;
}
default:
return TRILOGY_UNEXPECTED_PACKET;
}
while (1) {
rc = read_packet(conn);

if (rc == TRILOGY_OK) {
return rc;
}
else if (rc == TRILOGY_AGAIN) {
rc = trilogy_sock_wait_read(conn->socket);
}

if (rc != TRILOGY_OK) {
return rc;
}
}
}
case TRILOGY_PACKET_ERR:
trilogy_auth_clear_password(conn);
return read_err_packet(conn);
Expand Down
11 changes: 10 additions & 1 deletion src/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,16 @@ int trilogy_build_auth_packet(trilogy_builder_t *builder, const char *user, cons

trilogy_builder_finalize(builder);

return TRILOGY_OK;
fail:
return rc;
}

int trilogy_build_auth_clear_password(trilogy_builder_t *builder, const char *pass, size_t pass_len) {
int rc = TRILOGY_OK;

CHECKED(trilogy_builder_write_buffer(builder, pass, pass_len));
CHECKED(trilogy_builder_write_uint8(builder, 0));
trilogy_builder_finalize(builder);

fail:
return rc;
Expand Down

0 comments on commit 5417986

Please sign in to comment.