feat(tests): Add an integration test for SASL2
This commit is contained in:
parent
29f0419154
commit
d977a74446
25
flake.lock
25
flake.lock
@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1667395993,
|
"lastModified": 1678901627,
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@ -31,10 +31,27 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-unstable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1680273054,
|
||||||
|
"narHash": "sha256-Bs6/5LpvYp379qVqGt9mXxxx9GSE789k3oFc+OAL07M=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "3364b5b117f65fe1ce65a3cdd5612a078a3b31e3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
31
flake.nix
31
flake.nix
@ -2,10 +2,11 @@
|
|||||||
description = "moxxmpp";
|
description = "moxxmpp";
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:AtaraxiaSjel/nixpkgs/update/flutter";
|
nixpkgs.url = "github:AtaraxiaSjel/nixpkgs/update/flutter";
|
||||||
|
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let
|
outputs = { self, nixpkgs, nixpkgs-unstable, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
config = {
|
config = {
|
||||||
@ -13,6 +14,9 @@
|
|||||||
allowUnfree = true;
|
allowUnfree = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
unstable = import nixpkgs-unstable {
|
||||||
|
inherit system;
|
||||||
|
};
|
||||||
android = pkgs.androidenv.composeAndroidPackages {
|
android = pkgs.androidenv.composeAndroidPackages {
|
||||||
# TODO: Find a way to pin these
|
# TODO: Find a way to pin these
|
||||||
#toolsVersion = "26.1.1";
|
#toolsVersion = "26.1.1";
|
||||||
@ -46,7 +50,26 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
devShell = pkgs.mkShell {
|
devShell = let
|
||||||
|
prosody-newer-community-modules = unstable.prosody.overrideAttrs (old: {
|
||||||
|
communityModules = pkgs.fetchhg {
|
||||||
|
url = "https://hg.prosody.im/prosody-modules";
|
||||||
|
rev = "e3a3a6c86a9f";
|
||||||
|
sha256 = "sha256-C2x6PCv0sYuj4/SroDOJLsNPzfeNCodYKbMqmNodFrk=";
|
||||||
|
};
|
||||||
|
|
||||||
|
src = pkgs.fetchhg {
|
||||||
|
url = "https://hg.prosody.im/trunk";
|
||||||
|
rev = "8a2f75e38eb2";
|
||||||
|
sha256 = "sha256-zMNp9+wQ/hvUVyxFl76DqCVzQUPP8GkNdstiTDkG8Hw=";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
prosody-sasl2 = prosody-newer-community-modules.override {
|
||||||
|
withCommunityModules = [
|
||||||
|
"sasl2" "sasl2_fast" "sasl2_sm" "sasl2_bind2"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in pkgs.mkShell {
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
flutter pinnedJDK android.platform-tools dart # Dart
|
flutter pinnedJDK android.platform-tools dart # Dart
|
||||||
gitlint # Code hygiene
|
gitlint # Code hygiene
|
||||||
@ -71,6 +94,10 @@
|
|||||||
|
|
||||||
# For the scripts in ./scripts/
|
# For the scripts in ./scripts/
|
||||||
pythonEnv
|
pythonEnv
|
||||||
|
|
||||||
|
# For integration testing against a local prosody server
|
||||||
|
prosody-sasl2
|
||||||
|
mkcert
|
||||||
];
|
];
|
||||||
|
|
||||||
CPATH = "${pkgs.xorg.libX11.dev}/include:${pkgs.xorg.xorgproto}/include";
|
CPATH = "${pkgs.xorg.libX11.dev}/include:${pkgs.xorg.xorgproto}/include";
|
||||||
|
6
integration_tests/.gitignore
vendored
Normal file
6
integration_tests/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Files and directories created by pub.
|
||||||
|
.dart_tool/
|
||||||
|
.packages
|
||||||
|
|
||||||
|
# Conventional directory for build output.
|
||||||
|
build/
|
5
integration_tests/README.md
Normal file
5
integration_tests/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Integration Tests
|
||||||
|
|
||||||
|
The included `./prosody.cfg.lua` config file must be used for integration testing.
|
||||||
|
Additionally, ensure that a user `testuser@localhost` with the password `abc123`
|
||||||
|
exists.
|
1
integration_tests/analysis_options.yaml
Normal file
1
integration_tests/analysis_options.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
include: ../analysis_options.yaml
|
24
integration_tests/certs/localhost.crt
Normal file
24
integration_tests/certs/localhost.crt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEAzCCAmugAwIBAgIQd61NPnP8++X7h8a+85C6DjANBgkqhkiG9w0BAQsFADBZ
|
||||||
|
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExFzAVBgNVBAsMDmFsZXhh
|
||||||
|
bmRlckBtaWt1MR4wHAYDVQQDDBVta2NlcnQgYWxleGFuZGVyQG1pa3UwHhcNMjMw
|
||||||
|
NDAyMTM1ODIxWhcNMjUwNzAyMTM1ODIxWjBCMScwJQYDVQQKEx5ta2NlcnQgZGV2
|
||||||
|
ZWxvcG1lbnQgY2VydGlmaWNhdGUxFzAVBgNVBAsMDmFsZXhhbmRlckBtaWt1MIIB
|
||||||
|
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1DElEXPY+VDQP7cSikK0ne0K
|
||||||
|
gDgorGYPG9R7lOeuPLHyFYYry78+hB037OT0BOyA2uTu1yrog0dI/4YGicPDIqXh
|
||||||
|
IgHfjV+4kMi5SgO7ECWOBmZFqTC3bBwvbNtoW40aFjYSFaOkm/nnfp+nalEJJZ/N
|
||||||
|
kSkD4gdT3pH1ClsovlI4BlsxeIoJtyGzxMidJVXDAqMNraLatzJBwnT3OEs93xTf
|
||||||
|
7Kd1KUpQp9OZFrGi15zv/n6tCmrcC3xMOVHuYkhW0UCTFmev7ZqbghQsQ9N9s0E6
|
||||||
|
kk9rUf9xtMNH4Af6+2YRkT1DAGQ6FkXl1nQdB5H5XRgOBl+3k9s8wUrxQvQddQID
|
||||||
|
AQABo14wXDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYD
|
||||||
|
VR0jBBgwFoAU54aUZ+dytAOBTsYIdGtSnjiig/gwFAYDVR0RBA0wC4IJbG9jYWxo
|
||||||
|
b3N0MA0GCSqGSIb3DQEBCwUAA4IBgQBU8p7Ua0Cs+lXlWmtCh2j+YF9R+dvc+3Iw
|
||||||
|
dYEzCmYd375uxPctyHXW0yYjyuH9WuYn0F7OicEFEeC2+exHND+/z0J2Zv5yu34r
|
||||||
|
SfgHVfvE/Vxisn9InYrUCVtfRwLDF3HgLyIlm8FVzIyiIANhpe6vJdqjEWTsiL2X
|
||||||
|
I6hoDf1xlRgEqUx+Wxl2IFWrg+1SPPGTQzDPImiRlz8d+9ZJ9v48vaV5+aITMvDP
|
||||||
|
Gfm/bnNXXd5Gf7nGwL8zFHiwLoYQ5AUYl0IfXYwFAXJ72+LjiRT33IOidVJF0gsQ
|
||||||
|
6k9cTsc4lIrt4FOzdchalbF1Eu2prieWoZxz0apG8OuUeAhaB+t8kT6swAkwvkLW
|
||||||
|
OnlSATm9Cls9Pc4XDHTbZlbMmwF2Jmukgz/l1vlTutt4ZgZwQkSEa9Qfoi9Zym0R
|
||||||
|
iKls1CgD49zguR/cFDKK3agvfv6Afw6HdgaS/WqcI/Ros7b+RCkbAlAG5gqr6BLQ
|
||||||
|
8RGyVjZSC4Mz/ddcnMEpRAnjuFJjhGA=
|
||||||
|
-----END CERTIFICATE-----
|
28
integration_tests/certs/localhost.key
Normal file
28
integration_tests/certs/localhost.key
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDUMSURc9j5UNA/
|
||||||
|
txKKQrSd7QqAOCisZg8b1HuU5648sfIVhivLvz6EHTfs5PQE7IDa5O7XKuiDR0j/
|
||||||
|
hgaJw8MipeEiAd+NX7iQyLlKA7sQJY4GZkWpMLdsHC9s22hbjRoWNhIVo6Sb+ed+
|
||||||
|
n6dqUQkln82RKQPiB1PekfUKWyi+UjgGWzF4igm3IbPEyJ0lVcMCow2totq3MkHC
|
||||||
|
dPc4Sz3fFN/sp3UpSlCn05kWsaLXnO/+fq0KatwLfEw5Ue5iSFbRQJMWZ6/tmpuC
|
||||||
|
FCxD032zQTqST2tR/3G0w0fgB/r7ZhGRPUMAZDoWReXWdB0HkfldGA4GX7eT2zzB
|
||||||
|
SvFC9B11AgMBAAECggEAYaj4yY6LFzxVjG2i79WBsYnOonK2bZpPa9ygwEjdTXwM
|
||||||
|
0lE9SPoNONsFyVca5EVBjP1+27MY7orZkxlJWxCpeAHmmzNHg5bBqIlpliIfb3AJ
|
||||||
|
bPKXLyaH1Q8n2K8m2bQYhI6ARktZ0Jv1KrcqY2lGj3V8NEovSlFbDX4ZzJlmKCly
|
||||||
|
d4Ia6eQ7f9AjgsOwpQGeCTF7WLaVDnch6D4JfCGrW08lFeaqogiBQczsOE3hcNSd
|
||||||
|
tEul21Z0CkC7Iiw28KdkApPINquo1VYdAcOvUCOXkwJfPC1gsJwK4O2jxfi9v5NF
|
||||||
|
uU1niK0/00b396pQKvXpkfViynexwzK0MZCoo3zuQQKBgQDzaZexcniQNDyWqN3C
|
||||||
|
oMe4V3rnxs+aO/lu8Ed3mng+Jf4vuarZlxNot7WRBMGT/T+b7/UIrqRJy50CYAPY
|
||||||
|
3RRR84tLg3UMwUWhDYsPucNc2icODBG4c+QWJ300W19r+J+iT8PwS9AbH2n094Rn
|
||||||
|
LCRYFrX5aMsgIH5uwuncKzweMQKBgQDfKj2i1ptC53aOcr1tMCFYcnMGtaAZ8u6+
|
||||||
|
cKSgnzKlTw/g0EYlGcETUnCyZe0oVYWp3y859FBXU0JMDmxu84aYEZNF6BwRVlpF
|
||||||
|
feQgtUFZHyf9MepQGhjIJ5El8n7jhh1bsBY18QbDFe6/GtqPx/mQEF7vE+wPFl9h
|
||||||
|
putwdv3OhQKBgGKPyi2/BVSW4kW7IPiTM+vP+GNrnFp+mHS0dKvYb4HyzmcyzhyH
|
||||||
|
UQOhB7Mt8thivmP9GQIn/TwoZ24zxLsGYhkA/dFY7Id6pyAcpMd8V7/8Ub4dYvuG
|
||||||
|
acASw1709MF6jeEiXVuqxxyEbtoTc5h3Rkwo/gx8w2tB3RAqepl9JD2xAoGAfVL3
|
||||||
|
ci8a2iOqTKza/Cp/T3BWcHonAuuOb5xKl3lPs84GmLXd7o/cAcHWUBk1aeU9Pvx7
|
||||||
|
RQyS4bd8D8I52sUf3N5h2mxS9tmLsGLWbhfcLvR0PJh/gaRmLmEp/imEYLm8WvU0
|
||||||
|
Q+6rYXs7rE6kVwJygBjxd0m003Q49FoM9gec2RECgYEA5SLAe2UmJSLIb0DKk27o
|
||||||
|
nSfARDSdi9N40vIjDFHmDRdKTOYicED/f7KqXnxVpvFxDdCvJ7xeC4V7vkaqiiwd
|
||||||
|
/oMLQq0GjmBxG/PNd1AFIWDydyH+JcY6U4XWIzIw92OKVYC/KMvd2f9orTfmDyAU
|
||||||
|
RsGMfgV90kCzouAZKy3yPmo=
|
||||||
|
-----END PRIVATE KEY-----
|
56
integration_tests/prosody.cfg.lua
Normal file
56
integration_tests/prosody.cfg.lua
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
admins = { }
|
||||||
|
plugin_paths = {}
|
||||||
|
|
||||||
|
modules_enabled = {
|
||||||
|
-- Generally required
|
||||||
|
"disco"; -- Service discovery
|
||||||
|
"roster"; -- Allow users to have a roster. Recommended ;)
|
||||||
|
"saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
|
||||||
|
"tls"; -- Add support for secure TLS on c2s/s2s connections
|
||||||
|
|
||||||
|
-- Not essential, but recommended
|
||||||
|
"blocklist"; -- Allow users to block communications with other users
|
||||||
|
"bookmarks"; -- Synchronise the list of open rooms between clients
|
||||||
|
"carbons"; -- Keep multiple online clients in sync
|
||||||
|
"dialback"; -- Support for verifying remote servers using DNS
|
||||||
|
"limits"; -- Enable bandwidth limiting for XMPP connections
|
||||||
|
"pep"; -- Allow users to store public and private data in their account
|
||||||
|
"private"; -- Legacy account storage mechanism (XEP-0049)
|
||||||
|
"smacks"; -- Stream management and resumption (XEP-0198)
|
||||||
|
"vcard4"; -- User profiles (stored in PEP)
|
||||||
|
"vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard
|
||||||
|
|
||||||
|
-- Nice to have
|
||||||
|
"csi_simple"; -- Simple but effective traffic optimizations for mobile devices
|
||||||
|
"invites"; -- Create and manage invites
|
||||||
|
"invites_adhoc"; -- Allow admins/users to create invitations via their client
|
||||||
|
"invites_register"; -- Allows invited users to create accounts
|
||||||
|
"ping"; -- Replies to XMPP pings with pongs
|
||||||
|
"register"; -- Allow users to register on this server using a client and change passwords
|
||||||
|
"time"; -- Let others know the time here on this server
|
||||||
|
"uptime"; -- Report how long server has been running
|
||||||
|
"version"; -- Replies to server version requests
|
||||||
|
|
||||||
|
-- SASL2
|
||||||
|
"sasl2";
|
||||||
|
"sasl2_sm";
|
||||||
|
"sasl2_fast";
|
||||||
|
"sasl2_bind2";
|
||||||
|
}
|
||||||
|
|
||||||
|
s2s_secure_auth = false
|
||||||
|
|
||||||
|
-- Authentication
|
||||||
|
authentication = "internal_plain"
|
||||||
|
|
||||||
|
-- Storage
|
||||||
|
storage = "internal"
|
||||||
|
data_path = "/tmp/prosody-data/"
|
||||||
|
log = {
|
||||||
|
debug = "*console";
|
||||||
|
}
|
||||||
|
|
||||||
|
pidfile = "/tmp/prosody.pid"
|
||||||
|
|
||||||
|
VirtualHost "localhost"
|
||||||
|
|
16
integration_tests/pubspec.yaml
Normal file
16
integration_tests/pubspec.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
name: integration_tests
|
||||||
|
description: A sample command-line application.
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.18.0 <3.0.0'
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
logging: ^1.0.2
|
||||||
|
moxxmpp: 0.2.0
|
||||||
|
moxxmpp_socket_tcp: 0.2.1
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
lints: ^2.0.0
|
||||||
|
test: ^1.16.0
|
||||||
|
very_good_analysis: ^3.0.1
|
67
integration_tests/test/sasl2_test.dart
Normal file
67
integration_tests/test/sasl2_test.dart
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
|
import 'package:moxxmpp_socket_tcp/moxxmpp_socket_tcp.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
class TestingTCPSocketWrapper extends TCPSocketWrapper {
|
||||||
|
@override
|
||||||
|
bool onBadCertificate(dynamic certificate, String domain) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
Logger.root.level = Level.ALL;
|
||||||
|
Logger.root.onRecord.listen((record) {
|
||||||
|
// ignore: avoid_print
|
||||||
|
print(
|
||||||
|
'[${record.level.name}] (${record.loggerName}) ${record.time}: ${record.message}',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test authenticating against Prosody with SASL2, Bind2, and FAST', () async {
|
||||||
|
final conn = XmppConnection(
|
||||||
|
TestingReconnectionPolicy(),
|
||||||
|
AlwaysConnectedConnectivityManager(),
|
||||||
|
TestingTCPSocketWrapper(),
|
||||||
|
)..setConnectionSettings(
|
||||||
|
ConnectionSettings(
|
||||||
|
jid: JID.fromString('testuser@localhost'),
|
||||||
|
password: 'abc123',
|
||||||
|
useDirectTLS: false,
|
||||||
|
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: 5222,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final csi = CSIManager();
|
||||||
|
await csi.setInactive(sendNonza: false);
|
||||||
|
await conn.registerManagers([
|
||||||
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
|
DiscoManager([]),
|
||||||
|
]);
|
||||||
|
await conn.registerFeatureNegotiators([
|
||||||
|
SaslPlainNegotiator(),
|
||||||
|
ResourceBindingNegotiator(),
|
||||||
|
FASTSaslNegotiator(),
|
||||||
|
Bind2Negotiator(),
|
||||||
|
StartTlsNegotiator(),
|
||||||
|
Sasl2Negotiator(
|
||||||
|
userAgent: const UserAgent(
|
||||||
|
id: 'd4565fa7-4d72-4749-b3d3-740edbf87770',
|
||||||
|
software: 'moxxmpp',
|
||||||
|
device: "PapaTutuWawa's awesome device",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final result = await conn.connect(
|
||||||
|
waitUntilLogin: true,
|
||||||
|
shouldReconnect: false,
|
||||||
|
enableReconnectOnSuccess: false,
|
||||||
|
);
|
||||||
|
expect(result.isType<bool>(), true);
|
||||||
|
expect(conn.getNegotiatorById<Sasl2Negotiator>(sasl2Negotiator)!.state, NegotiatorState.done);
|
||||||
|
expect(conn.getNegotiatorById<FASTSaslNegotiator>(saslFASTNegotiator)!.fastToken != null, true,);
|
||||||
|
});
|
||||||
|
}
|
43
packages/moxxmpp/integration_tests/sasl2_test.dart
Normal file
43
packages/moxxmpp/integration_tests/sasl2_test.dart
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
|
import 'package:moxxmpp_socket_tcp/moxxmpp_socket_tcp.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
final conn = XmppConnection(
|
||||||
|
TestingReconnectionPolicy(),
|
||||||
|
AlwaysConnectedConnectivityManager(),
|
||||||
|
TCPSocketWrapper(),
|
||||||
|
)..setConnectionSettings(
|
||||||
|
ConnectionSettings(
|
||||||
|
jid: JID.fromString('testuser@localhost'),
|
||||||
|
password: 'abc123',
|
||||||
|
useDirectTLS: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final csi = CSIManager();
|
||||||
|
await csi.setInactive(sendNonza: false);
|
||||||
|
await conn.registerManagers([
|
||||||
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
|
DiscoManager([]),
|
||||||
|
]);
|
||||||
|
await conn.registerFeatureNegotiators([
|
||||||
|
SaslPlainNegotiator(),
|
||||||
|
ResourceBindingNegotiator(),
|
||||||
|
FASTSaslNegotiator(),
|
||||||
|
Bind2Negotiator(),
|
||||||
|
Sasl2Negotiator(
|
||||||
|
userAgent: const UserAgent(
|
||||||
|
id: 'd4565fa7-4d72-4749-b3d3-740edbf87770',
|
||||||
|
software: 'moxxmpp',
|
||||||
|
device: "PapaTutuWawa's awesome device",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final result = await conn.connect(
|
||||||
|
waitUntilLogin: true,
|
||||||
|
shouldReconnect: false,
|
||||||
|
enableReconnectOnSuccess: false,
|
||||||
|
);
|
||||||
|
expect(result.isType<NegotiatorError>(), false);
|
||||||
|
}
|
@ -9,6 +9,7 @@ import 'package:moxxmpp/src/connectivity.dart';
|
|||||||
import 'package:moxxmpp/src/errors.dart';
|
import 'package:moxxmpp/src/errors.dart';
|
||||||
import 'package:moxxmpp/src/events.dart';
|
import 'package:moxxmpp/src/events.dart';
|
||||||
import 'package:moxxmpp/src/iq.dart';
|
import 'package:moxxmpp/src/iq.dart';
|
||||||
|
import 'package:moxxmpp/src/jid.dart';
|
||||||
import 'package:moxxmpp/src/managers/attributes.dart';
|
import 'package:moxxmpp/src/managers/attributes.dart';
|
||||||
import 'package:moxxmpp/src/managers/base.dart';
|
import 'package:moxxmpp/src/managers/base.dart';
|
||||||
import 'package:moxxmpp/src/managers/data.dart';
|
import 'package:moxxmpp/src/managers/data.dart';
|
||||||
@ -63,14 +64,15 @@ enum StanzaFromType {
|
|||||||
|
|
||||||
/// Nonza describing the XMPP stream header.
|
/// Nonza describing the XMPP stream header.
|
||||||
class StreamHeaderNonza extends XMLNode {
|
class StreamHeaderNonza extends XMLNode {
|
||||||
StreamHeaderNonza(String serverDomain)
|
StreamHeaderNonza(JID jid)
|
||||||
: super(
|
: super(
|
||||||
tag: 'stream:stream',
|
tag: 'stream:stream',
|
||||||
attributes: <String, String>{
|
attributes: <String, String>{
|
||||||
'xmlns': stanzaXmlns,
|
'xmlns': stanzaXmlns,
|
||||||
'version': '1.0',
|
'version': '1.0',
|
||||||
'xmlns:stream': streamXmlns,
|
'xmlns:stream': streamXmlns,
|
||||||
'to': serverDomain,
|
'to': jid.domain,
|
||||||
|
'from': jid.toBare().toString(),
|
||||||
'xml:lang': 'en',
|
'xml:lang': 'en',
|
||||||
},
|
},
|
||||||
closeTag: false,
|
closeTag: false,
|
||||||
@ -1037,11 +1039,11 @@ class XmppConnection {
|
|||||||
_socket.write(
|
_socket.write(
|
||||||
XMLNode(
|
XMLNode(
|
||||||
tag: 'xml',
|
tag: 'xml',
|
||||||
attributes: <String, String>{'version': '1.0'},
|
attributes: {'version': '1.0'},
|
||||||
closeTag: false,
|
closeTag: false,
|
||||||
isDeclaration: true,
|
isDeclaration: true,
|
||||||
children: [
|
children: [
|
||||||
StreamHeaderNonza(_connectionSettings.jid.domain),
|
StreamHeaderNonza(_connectionSettings.jid),
|
||||||
],
|
],
|
||||||
).toXml(),
|
).toXml(),
|
||||||
);
|
);
|
||||||
@ -1156,13 +1158,16 @@ class XmppConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final smManager = getStreamManagementManager();
|
final smManager = getStreamManagementManager();
|
||||||
String? host;
|
String? host = _connectionSettings.host;
|
||||||
int? port;
|
int? port = _connectionSettings.port;
|
||||||
if (smManager?.state.streamResumptionLocation != null) {
|
if (smManager?.state.streamResumptionLocation != null) {
|
||||||
// TODO(Unknown): Maybe wrap this in a try catch?
|
// TODO(Unknown): Maybe wrap this in a try catch?
|
||||||
final parsed = Uri.parse(smManager!.state.streamResumptionLocation!);
|
final parsed = Uri.parse(smManager!.state.streamResumptionLocation!);
|
||||||
host = parsed.host;
|
host = parsed.host;
|
||||||
port = parsed.port;
|
port = parsed.port;
|
||||||
|
} else {
|
||||||
|
host = _connectionSettings.host;
|
||||||
|
port = _connectionSettings.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
final result = await _socket.connect(
|
final result = await _socket.connect(
|
||||||
|
@ -8,6 +8,7 @@ import 'package:moxxmpp/src/negotiators/sasl/nonza.dart';
|
|||||||
import 'package:moxxmpp/src/negotiators/sasl2.dart';
|
import 'package:moxxmpp/src/negotiators/sasl2.dart';
|
||||||
import 'package:moxxmpp/src/stringxml.dart';
|
import 'package:moxxmpp/src/stringxml.dart';
|
||||||
import 'package:moxxmpp/src/types/result.dart';
|
import 'package:moxxmpp/src/types/result.dart';
|
||||||
|
import 'package:saslprep/saslprep.dart';
|
||||||
|
|
||||||
class SaslPlainAuthNonza extends SaslAuthNonza {
|
class SaslPlainAuthNonza extends SaslAuthNonza {
|
||||||
SaslPlainAuthNonza(String data)
|
SaslPlainAuthNonza(String data)
|
||||||
@ -86,8 +87,9 @@ class SaslPlainNegotiator extends Sasl2AuthenticationNegotiator {
|
|||||||
@override
|
@override
|
||||||
Future<String> getRawStep(String input) async {
|
Future<String> getRawStep(String input) async {
|
||||||
final settings = attributes.getConnectionSettings();
|
final settings = attributes.getConnectionSettings();
|
||||||
|
final prep = Saslprep.saslprep(settings.password);
|
||||||
return base64.encode(
|
return base64.encode(
|
||||||
utf8.encode('\u0000${settings.jid.local}\u0000${settings.password}'),
|
utf8.encode('\u0000${settings.jid.local}\u0000${prep}'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'package:moxxmpp/src/jid.dart';
|
import 'package:moxxmpp/src/jid.dart';
|
||||||
import 'package:moxxmpp/src/namespaces.dart';
|
import 'package:moxxmpp/src/namespaces.dart';
|
||||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
||||||
@ -245,7 +246,6 @@ class Sasl2Negotiator extends XmppFeatureNegotiatorBase {
|
|||||||
attributes.sendNonza(authenticate);
|
attributes.sendNonza(authenticate);
|
||||||
return const Result(NegotiatorState.ready);
|
return const Result(NegotiatorState.ready);
|
||||||
case Sasl2State.authenticateSent:
|
case Sasl2State.authenticateSent:
|
||||||
// TODO(PapaTutuWawa): Handle failure
|
|
||||||
if (nonza.tag == 'success') {
|
if (nonza.tag == 'success') {
|
||||||
// Tell the dependent negotiators about the result
|
// Tell the dependent negotiators about the result
|
||||||
final negotiators = _featureNegotiators
|
final negotiators = _featureNegotiators
|
||||||
|
@ -5,8 +5,13 @@ class ConnectionSettings {
|
|||||||
required this.jid,
|
required this.jid,
|
||||||
required this.password,
|
required this.password,
|
||||||
required this.useDirectTLS,
|
required this.useDirectTLS,
|
||||||
|
this.host,
|
||||||
|
this.port,
|
||||||
});
|
});
|
||||||
final JID jid;
|
final JID jid;
|
||||||
final String password;
|
final String password;
|
||||||
final bool useDirectTLS;
|
final bool useDirectTLS;
|
||||||
|
|
||||||
|
final String? host;
|
||||||
|
final int? port;
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,8 @@ class TCPSocketWrapper extends BaseSocketWrapper {
|
|||||||
if (await _hostPortConnect(host, port)) {
|
if (await _hostPortConnect(host, port)) {
|
||||||
_setupStreams();
|
_setupStreams();
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user