From 66c8c5d30242d1d33cfd1f4e498a068655a80aa3 Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Sat, 27 Nov 2021 12:11:51 +0100 Subject: [PATCH 1/8] Add clear type and auth scheme --- lib/src/auth/auth.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/auth/auth.dart b/lib/src/auth/auth.dart index 99e61161..5a099f3b 100644 --- a/lib/src/auth/auth.dart +++ b/lib/src/auth/auth.dart @@ -3,10 +3,11 @@ import 'package:sasl_scram/sasl_scram.dart'; import '../../postgres.dart'; import '../server_messages.dart'; +import 'clearText_authenticator.dart'; import 'md5_authenticator.dart'; import 'sasl_authenticator.dart'; -enum AuthenticationScheme { MD5, SCRAM_SHA_256 } +enum AuthenticationScheme { MD5, SCRAM_SHA_256, CLEAR } abstract class PostgresAuthenticator { static String? name; @@ -27,6 +28,8 @@ PostgresAuthenticator createAuthenticator(PostgreSQLConnection connection, username: connection.username, password: connection.password); return PostgresSaslAuthenticator( connection, ScramAuthenticator('SCRAM-SHA-256', sha256, credentials)); + case AuthenticationScheme.CLEAR: + return ClearAuthenticator(connection); default: throw PostgreSQLException("Authenticator wasn't specified"); } From 529ed4c772dee65308343f1f97bdd9caa25454af Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Sat, 27 Nov 2021 12:11:57 +0100 Subject: [PATCH 2/8] Create clearText_authenticator.dart --- lib/src/auth/clearText_authenticator.dart | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 lib/src/auth/clearText_authenticator.dart diff --git a/lib/src/auth/clearText_authenticator.dart b/lib/src/auth/clearText_authenticator.dart new file mode 100644 index 00000000..8edd8ef4 --- /dev/null +++ b/lib/src/auth/clearText_authenticator.dart @@ -0,0 +1,33 @@ +import 'package:buffer/buffer.dart'; + +import '../../postgres.dart'; +import '../client_messages.dart'; +import '../server_messages.dart'; +import '../utf8_backed_string.dart'; +import 'auth.dart'; + +class ClearAuthenticator extends PostgresAuthenticator{ + ClearAuthenticator(PostgreSQLConnection connection) : super(connection); + + @override + void onMessage(AuthenticationMessage message) { + final authMessage = ClearMessage(connection.password!); + connection.socket!.add(authMessage.asBytes()); + } + +} +class ClearMessage extends ClientMessage { + UTF8BackedString? _authString; + + ClearMessage(String password) { + _authString = UTF8BackedString(password); + } + + @override + void applyToBuffer(ByteDataWriter buffer) { + buffer.writeUint8(ClientMessage.PasswordIdentifier); + final length = 5 + _authString!.utf8Length; + buffer.writeUint32(length); + _authString!.applyToBuffer(buffer); + } +} \ No newline at end of file From e53898913ee3a314ac6f560c8c57455bea84cae4 Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Sat, 27 Nov 2021 12:12:21 +0100 Subject: [PATCH 3/8] Add case in Auth message evaluation --- lib/src/connection_fsm.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/src/connection_fsm.dart b/lib/src/connection_fsm.dart index 4564351f..e9c35613 100644 --- a/lib/src/connection_fsm.dart +++ b/lib/src/connection_fsm.dart @@ -119,6 +119,10 @@ class _PostgreSQLConnectionStateAuthenticating case AuthenticationMessage.KindSASLFinal: _authenticator.onMessage(message); return this; + case AuthenticationMessage.KindClearTextPassword: + _authenticator = + createAuthenticator(connection!, AuthenticationScheme.CLEAR); + continue authMsg; } completer.completeError(PostgreSQLException( From c53e368dafb050414506338e1cf0b0355cc05217 Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Mon, 29 Nov 2021 11:57:55 +0100 Subject: [PATCH 4/8] Optional parameter for selecting feature --- lib/src/connection.dart | 5 +++++ lib/src/connection_fsm.dart | 13 +++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/src/connection.dart b/lib/src/connection.dart index c7cd7094..23f03e8f 100644 --- a/lib/src/connection.dart +++ b/lib/src/connection.dart @@ -39,6 +39,7 @@ class PostgreSQLConnection extends Object /// [queryTimeoutInSeconds] refers to the default timeout for [PostgreSQLExecutionContext]'s execute and query methods. /// [timeZone] is the timezone the connection is in. Defaults to 'UTC'. /// [useSSL] when true, uses a secure socket when connecting to a PostgreSQL database. + /// [allowClearTextPassword] when true, allows sending the password during authentication in clear text. Use only when required by the database server and under encrypted connections, this feature may lead to security issues PostgreSQLConnection( this.host, this.port, @@ -50,6 +51,7 @@ class PostgreSQLConnection extends Object this.timeZone = 'UTC', this.useSSL = false, this.isUnixSocket = false, + this.allowClearTextPassword = false, }) { _connectionState = _PostgreSQLConnectionStateClosed(); _connectionState.connection = this; @@ -91,6 +93,9 @@ class PostgreSQLConnection extends Object /// If true, connection is made via unix socket. final bool isUnixSocket; + /// If true, allows password in clear text for aunthentication + final bool allowClearTextPassword; + /// Stream of notification from the database. /// /// Listen to this [Stream] to receive events from PostgreSQL NOTIFY commands. diff --git a/lib/src/connection_fsm.dart b/lib/src/connection_fsm.dart index e9c35613..7fde4fad 100644 --- a/lib/src/connection_fsm.dart +++ b/lib/src/connection_fsm.dart @@ -110,6 +110,15 @@ class _PostgreSQLConnectionStateAuthenticating _authenticator = createAuthenticator(connection!, AuthenticationScheme.MD5); continue authMsg; + case AuthenticationMessage.KindClearTextPassword: + if (connection!.allowClearTextPassword) { + _authenticator = + createAuthenticator(connection!, AuthenticationScheme.CLEAR); + continue authMsg; + } + else { + break; + } case AuthenticationMessage.KindSASL: _authenticator = createAuthenticator( connection!, AuthenticationScheme.SCRAM_SHA_256); @@ -119,10 +128,6 @@ class _PostgreSQLConnectionStateAuthenticating case AuthenticationMessage.KindSASLFinal: _authenticator.onMessage(message); return this; - case AuthenticationMessage.KindClearTextPassword: - _authenticator = - createAuthenticator(connection!, AuthenticationScheme.CLEAR); - continue authMsg; } completer.completeError(PostgreSQLException( From dc0e3d4a761aa5ac36e17684d805f195dfb61789 Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Mon, 29 Nov 2021 11:58:04 +0100 Subject: [PATCH 5/8] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb86cee..3fc20142 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.4.3 +- Add authenticator for passwords required as ClearText. Fixes connections issues with Azure Database for PostgreSQL. +- Added a new boolean parameter in connection as 'allowClearTextPassword' to activate / deactivate the feature. + ## 2.4.2 - Include original stacktrace when query fails. From c7574dda354e5ea14e825ff6dd22ea1e1a148d61 Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Tue, 30 Nov 2021 09:21:16 +0100 Subject: [PATCH 6/8] Format, typo and style fixing --- CHANGELOG.md | 3 +-- lib/src/auth/auth.dart | 2 +- ...ext_authenticator.dart => clear_text_authenticator.dart} | 6 +++--- lib/src/connection.dart | 4 ++-- lib/src/connection_fsm.dart | 3 +-- 5 files changed, 8 insertions(+), 10 deletions(-) rename lib/src/auth/{clearText_authenticator.dart => clear_text_authenticator.dart} (93%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc20142..6a984d32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,7 @@ # Changelog ## 2.4.3 -- Add authenticator for passwords required as ClearText. Fixes connections issues with Azure Database for PostgreSQL. -- Added a new boolean parameter in connection as 'allowClearTextPassword' to activate / deactivate the feature. +- Support for clear text passwords using a boolean parameter in connection as 'allowClearTextPassword' to activate / deactivate the feature. [#20](https://github.com/isoos/postgresql-dart/pull/20). ## 2.4.2 diff --git a/lib/src/auth/auth.dart b/lib/src/auth/auth.dart index 5a099f3b..1c487a1f 100644 --- a/lib/src/auth/auth.dart +++ b/lib/src/auth/auth.dart @@ -3,7 +3,7 @@ import 'package:sasl_scram/sasl_scram.dart'; import '../../postgres.dart'; import '../server_messages.dart'; -import 'clearText_authenticator.dart'; +import 'clear_text_authenticator.dart'; import 'md5_authenticator.dart'; import 'sasl_authenticator.dart'; diff --git a/lib/src/auth/clearText_authenticator.dart b/lib/src/auth/clear_text_authenticator.dart similarity index 93% rename from lib/src/auth/clearText_authenticator.dart rename to lib/src/auth/clear_text_authenticator.dart index 8edd8ef4..b954a0ee 100644 --- a/lib/src/auth/clearText_authenticator.dart +++ b/lib/src/auth/clear_text_authenticator.dart @@ -6,7 +6,7 @@ import '../server_messages.dart'; import '../utf8_backed_string.dart'; import 'auth.dart'; -class ClearAuthenticator extends PostgresAuthenticator{ +class ClearAuthenticator extends PostgresAuthenticator { ClearAuthenticator(PostgreSQLConnection connection) : super(connection); @override @@ -14,8 +14,8 @@ class ClearAuthenticator extends PostgresAuthenticator{ final authMessage = ClearMessage(connection.password!); connection.socket!.add(authMessage.asBytes()); } - } + class ClearMessage extends ClientMessage { UTF8BackedString? _authString; @@ -30,4 +30,4 @@ class ClearMessage extends ClientMessage { buffer.writeUint32(length); _authString!.applyToBuffer(buffer); } -} \ No newline at end of file +} diff --git a/lib/src/connection.dart b/lib/src/connection.dart index 23f03e8f..e4b1082c 100644 --- a/lib/src/connection.dart +++ b/lib/src/connection.dart @@ -39,7 +39,7 @@ class PostgreSQLConnection extends Object /// [queryTimeoutInSeconds] refers to the default timeout for [PostgreSQLExecutionContext]'s execute and query methods. /// [timeZone] is the timezone the connection is in. Defaults to 'UTC'. /// [useSSL] when true, uses a secure socket when connecting to a PostgreSQL database. - /// [allowClearTextPassword] when true, allows sending the password during authentication in clear text. Use only when required by the database server and under encrypted connections, this feature may lead to security issues + /// [allowClearTextPassword] when true, allows sending the password during authentication in clear text. Use only when required by the database server and under encrypted connections, this feature may lead to security issues. PostgreSQLConnection( this.host, this.port, @@ -93,7 +93,7 @@ class PostgreSQLConnection extends Object /// If true, connection is made via unix socket. final bool isUnixSocket; - /// If true, allows password in clear text for aunthentication + /// If true, allows password in clear text for authentication. final bool allowClearTextPassword; /// Stream of notification from the database. diff --git a/lib/src/connection_fsm.dart b/lib/src/connection_fsm.dart index 7fde4fad..98fe78f4 100644 --- a/lib/src/connection_fsm.dart +++ b/lib/src/connection_fsm.dart @@ -115,8 +115,7 @@ class _PostgreSQLConnectionStateAuthenticating _authenticator = createAuthenticator(connection!, AuthenticationScheme.CLEAR); continue authMsg; - } - else { + } else { break; } case AuthenticationMessage.KindSASL: From 4f6daf6cd9615e98427cd5a02801556ff90bda81 Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Tue, 30 Nov 2021 09:21:29 +0100 Subject: [PATCH 7/8] Increase version in pubspec --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 06d0b8d8..cf27afc2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: postgres description: PostgreSQL database driver. Supports statement reuse and binary protocol. -version: 2.4.2 +version: 2.4.3 homepage: https://github.com/isoos/postgresql-dart environment: From 54e5cd6b1e822081e69f7abc91ec169ec671bf4b Mon Sep 17 00:00:00 2001 From: pedropastor <> Date: Tue, 30 Nov 2021 09:28:16 +0100 Subject: [PATCH 8/8] Specific message when flag disabled --- lib/src/connection_fsm.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/connection_fsm.dart b/lib/src/connection_fsm.dart index 98fe78f4..0dcdb788 100644 --- a/lib/src/connection_fsm.dart +++ b/lib/src/connection_fsm.dart @@ -116,6 +116,8 @@ class _PostgreSQLConnectionStateAuthenticating createAuthenticator(connection!, AuthenticationScheme.CLEAR); continue authMsg; } else { + completer.completeError(PostgreSQLException( + 'type ${message.type} connections disabled. Set AllowClearTextPassword flag on PostgreSQLConnection to enable this feature.')); break; } case AuthenticationMessage.KindSASL: