2021-12-30 18:49:01 +00:00
|
|
|
import "dart:async";
|
|
|
|
|
|
|
|
import "package:moxxyv2/xmpp/connection.dart";
|
|
|
|
import "package:moxxyv2/xmpp/settings.dart";
|
|
|
|
import "package:moxxyv2/xmpp/stringxml.dart";
|
2021-12-30 19:06:20 +00:00
|
|
|
import "package:moxxyv2/xmpp/jid.dart";
|
2022-01-25 14:50:25 +00:00
|
|
|
import "package:moxxyv2/xmpp/stanza.dart";
|
2022-01-21 08:34:38 +00:00
|
|
|
import "package:moxxyv2/xmpp/presence.dart";
|
2022-01-21 10:23:09 +00:00
|
|
|
import "package:moxxyv2/xmpp/roster.dart";
|
2022-01-25 14:56:20 +00:00
|
|
|
import "package:moxxyv2/xmpp/events.dart";
|
2022-07-15 17:27:28 +00:00
|
|
|
import "package:moxxyv2/xmpp/ping.dart";
|
2022-05-30 14:26:34 +00:00
|
|
|
import "package:moxxyv2/xmpp/reconnect.dart";
|
2022-01-21 10:23:09 +00:00
|
|
|
import "package:moxxyv2/xmpp/managers/attributes.dart";
|
2022-03-11 20:39:42 +00:00
|
|
|
import "package:moxxyv2/xmpp/managers/data.dart";
|
2022-07-16 11:09:35 +00:00
|
|
|
import "package:moxxyv2/xmpp/negotiators/resource_binding.dart";
|
2022-07-15 19:33:04 +00:00
|
|
|
import "package:moxxyv2/xmpp/negotiators/sasl/plain.dart";
|
|
|
|
import "package:moxxyv2/xmpp/negotiators/sasl/scram.dart";
|
2022-02-17 11:41:45 +00:00
|
|
|
import "package:moxxyv2/xmpp/xeps/xep_0030/xep_0030.dart";
|
2022-03-11 20:39:42 +00:00
|
|
|
import "package:moxxyv2/xmpp/xeps/xep_0030/cachemanager.dart";
|
2021-12-30 18:49:01 +00:00
|
|
|
|
2022-07-15 19:48:32 +00:00
|
|
|
import "helpers/logging.dart";
|
2022-01-16 12:33:52 +00:00
|
|
|
import "helpers/xmpp.dart";
|
|
|
|
|
2021-12-30 18:49:01 +00:00
|
|
|
import "package:test/test.dart";
|
|
|
|
|
2022-02-22 20:21:31 +00:00
|
|
|
/// Returns true if the roster manager triggeres an event for a given stanza
|
|
|
|
Future<bool> testRosterManager(String bareJid, String resource, String stanzaString) async {
|
|
|
|
bool eventTriggered = false;
|
|
|
|
final roster = RosterManager();
|
|
|
|
roster.register(XmppManagerAttributes(
|
2022-04-10 20:57:04 +00:00
|
|
|
sendStanza: (_, { StanzaFromType addFrom = StanzaFromType.full, bool addId = true, bool retransmitted = false, bool awaitable = true }) async => XMLNode(tag: "hallo"),
|
2022-02-22 20:21:31 +00:00
|
|
|
sendEvent: (event) {
|
|
|
|
eventTriggered = true;
|
|
|
|
},
|
|
|
|
sendNonza: (_) {},
|
|
|
|
sendRawXml: (_) {},
|
|
|
|
getConnectionSettings: () => ConnectionSettings(
|
|
|
|
jid: JID.fromString(bareJid),
|
|
|
|
password: "password",
|
|
|
|
useDirectTLS: true,
|
|
|
|
allowPlainAuth: false,
|
|
|
|
),
|
|
|
|
getManagerById: (_) => null,
|
2022-03-01 19:26:55 +00:00
|
|
|
isFeatureSupported: (_) => false,
|
2022-04-20 20:52:32 +00:00
|
|
|
getFullJID: () => JID.fromString("$bareJid/$resource"),
|
2022-05-07 21:48:51 +00:00
|
|
|
getSocket: () => StubTCPSocket(play: []),
|
2022-07-16 10:43:21 +00:00
|
|
|
getConnection: () => XmppConnection(TestingReconnectionPolicy()),
|
|
|
|
// TODO
|
|
|
|
getNegotiatorById: (id) => null,
|
2022-02-22 20:21:31 +00:00
|
|
|
));
|
|
|
|
|
|
|
|
final stanza = Stanza.fromXMLNode(XMLNode.fromString(stanzaString));
|
2022-03-11 20:39:42 +00:00
|
|
|
for (final handler in roster.getIncomingStanzaHandlers()) {
|
|
|
|
if (handler.matches(stanza)) await handler.callback(stanza, StanzaHandlerData(false, stanza));
|
|
|
|
}
|
2022-02-22 20:21:31 +00:00
|
|
|
|
|
|
|
return eventTriggered;
|
|
|
|
}
|
|
|
|
|
2021-12-30 18:49:01 +00:00
|
|
|
void main() {
|
2022-07-15 19:48:32 +00:00
|
|
|
initLogger();
|
|
|
|
|
2022-01-21 08:34:38 +00:00
|
|
|
test("Test a successful login attempt with no SM", () async {
|
2022-01-16 12:33:52 +00:00
|
|
|
final fakeSocket = StubTCPSocket(
|
|
|
|
play: [
|
|
|
|
Expectation(
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"to": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false
|
|
|
|
),
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"from": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false,
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "stream:features",
|
|
|
|
xmlns: "http://etherx.jabber.org/streams",
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "mechanisms",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "mechanism", text: "PLAIN")
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
),
|
2022-01-21 08:34:38 +00:00
|
|
|
Expectation(XMLNode.xmlns(
|
2022-01-16 12:33:52 +00:00
|
|
|
tag: "auth",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
attributes: {
|
|
|
|
"mechanism": "PLAIN"
|
|
|
|
},
|
|
|
|
text: "AHBvbHlub21kaXZpc2lvbgBhYWFh"
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "success",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"
|
|
|
|
)
|
|
|
|
),
|
|
|
|
Expectation(
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"to": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false
|
|
|
|
),
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"from": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false,
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "stream:features",
|
|
|
|
xmlns: "http://etherx.jabber.org/streams",
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "bind",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-bind",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "required")
|
|
|
|
]
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "session",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-session",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "optional")
|
|
|
|
]
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "csi",
|
|
|
|
xmlns: "urn:xmpp:csi:0",
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Expectation(
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "iq",
|
|
|
|
xmlns: "jabber:client",
|
|
|
|
attributes: { "type": "set", "id": "a" },
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "bind",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-bind"
|
|
|
|
)
|
|
|
|
]
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "iq",
|
|
|
|
xmlns: "jabber:client",
|
2022-01-19 14:59:48 +00:00
|
|
|
attributes: { "type": "result" },
|
2022-01-16 12:33:52 +00:00
|
|
|
children: [
|
2022-01-19 14:59:48 +00:00
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "bind",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-bind",
|
|
|
|
children: [
|
|
|
|
XMLNode(
|
|
|
|
tag: "jid",
|
|
|
|
text: "polynomdivision@test.server/MU29eEZn"
|
|
|
|
)
|
|
|
|
]
|
2022-01-16 12:33:52 +00:00
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
),
|
|
|
|
Expectation(
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "presence",
|
|
|
|
xmlns: "jabber:client",
|
|
|
|
attributes: { "from": "polynomdivision@test.server/MU29eEZn" },
|
|
|
|
children: [
|
|
|
|
XMLNode(
|
|
|
|
tag: "show",
|
2022-01-21 08:34:38 +00:00
|
|
|
text: "chat"
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "c",
|
|
|
|
xmlns: "http://jabber.org/protocol/caps",
|
|
|
|
attributes: {
|
|
|
|
// TODO: Somehow make the test ignore this attribute
|
2022-01-23 15:17:00 +00:00
|
|
|
"ver": "QRTBC5cg/oYd+UOTYazSQR4zb/I=",
|
2022-01-21 08:34:38 +00:00
|
|
|
"node": "http://moxxy.im",
|
|
|
|
"hash": "sha-1"
|
|
|
|
}
|
2022-01-16 12:33:52 +00:00
|
|
|
)
|
|
|
|
]
|
|
|
|
),
|
|
|
|
XMLNode(
|
|
|
|
tag: "presence",
|
|
|
|
)
|
|
|
|
),
|
|
|
|
]
|
|
|
|
);
|
2022-03-11 20:39:42 +00:00
|
|
|
// TODO: This test is broken since we query the server and enable carbons
|
2022-05-30 14:26:34 +00:00
|
|
|
final XmppConnection conn = XmppConnection(TestingReconnectionPolicy(), socket: fakeSocket);
|
2022-01-16 12:33:52 +00:00
|
|
|
conn.setConnectionSettings(ConnectionSettings(
|
2022-02-22 20:21:31 +00:00
|
|
|
jid: JID.fromString("polynomdivision@test.server"),
|
2022-01-16 12:33:52 +00:00
|
|
|
password: "aaaa",
|
|
|
|
useDirectTLS: true,
|
2022-01-20 12:18:34 +00:00
|
|
|
allowPlainAuth: true
|
2022-01-16 12:33:52 +00:00
|
|
|
));
|
2022-07-16 16:42:45 +00:00
|
|
|
conn.registerManagers([
|
|
|
|
PresenceManager(),
|
|
|
|
RosterManager(),
|
|
|
|
DiscoManager(),
|
|
|
|
DiscoCacheManager(),
|
|
|
|
PingManager(),
|
|
|
|
]);
|
2022-01-23 15:17:00 +00:00
|
|
|
|
2022-07-15 18:39:10 +00:00
|
|
|
conn.registerFeatureNegotiators(
|
|
|
|
[
|
2022-07-15 19:09:33 +00:00
|
|
|
SaslPlainNegotiator(),
|
2022-07-16 11:09:35 +00:00
|
|
|
SaslScramNegotiator(10, "", "", ScramHashType.sha512),
|
|
|
|
ResourceBindingNegotiator(),
|
2022-07-15 18:39:10 +00:00
|
|
|
]
|
|
|
|
);
|
|
|
|
|
2022-03-08 20:50:21 +00:00
|
|
|
await conn.connect();
|
2022-01-21 16:44:48 +00:00
|
|
|
await Future.delayed(const Duration(seconds: 3), () {
|
2022-01-21 08:34:38 +00:00
|
|
|
expect(fakeSocket.getState(), 5);
|
2022-01-16 12:33:52 +00:00
|
|
|
});
|
2021-12-30 18:49:01 +00:00
|
|
|
});
|
|
|
|
|
2022-01-21 10:23:09 +00:00
|
|
|
test("Test a failed SASL auth", () async {
|
|
|
|
final fakeSocket = StubTCPSocket(
|
|
|
|
play: [
|
|
|
|
Expectation(
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"to": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false
|
|
|
|
),
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"from": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false,
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "stream:features",
|
|
|
|
xmlns: "http://etherx.jabber.org/streams",
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "mechanisms",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "mechanism", text: "PLAIN")
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
),
|
|
|
|
Expectation(XMLNode.xmlns(
|
|
|
|
tag: "auth",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
attributes: {
|
|
|
|
"mechanism": "PLAIN"
|
|
|
|
},
|
|
|
|
text: "AHBvbHlub21kaXZpc2lvbgBhYWFh"
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "failure",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "not-authorized")
|
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
]
|
|
|
|
);
|
|
|
|
bool receivedEvent = false;
|
2022-05-30 14:26:34 +00:00
|
|
|
final XmppConnection conn = XmppConnection(TestingReconnectionPolicy(), socket: fakeSocket);
|
2022-01-21 10:23:09 +00:00
|
|
|
conn.setConnectionSettings(ConnectionSettings(
|
2022-07-16 16:42:45 +00:00
|
|
|
jid: JID.fromString("polynomdivision@test.server"),
|
|
|
|
password: "aaaa",
|
|
|
|
useDirectTLS: true,
|
|
|
|
allowPlainAuth: true
|
2022-01-21 10:23:09 +00:00
|
|
|
));
|
2022-07-16 16:42:45 +00:00
|
|
|
conn.registerManagers([
|
|
|
|
PresenceManager(),
|
|
|
|
RosterManager(),
|
|
|
|
DiscoManager(),
|
|
|
|
PingManager(),
|
|
|
|
]);
|
|
|
|
conn.registerFeatureNegotiators([
|
|
|
|
SaslPlainNegotiator()
|
|
|
|
]);
|
2021-12-30 18:49:01 +00:00
|
|
|
|
2022-01-21 10:23:09 +00:00
|
|
|
conn.asBroadcastStream().listen((event) {
|
2022-07-16 16:42:45 +00:00
|
|
|
if (event is AuthenticationFailedEvent && event.saslError == "not-authorized") {
|
|
|
|
receivedEvent = true;
|
|
|
|
}
|
2022-01-21 10:23:09 +00:00
|
|
|
});
|
2021-12-30 18:49:01 +00:00
|
|
|
|
2022-03-08 20:50:21 +00:00
|
|
|
await conn.connect();
|
2022-01-21 16:44:48 +00:00
|
|
|
await Future.delayed(const Duration(seconds: 3), () {
|
2022-01-21 10:23:09 +00:00
|
|
|
expect(receivedEvent, true);
|
|
|
|
});
|
|
|
|
});
|
2021-12-30 18:49:01 +00:00
|
|
|
|
2022-01-21 10:23:09 +00:00
|
|
|
test("Test another failed SASL auth", () async {
|
|
|
|
final fakeSocket = StubTCPSocket(
|
|
|
|
play: [
|
|
|
|
Expectation(
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"to": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false
|
|
|
|
),
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"from": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false,
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "stream:features",
|
|
|
|
xmlns: "http://etherx.jabber.org/streams",
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "mechanisms",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "mechanism", text: "PLAIN")
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
),
|
|
|
|
Expectation(XMLNode.xmlns(
|
|
|
|
tag: "auth",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
attributes: {
|
|
|
|
"mechanism": "PLAIN"
|
|
|
|
},
|
|
|
|
text: "AHBvbHlub21kaXZpc2lvbgBhYWFh"
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "failure",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "mechanism-too-weak")
|
|
|
|
]
|
|
|
|
)
|
2021-12-30 18:49:01 +00:00
|
|
|
)
|
2022-01-21 10:23:09 +00:00
|
|
|
]
|
2021-12-30 18:49:01 +00:00
|
|
|
);
|
2022-01-21 10:23:09 +00:00
|
|
|
bool receivedEvent = false;
|
2022-05-30 14:26:34 +00:00
|
|
|
final XmppConnection conn = XmppConnection(TestingReconnectionPolicy(), socket: fakeSocket);
|
2022-01-21 10:23:09 +00:00
|
|
|
conn.setConnectionSettings(ConnectionSettings(
|
2022-02-22 20:21:31 +00:00
|
|
|
jid: JID.fromString("polynomdivision@test.server"),
|
2022-01-21 10:23:09 +00:00
|
|
|
password: "aaaa",
|
|
|
|
useDirectTLS: true,
|
|
|
|
allowPlainAuth: true
|
|
|
|
));
|
2022-07-16 16:42:45 +00:00
|
|
|
conn.registerManagers([
|
|
|
|
PresenceManager(),
|
|
|
|
RosterManager(),
|
|
|
|
DiscoManager(),
|
|
|
|
PingManager(),
|
|
|
|
]);
|
|
|
|
conn.registerFeatureNegotiators([
|
|
|
|
SaslPlainNegotiator()
|
|
|
|
]);
|
2022-01-21 10:23:09 +00:00
|
|
|
|
|
|
|
conn.asBroadcastStream().listen((event) {
|
|
|
|
if (event is AuthenticationFailedEvent && event.saslError == "mechanism-too-weak") {
|
|
|
|
receivedEvent = true;
|
|
|
|
}
|
|
|
|
});
|
2021-12-30 18:49:01 +00:00
|
|
|
|
2022-03-08 20:50:21 +00:00
|
|
|
await conn.connect();
|
2022-01-21 16:44:48 +00:00
|
|
|
await Future.delayed(const Duration(seconds: 3), () {
|
2022-01-21 10:23:09 +00:00
|
|
|
expect(receivedEvent, true);
|
|
|
|
});
|
2021-12-30 18:49:01 +00:00
|
|
|
});
|
2021-12-30 19:06:20 +00:00
|
|
|
|
2022-01-21 10:23:09 +00:00
|
|
|
test("Test choosing SCRAM-SHA-1", () async {
|
|
|
|
final fakeSocket = StubTCPSocket(
|
|
|
|
play: [
|
|
|
|
Expectation(
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"to": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false
|
|
|
|
),
|
|
|
|
XMLNode(
|
|
|
|
tag: "stream:stream",
|
|
|
|
attributes: {
|
|
|
|
"xmlns": "jabber:client",
|
|
|
|
"version": "1.0",
|
|
|
|
"xmlns:stream": "http://etherx.jabber.org/streams",
|
|
|
|
"from": "test.server",
|
|
|
|
"xml:lang": "en"
|
|
|
|
},
|
|
|
|
closeTag: false,
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "stream:features",
|
|
|
|
xmlns: "http://etherx.jabber.org/streams",
|
|
|
|
children: [
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "mechanisms",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
children: [
|
|
|
|
XMLNode(tag: "mechanism", text: "PLAIN"),
|
|
|
|
XMLNode(tag: "mechanism", text: "SCRAM-SHA-1")
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
),
|
|
|
|
Expectation(XMLNode.xmlns(
|
|
|
|
tag: "auth",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
attributes: {
|
|
|
|
"mechanism": "SCRAM-SHA-1"
|
|
|
|
},
|
|
|
|
text: "..."
|
|
|
|
),
|
|
|
|
XMLNode.xmlns(
|
|
|
|
tag: "challenge",
|
|
|
|
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl",
|
|
|
|
attributes: {
|
|
|
|
"mechanism": "SCRAM-SHA-1"
|
|
|
|
},
|
|
|
|
text: "cj02ZDQ0MmI1ZDllNTFhNzQwZjM2OWUzZGNlY2YzMTc4ZWMxMmIzOTg1YmJkNGE4ZTZmODE0YjQyMmFiNzY2NTczLHM9UVNYQ1IrUTZzZWs4YmY5MixpPTQwOTY="
|
|
|
|
),
|
|
|
|
justCheckAttributes: {
|
|
|
|
"mechanism": "SCRAM-SHA-1"
|
|
|
|
}
|
|
|
|
)
|
|
|
|
]
|
|
|
|
);
|
2022-05-30 14:26:34 +00:00
|
|
|
final XmppConnection conn = XmppConnection(TestingReconnectionPolicy(), socket: fakeSocket);
|
2022-01-21 10:23:09 +00:00
|
|
|
conn.setConnectionSettings(ConnectionSettings(
|
2022-02-22 20:21:31 +00:00
|
|
|
jid: JID.fromString("polynomdivision@test.server"),
|
2022-01-21 10:23:09 +00:00
|
|
|
password: "aaaa",
|
|
|
|
useDirectTLS: true,
|
|
|
|
allowPlainAuth: false
|
|
|
|
));
|
2022-07-16 16:42:45 +00:00
|
|
|
conn.registerManagers([
|
|
|
|
PresenceManager(),
|
|
|
|
RosterManager(),
|
|
|
|
DiscoManager(),
|
|
|
|
PingManager(),
|
|
|
|
]);
|
|
|
|
conn.registerFeatureNegotiators([
|
|
|
|
SaslPlainNegotiator(),
|
|
|
|
SaslScramNegotiator(10, "", "", ScramHashType.sha1),
|
|
|
|
]);
|
2022-01-23 15:17:00 +00:00
|
|
|
|
2022-03-08 20:50:21 +00:00
|
|
|
await conn.connect();
|
2022-01-21 16:44:48 +00:00
|
|
|
await Future.delayed(const Duration(seconds: 3), () {
|
|
|
|
expect(fakeSocket.getState(), 2);
|
|
|
|
});
|
2022-01-21 10:23:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
group("Test roster pushes", () {
|
|
|
|
test("Test for a CVE-2015-8688 style vulnerability", () async {
|
|
|
|
bool eventTriggered = false;
|
|
|
|
final roster = RosterManager();
|
|
|
|
roster.register(XmppManagerAttributes(
|
2022-04-10 20:57:04 +00:00
|
|
|
sendStanza: (_, { StanzaFromType addFrom = StanzaFromType.full, bool addId = true, bool retransmitted = false, bool awaitable = true }) async => XMLNode(tag: "hallo"),
|
2022-01-21 10:23:09 +00:00
|
|
|
sendEvent: (event) {
|
|
|
|
eventTriggered = true;
|
|
|
|
},
|
|
|
|
sendNonza: (_) {},
|
|
|
|
sendRawXml: (_) {},
|
|
|
|
getConnectionSettings: () => ConnectionSettings(
|
2022-02-22 20:21:31 +00:00
|
|
|
jid: JID.fromString("some.user@example.server"),
|
2022-01-21 10:23:09 +00:00
|
|
|
password: "password",
|
|
|
|
useDirectTLS: true,
|
|
|
|
allowPlainAuth: false,
|
|
|
|
),
|
|
|
|
getManagerById: (_) => null,
|
2022-03-01 19:26:55 +00:00
|
|
|
isFeatureSupported: (_) => false,
|
2022-04-20 20:52:32 +00:00
|
|
|
getFullJID: () => JID.fromString("some.user@example.server/aaaaa"),
|
2022-05-07 21:48:51 +00:00
|
|
|
getSocket: () => StubTCPSocket(play: []),
|
2022-07-16 16:42:45 +00:00
|
|
|
getConnection: () => XmppConnection(TestingReconnectionPolicy()),
|
|
|
|
getNegotiatorById: (_) => null,
|
2022-01-21 10:23:09 +00:00
|
|
|
));
|
|
|
|
|
|
|
|
// NOTE: Based on https://gultsch.de/gajim_roster_push_and_message_interception.html
|
2022-02-22 15:25:12 +00:00
|
|
|
// NOTE: Added a from attribute as a server would add it itself.
|
|
|
|
final maliciousStanza = Stanza.fromXMLNode(XMLNode.fromString("<iq type=\"set\" from=\"eve@siacs.eu/bbbbb\" to=\"some.user@example.server/aaaaa\"><query xmlns='jabber:iq:roster'><item subscription=\"both\" jid=\"eve@siacs.eu\" name=\"Bob\" /></query></iq>"));
|
2022-03-11 20:39:42 +00:00
|
|
|
|
|
|
|
for (final handler in roster.getIncomingStanzaHandlers()) {
|
|
|
|
if (handler.matches(maliciousStanza)) await handler.callback(maliciousStanza, StanzaHandlerData(false, maliciousStanza));
|
|
|
|
}
|
2022-01-21 10:23:09 +00:00
|
|
|
|
|
|
|
expect(eventTriggered, false, reason: "Was able to inject a malicious roster push");
|
|
|
|
});
|
2022-02-22 20:21:31 +00:00
|
|
|
test("The manager should accept pushes from our bare jid", () async {
|
|
|
|
final result = await testRosterManager("test.user@server.example", "aaaaa", "<iq from='test.user@server.example' type='result' id='82c2aa1e-cac3-4f62-9e1f-bbe6b057daf3' to='test.user@server.example/aaaaa' xmlns='jabber:client'><query ver='64' xmlns='jabber:iq:roster'><item jid='some.other.user@server.example' subscription='to' /></query></iq>");
|
|
|
|
expect(result, true, reason: "Roster pushes from our bare JID should be accepted");
|
|
|
|
});
|
|
|
|
test("The manager should accept pushes from a jid that, if the resource is stripped, is our bare jid", () async {
|
|
|
|
final result1 = await testRosterManager("test.user@server.example", "aaaaa", "<iq from='test.user@server.example/aaaaa' type='result' id='82c2aa1e-cac3-4f62-9e1f-bbe6b057daf3' to='test.user@server.example/aaaaa' xmlns='jabber:client'><query ver='64' xmlns='jabber:iq:roster'><item jid='some.other.user@server.example' subscription='to' /></query></iq>");
|
|
|
|
expect(result1, true, reason: "Roster pushes should be accepted if the bare JIDs are the same");
|
|
|
|
|
|
|
|
final result2 = await testRosterManager("test.user@server.example", "aaaaa", "<iq from='test.user@server.example/bbbbb' type='result' id='82c2aa1e-cac3-4f62-9e1f-bbe6b057daf3' to='test.user@server.example/aaaaa' xmlns='jabber:client'><query ver='64' xmlns='jabber:iq:roster'><item jid='some.other.user@server.example' subscription='to' /></query></iq>");
|
|
|
|
expect(result2, true, reason: "Roster pushes should be accepted if the bare JIDs are the same");
|
|
|
|
});
|
2021-12-30 19:06:20 +00:00
|
|
|
});
|
2021-12-30 18:49:01 +00:00
|
|
|
}
|