Skip to content

Commit

Permalink
Support GSS encrypt request decoding as part of psql 14.15 client (#1361
Browse files Browse the repository at this point in the history
)
  • Loading branch information
akrambek authored Jan 3, 2025
1 parent 063d7cb commit 811415b
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#
# Copyright 2021-2024 Aklivity Inc
#
# Licensed under the Aklivity Community License (the "License"); you may not use
# this file except in compliance with the License. You may obtain a copy of the
# License at
#
# https://www.aklivity.io/aklivity-community-license/
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#

connect "zilla://streams/app0"
option zilla:window 8192
option zilla:transmission "duplex"

write zilla:begin.ext ${pgsql:beginEx()
.typeId(zilla:id("pgsql"))
.parameter("user", "root")
.parameter("database", "dev")
.parameter("application_name", "psql")
.parameter("client_encoding", "UTF8")
.build()}

connected

read closed
write close
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#
# Copyright 2021-2024 Aklivity Inc
#
# Licensed under the Aklivity Community License (the "License"); you may not use
# this file except in compliance with the License. You may obtain a copy of the
# License at
#
# https://www.aklivity.io/aklivity-community-license/
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#

property serverAddress "zilla://streams/app0"

accept ${serverAddress}
option zilla:window 8192
option zilla:transmission "duplex"

accepted

read zilla:begin.ext ${pgsql:beginEx()
.typeId(zilla:id("pgsql"))
.parameter("user", "root")
.parameter("database", "dev")
.parameter("application_name", "psql")
.parameter("client_encoding", "UTF8")
.build()}

connected

write close
read closed
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#
# Copyright 2021-2024 Aklivity Inc
#
# Licensed under the Aklivity Community License (the "License"); you may not use
# this file except in compliance with the License. You may obtain a copy of the
# License at
#
# https://www.aklivity.io/aklivity-community-license/
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#

property networkConnectWindow 8192

connect "zilla://streams/net0"
option zilla:window ${networkConnectWindow}
option zilla:transmission "duplex"
option zilla:byteorder "network"

connected

write 8 # length
[0x04 0xd2 0x16 0x30] # gss encrypt request code

read [0x4e]

write 8 # length
[0x04 0xd2 0x16 0x2f] # ssl request code

read [0x4e]

write 75 # length
3s # major version
0s # minor version
"user" [0x00] # name
"root" [0x00] # value
"database" [0x00] # name
"dev" [0x00] # value
"application_name" [0x00] # name
"psql" [0x00] # value
"client_encoding" [0x00] # name
"UTF8" [0x00] # value
[0x00] # end of parameters

read [0x52] # type R
8 # length
0 # authentication type

read [0x4b] # type K
12 # length
0 # pid
0 # key

read [0x53] # type S
25 # length
"client_encoding" [0x00] # name
"UTF8" [0x00] # value

read [0x53] # type S
35 # length
"standard_conforming_strings" [0x00] # name
[0x6f 0x6e 0x00] # value

read [0x53] # type S
25 # length
"server_version" [0x00] # name
"9.1.0" [0x00] # value

read [0x53] # type S
27 # length
"application_name" [0x00] # name
"zilla" [0x00] # value

read [0x5a] # type Z
5 # length
[0x49] # status

read [0x58] # type X
4 # length

read closed
write close
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#
# Copyright 2021-2024 Aklivity Inc
#
# Licensed under the Aklivity Community License (the "License"); you may not use
# this file except in compliance with the License. You may obtain a copy of the
# License at
#
# https://www.aklivity.io/aklivity-community-license/
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#

property networkAcceptWindow 8192

accept "zilla://streams/net0"
option zilla:window ${networkAcceptWindow}
option zilla:transmission "duplex"
option zilla:byteorder "network"

accepted

connected

read 8 # length
[0x04 0xd2 0x16 0x30] # gss encrypt request code

write [0x4e]

read 8 # length
[0x04 0xd2 0x16 0x2f] # ssl request code

write [0x4e]

read 75 # length
3s # major version
0s # minor version
"user" [0x00] # name
"root" [0x00] # value
"database" [0x00] # name
"dev" [0x00] # value
"application_name" [0x00] # name
"psql" [0x00] # value
"client_encoding" [0x00] # name
"UTF8" [0x00] # value
[0x00] # end of parameters

write [0x52] # type R
8 # length
0 # authentication type

write [0x4b] # type K
12 # length
0 # pid
0 # key

write [0x53] # type S
25 # length
"client_encoding" [0x00] # name
"UTF8" [0x00] # value

write [0x53] # type S
35 # length
"standard_conforming_strings" [0x00] # name
[0x6f 0x6e 0x00] # value

write [0x53] # type S
25 # length
"server_version" [0x00] # name
"9.1.0" [0x00] # value

write [0x53] # type S
27 # length
"application_name" [0x00] # name
"zilla" [0x00] # value

write [0x5a] # type Z
5 # length
[0x49] # status

write [0x58] # type X
4 # length

write close
read closed
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ public void shouldHandleFragmentedCreateTable() throws Exception
k3po.finish();
}

@Test
@Specification({
"${app}/gss.encrypt.request/client",
"${app}/gss.encrypt.request/server" })
public void shouldHandleGssEncryptRequest() throws Exception
{
k3po.finish();
}

@Test
@Specification({
"${app}/ssl.request/client",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ public void shouldHandleSslRequest() throws Exception
k3po.finish();
}

@Test
@Specification({
"${net}/gss.encrypt.request/client",
"${net}/gss.encrypt.request/server" })
public void shouldHandleGssEncryptRequest() throws Exception
{
k3po.finish();
}

@Test
@Specification({
"${net}/client.sent.write.abort/client",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlAuthenticationMessageFW;
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlBackendKeyMessageFW;
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlCancelRequestMessageFW;
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlGssEncryptRequestFW;
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlGssEncryptResponseFW;
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlMessageFW;
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlSslRequestFW;
import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlSslResponseFW;
Expand Down Expand Up @@ -79,6 +81,7 @@ public final class PgsqlServerFactory implements PgsqlStreamFactory
private static final Byte MESSAGE_TYPE_PARAMETER_STATUS = 'S';

private static final int SSL_REQUEST_CODE = 80877103;
private static final int GSS_ENCRYPT_REQUEST_CODE = 80877104;
private static final int CANCEL_REQUEST_CODE = 80877102;
private static final int END_OF_FIELD = 0x00;

Expand Down Expand Up @@ -122,11 +125,13 @@ public final class PgsqlServerFactory implements PgsqlStreamFactory

private final PgsqlMessageFW messageRO = new PgsqlMessageFW();
private final PgsqlSslRequestFW sslRequestRO = new PgsqlSslRequestFW();
private final PgsqlGssEncryptRequestFW gssRequestRO = new PgsqlGssEncryptRequestFW();
private final PgsqlStartupMessageFW startupMessageRO = new PgsqlStartupMessageFW();
private final PgsqlCancelRequestMessageFW cancelReqMessageRO = new PgsqlCancelRequestMessageFW();

private final PgsqlMessageFW.Builder messageRW = new PgsqlMessageFW.Builder();
private final PgsqlSslResponseFW.Builder sslResponseRW = new PgsqlSslResponseFW.Builder();
private final PgsqlGssEncryptResponseFW.Builder gssResponseRW = new PgsqlGssEncryptResponseFW.Builder();
private final PgsqlAuthenticationMessageFW.Builder authMessageRW = new PgsqlAuthenticationMessageFW.Builder();
private final PgsqlBackendKeyMessageFW.Builder backendKeyMessageRW = new PgsqlBackendKeyMessageFW.Builder();

Expand All @@ -146,6 +151,7 @@ public final class PgsqlServerFactory implements PgsqlStreamFactory
private final int pgsqlTypeId;

private final PgsqlServerDecoder decodePgsqlInitial = this::decodePgsqlInitial;
private final PgsqlServerDecoder decodePgsqlGssRequest = this::decodePgsqlGssEncryptRequest;
private final PgsqlServerDecoder decodePgsqlSslRequest = this::decodePgsqlSslRequest;
private final PgsqlServerDecoder decodePgsqlStartupMessage = this::decodePgsqlStartupMessage;
private final PgsqlServerDecoder decodePgsqlCancelRequest = this::decodePgsqlCancelRequest;
Expand Down Expand Up @@ -605,6 +611,14 @@ public void onDecodeSslRequest(
doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, sslResponse.limit());
}

public void onDecodeGssEncryptRequest(
long traceId,
long authorization)
{
PgsqlGssEncryptResponseFW gssResponse = gssResponseRW.wrap(messageBuffer, 0, messageBuffer.capacity()).build();
doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, gssResponse.limit());
}

public void onDecodeCancelRequest(
long traceId,
long authorization,
Expand Down Expand Up @@ -1493,10 +1507,16 @@ private int decodePgsqlInitial(
int limit)
{
final PgsqlSslRequestFW pgsqlSslRequest = sslRequestRO.tryWrap(buffer, offset, limit);
final PgsqlGssEncryptRequestFW pgsqlGssRequest = gssRequestRO.tryWrap(buffer, offset, limit);
final PgsqlCancelRequestMessageFW cancelRequest = cancelReqMessageRO.tryWrap(buffer, offset, limit);
final PgsqlStartupMessageFW startupMessage = startupMessageRO.tryWrap(buffer, offset, limit);

if (pgsqlSslRequest != null &&
if (pgsqlGssRequest != null &&
pgsqlGssRequest.code() == GSS_ENCRYPT_REQUEST_CODE)
{
server.decoder = decodePgsqlGssRequest;
}
else if (pgsqlSslRequest != null &&
pgsqlSslRequest.code() == SSL_REQUEST_CODE)
{
server.decoder = decodePgsqlSslRequest;
Expand All @@ -1510,10 +1530,6 @@ else if (startupMessage != null)
{
server.decoder = decodePgsqlStartupMessage;
}
else
{
server.decoder = decodePgsqlIgnoreAll;
}

return offset;
}
Expand All @@ -1535,6 +1551,23 @@ private int decodePgsqlSslRequest(
return sslRequest.limit();
}

private int decodePgsqlGssEncryptRequest(
PgsqlServer server,
long traceId,
long authorization,
long budgetId,
DirectBuffer buffer,
int offset,
int limit)
{
PgsqlGssEncryptRequestFW gssRequest = gssRequestRO.wrap(buffer, offset, limit);

server.onDecodeGssEncryptRequest(traceId, authorization);
server.decoder = decodePgsqlInitial;

return gssRequest.limit();
}

private int decodePgsqlStartupMessage(
PgsqlServer server,
long traceId,
Expand Down
11 changes: 11 additions & 0 deletions incubator/binding-pgsql/src/main/zilla/protocol.idl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ scope protocol
uint8 answer = 78;
}

struct PgsqlGssEncryptRequest
{
int32 length = 4;
int32 code = 80877104;
}

struct PgsqlGssEncryptResponse
{
uint8 answer = 78;
}

struct PgsqlStartupMessage
{
int32 length;
Expand Down
Loading

0 comments on commit 811415b

Please sign in to comment.