Compare commits
No commits in common. "c307567025b50b8a2458b7e820043fed37f23041" and "6d9010b11c73037725ee511785b5a67cbfa702ee" have entirely different histories.
c307567025
...
6d9010b11c
@ -78,7 +78,6 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
CSINegotiator(),
|
CSINegotiator(),
|
||||||
RosterFeatureNegotiator(),
|
RosterFeatureNegotiator(),
|
||||||
SaslPlainNegotiator(),
|
SaslPlainNegotiator(),
|
||||||
SaslScramNegotiator(10, '', '', ScramHashType.sha512),
|
|
||||||
SaslScramNegotiator(9, '', '', ScramHashType.sha256),
|
SaslScramNegotiator(9, '', '', ScramHashType.sha256),
|
||||||
SaslScramNegotiator(8, '', '', ScramHashType.sha1),
|
SaslScramNegotiator(8, '', '', ScramHashType.sha1),
|
||||||
]);
|
]);
|
||||||
|
@ -16,10 +16,10 @@ dependencies:
|
|||||||
version: 0.1.4+1
|
version: 0.1.4+1
|
||||||
moxxmpp:
|
moxxmpp:
|
||||||
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
||||||
version: 0.1.2+3
|
version: 0.1.2+2
|
||||||
moxxmpp_socket_tcp:
|
moxxmpp_socket_tcp:
|
||||||
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
||||||
version: 0.1.2+3
|
version: 0.1.2+2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
## 0.1.2+3
|
|
||||||
|
|
||||||
- **FIX**: SASL SCRAM-SHA-{256,512} should now work.
|
|
||||||
|
|
||||||
## 0.1.2+2
|
## 0.1.2+2
|
||||||
|
|
||||||
- **FIX**: Fix reconnections when the connection is awaited.
|
- **FIX**: Fix reconnections when the connection is awaited.
|
||||||
|
@ -30,17 +30,6 @@ HashAlgorithm hashFromType(ScramHashType type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pbkdfBitsFromHash(ScramHashType type) {
|
|
||||||
switch (type) {
|
|
||||||
// NOTE: SHA1 is 20 octets long => 20 octets * 8 bits/octet
|
|
||||||
case ScramHashType.sha1: return 160;
|
|
||||||
// NOTE: SHA256 is 32 octets long => 32 octets * 8 bits/octet
|
|
||||||
case ScramHashType.sha256: return 256;
|
|
||||||
// NOTE: SHA512 is 64 octets long => 64 octets * 8 bits/octet
|
|
||||||
case ScramHashType.sha512: return 512;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const scramSha1Mechanism = 'SCRAM-SHA-1';
|
const scramSha1Mechanism = 'SCRAM-SHA-1';
|
||||||
const scramSha256Mechanism = 'SCRAM-SHA-256';
|
const scramSha256Mechanism = 'SCRAM-SHA-256';
|
||||||
const scramSha512Mechanism = 'SCRAM-SHA-512';
|
const scramSha512Mechanism = 'SCRAM-SHA-512';
|
||||||
@ -117,7 +106,7 @@ class SaslScramNegotiator extends SaslNegotiator {
|
|||||||
final pbkdf2 = Pbkdf2(
|
final pbkdf2 = Pbkdf2(
|
||||||
macAlgorithm: Hmac(_hash),
|
macAlgorithm: Hmac(_hash),
|
||||||
iterations: iterations,
|
iterations: iterations,
|
||||||
bits: pbkdfBitsFromHash(hashType),
|
bits: 160, // NOTE: RFC says 20 octets => 20 octets * 8 bits/octet
|
||||||
);
|
);
|
||||||
|
|
||||||
final saltedPasswordRaw = await pbkdf2.deriveKey(
|
final saltedPasswordRaw = await pbkdf2.deriveKey(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: moxxmpp
|
name: moxxmpp
|
||||||
description: A pure-Dart XMPP library
|
description: A pure-Dart XMPP library
|
||||||
version: 0.1.2+3
|
version: 0.1.2+2
|
||||||
homepage: https://codeberg.org/moxxy/moxxmpp
|
homepage: https://codeberg.org/moxxy/moxxmpp
|
||||||
publish_to: https://git.polynom.me/api/packages/Moxxy/pub
|
publish_to: https://git.polynom.me/api/packages/Moxxy/pub
|
||||||
|
|
||||||
@ -31,6 +31,6 @@ dev_dependencies:
|
|||||||
build_runner: ^2.1.11
|
build_runner: ^2.1.11
|
||||||
moxxmpp_socket_tcp:
|
moxxmpp_socket_tcp:
|
||||||
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
||||||
version: ^0.1.2+3
|
version: ^0.1.2+2
|
||||||
test: ^1.16.0
|
test: ^1.16.0
|
||||||
very_good_analysis: ^3.0.1
|
very_good_analysis: ^3.0.1
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
import 'package:moxxmpp/src/negotiators/sasl/kv.dart';
|
|
||||||
import 'package:moxxmpp/moxxmpp.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
test('Test the Key-Value parser', () {
|
|
||||||
final result1 = parseKeyValue('n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL');
|
|
||||||
expect(result1.length, 2);
|
|
||||||
expect(result1['n']!, 'user');
|
|
||||||
expect(result1['r']!, 'fyko+d2lbbFgONRv9qkxdawL');
|
|
||||||
|
|
||||||
final result2 = parseKeyValue('r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096');
|
|
||||||
expect(result2.length, 3);
|
|
||||||
expect(result2['r']!, 'fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j');
|
|
||||||
expect(result2['s']!, 'QSXCR+Q6sek8bf92');
|
|
||||||
expect(result2['i']!, '4096');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Test the Key-Value parser with '=' as a value", () {
|
|
||||||
final result = parseKeyValue('c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=,o=123');
|
|
||||||
expect(result.length, 4);
|
|
||||||
expect(result['c']!, 'biws');
|
|
||||||
expect(result['r']!, 'fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j');
|
|
||||||
expect(result['p']!, 'v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=');
|
|
||||||
expect(result['o']!, '123');
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,207 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'package:hex/hex.dart';
|
|
||||||
import 'package:moxxmpp/moxxmpp.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
import '../helpers/xmpp.dart';
|
|
||||||
|
|
||||||
final scramSha1StreamFeatures = XMLNode(
|
|
||||||
tag: 'stream:features',
|
|
||||||
children: [
|
|
||||||
XMLNode.xmlns(
|
|
||||||
tag: 'mechanisms',
|
|
||||||
xmlns: saslXmlns,
|
|
||||||
children: [
|
|
||||||
XMLNode(
|
|
||||||
tag: 'mechanism',
|
|
||||||
text: 'SCRAM-SHA-1',
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
final scramSha256StreamFeatures = XMLNode(
|
|
||||||
tag: 'stream:features',
|
|
||||||
children: [
|
|
||||||
XMLNode.xmlns(
|
|
||||||
tag: 'mechanisms',
|
|
||||||
xmlns: saslXmlns,
|
|
||||||
children: [
|
|
||||||
XMLNode(
|
|
||||||
tag: 'mechanism',
|
|
||||||
text: 'SCRAM-SHA-256',
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
final fakeSocket = StubTCPSocket(play: []);
|
|
||||||
test('Test SASL SCRAM-SHA-1', () async {
|
|
||||||
final negotiator = SaslScramNegotiator(0, 'n=user,r=fyko+d2lbbFgONRv9qkxdawL', 'fyko+d2lbbFgONRv9qkxdawL', ScramHashType.sha1);
|
|
||||||
negotiator.register(
|
|
||||||
NegotiatorAttributes(
|
|
||||||
(XMLNode _, {String? redact}) {},
|
|
||||||
() => ConnectionSettings(jid: JID.fromString('user@server'), password: 'pencil', useDirectTLS: true, allowPlainAuth: true),
|
|
||||||
(_) async {},
|
|
||||||
getNegotiatorNullStub,
|
|
||||||
getManagerNullStub,
|
|
||||||
() => JID.fromString('user@server'),
|
|
||||||
() => fakeSocket,
|
|
||||||
() => false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
HEX.encode(await negotiator.calculateSaltedPassword('QSXCR+Q6sek8bf92', 4096)),
|
|
||||||
'1d96ee3a529b5a5f9e47c01f229a2cb8a6e15f7d',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
HEX.encode(
|
|
||||||
await negotiator.calculateClientKey(HEX.decode('1d96ee3a529b5a5f9e47c01f229a2cb8a6e15f7d')),
|
|
||||||
),
|
|
||||||
'e234c47bf6c36696dd6d852b99aaa2ba26555728',
|
|
||||||
);
|
|
||||||
const authMessage = 'n=user,r=fyko+d2lbbFgONRv9qkxdawL,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096,c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j';
|
|
||||||
expect(
|
|
||||||
HEX.encode(
|
|
||||||
await negotiator.calculateClientSignature(authMessage, HEX.decode('e9d94660c39d65c38fbad91c358f14da0eef2bd6')),
|
|
||||||
),
|
|
||||||
'5d7138c486b0bfabdf49e3e2da8bd6e5c79db613',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
HEX.encode(
|
|
||||||
negotiator.calculateClientProof(HEX.decode('e234c47bf6c36696dd6d852b99aaa2ba26555728'), HEX.decode('5d7138c486b0bfabdf49e3e2da8bd6e5c79db613')),
|
|
||||||
),
|
|
||||||
'bf45fcbf7073d93d022466c94321745fe1c8e13b',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
HEX.encode(
|
|
||||||
await negotiator.calculateServerSignature(authMessage, HEX.decode('0fe09258b3ac852ba502cc62ba903eaacdbf7d31')),
|
|
||||||
),
|
|
||||||
'ae617da6a57c4bbb2e0286568dae1d251905b0a4',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
HEX.encode(
|
|
||||||
await negotiator.calculateServerKey(HEX.decode('1d96ee3a529b5a5f9e47c01f229a2cb8a6e15f7d')),
|
|
||||||
),
|
|
||||||
'0fe09258b3ac852ba502cc62ba903eaacdbf7d31',
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
HEX.encode(
|
|
||||||
negotiator.calculateClientProof(
|
|
||||||
HEX.decode('e234c47bf6c36696dd6d852b99aaa2ba26555728'),
|
|
||||||
HEX.decode('5d7138c486b0bfabdf49e3e2da8bd6e5c79db613'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'bf45fcbf7073d93d022466c94321745fe1c8e13b',
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(await negotiator.calculateChallengeResponse('cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng=='), 'c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test SASL SCRAM-SHA-256', () async {
|
|
||||||
String? lastMessage;
|
|
||||||
final negotiator = SaslScramNegotiator(0, 'n=user,r=rOprNGfwEbeRWgbNEkqO', 'rOprNGfwEbeRWgbNEkqO', ScramHashType.sha256);
|
|
||||||
negotiator.register(
|
|
||||||
NegotiatorAttributes(
|
|
||||||
(XMLNode n, {String? redact}) => lastMessage = n.innerText(),
|
|
||||||
() => ConnectionSettings(jid: JID.fromString('user@server'), password: 'pencil', useDirectTLS: true, allowPlainAuth: true),
|
|
||||||
(_) async {},
|
|
||||||
getNegotiatorNullStub,
|
|
||||||
getManagerNullStub,
|
|
||||||
() => JID.fromString('user@server'),
|
|
||||||
() => fakeSocket,
|
|
||||||
() => false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await negotiator.negotiate(scramSha256StreamFeatures);
|
|
||||||
expect(
|
|
||||||
utf8.decode(base64Decode(lastMessage!)),
|
|
||||||
'n,,n=user,r=rOprNGfwEbeRWgbNEkqO',
|
|
||||||
);
|
|
||||||
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1yT3ByTkdmd0ViZVJXZ2JORWtxTyVodllEcFdVYTJSYVRDQWZ1eEZJbGopaE5sRiRrMCxzPVcyMlphSjBTTlk3c29Fc1VFamI2Z1E9PSxpPTQwOTY=</challenge>"));
|
|
||||||
expect(
|
|
||||||
utf8.decode(base64Decode(lastMessage!)),
|
|
||||||
'c=biws,r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF\$k0,p=dHzbZapWIk4jUhN+Ute9ytag9zjfMHgsqmmiz7AndVQ=',
|
|
||||||
);
|
|
||||||
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dj02cnJpVFJCaTIzV3BSUi93dHVwK21NaFVaVW4vZEI1bkxUSlJzamw5NUc0PQ==</success>"));
|
|
||||||
|
|
||||||
expect(negotiator.state, NegotiatorState.done);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test a positive server signature check', () async {
|
|
||||||
final negotiator = SaslScramNegotiator(0, 'n=user,r=fyko+d2lbbFgONRv9qkxdawL', 'fyko+d2lbbFgONRv9qkxdawL', ScramHashType.sha1);
|
|
||||||
negotiator.register(
|
|
||||||
NegotiatorAttributes(
|
|
||||||
(XMLNode _, {String? redact}) {},
|
|
||||||
() => ConnectionSettings(jid: JID.fromString('user@server'), password: 'pencil', useDirectTLS: true, allowPlainAuth: true),
|
|
||||||
(_) async {},
|
|
||||||
getNegotiatorNullStub,
|
|
||||||
getManagerNullStub,
|
|
||||||
() => JID.fromString('user@server'),
|
|
||||||
() => fakeSocket,
|
|
||||||
() => false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await negotiator.negotiate(scramSha1StreamFeatures);
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==</challenge>"));
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dj1ybUY5cHFWOFM3c3VBb1pXamE0ZEpSa0ZzS1E9</success>"));
|
|
||||||
|
|
||||||
expect(negotiator.state, NegotiatorState.done);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test a negative server signature check', () async {
|
|
||||||
final negotiator = SaslScramNegotiator(0, 'n=user,r=fyko+d2lbbFgONRv9qkxdawL', 'fyko+d2lbbFgONRv9qkxdawL', ScramHashType.sha1);
|
|
||||||
negotiator.register(
|
|
||||||
NegotiatorAttributes(
|
|
||||||
(XMLNode _, {String? redact}) {},
|
|
||||||
() => ConnectionSettings(jid: JID.fromString('user@server'), password: 'pencil', useDirectTLS: true, allowPlainAuth: true),
|
|
||||||
(_) async {},
|
|
||||||
getNegotiatorNullStub,
|
|
||||||
getManagerNullStub,
|
|
||||||
() => JID.fromString('user@server'),
|
|
||||||
() => fakeSocket,
|
|
||||||
() => false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await negotiator.negotiate(scramSha1StreamFeatures);
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==</challenge>"));
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dj1zbUY5cHFWOFM3c3VBb1pXamE0ZEpSa0ZzS1E9</success>"));
|
|
||||||
|
|
||||||
expect(negotiator.state, NegotiatorState.error);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test a resetting the SCRAM negotiator', () async {
|
|
||||||
final negotiator = SaslScramNegotiator(0, 'n=user,r=fyko+d2lbbFgONRv9qkxdawL', 'fyko+d2lbbFgONRv9qkxdawL', ScramHashType.sha1);
|
|
||||||
negotiator.register(
|
|
||||||
NegotiatorAttributes(
|
|
||||||
(XMLNode _, {String? redact}) {},
|
|
||||||
() => ConnectionSettings(jid: JID.fromString('user@server'), password: 'pencil', useDirectTLS: true, allowPlainAuth: true),
|
|
||||||
(_) async {},
|
|
||||||
getNegotiatorNullStub,
|
|
||||||
getManagerNullStub,
|
|
||||||
() => JID.fromString('user@server'),
|
|
||||||
() => fakeSocket,
|
|
||||||
() => false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
await negotiator.negotiate(scramSha1StreamFeatures);
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==</challenge>"));
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dj1ybUY5cHFWOFM3c3VBb1pXamE0ZEpSa0ZzS1E9</success>"));
|
|
||||||
expect(negotiator.state, NegotiatorState.done);
|
|
||||||
|
|
||||||
// Reset and try again
|
|
||||||
negotiator.reset();
|
|
||||||
await negotiator.negotiate(scramSha1StreamFeatures);
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==</challenge>"));
|
|
||||||
await negotiator.negotiate(XMLNode.fromString("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dj1ybUY5cHFWOFM3c3VBb1pXamE0ZEpSa0ZzS1E9</success>"));
|
|
||||||
expect(negotiator.state, NegotiatorState.done);
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,7 +1,3 @@
|
|||||||
## 0.1.2+3
|
|
||||||
|
|
||||||
- Update a dependency to the latest release.
|
|
||||||
|
|
||||||
## 0.1.2+2
|
## 0.1.2+2
|
||||||
|
|
||||||
- **FIX**: Fix reconnections when the connection is awaited.
|
- **FIX**: Fix reconnections when the connection is awaited.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: moxxmpp_socket_tcp
|
name: moxxmpp_socket_tcp
|
||||||
description: A socket for moxxmpp using TCP that implements the RFC6120 connection algorithm and XEP-0368
|
description: A socket for moxxmpp using TCP that implements the RFC6120 connection algorithm and XEP-0368
|
||||||
version: 0.1.2+3
|
version: 0.1.2+2
|
||||||
homepage: https://codeberg.org/moxxy/moxxmpp
|
homepage: https://codeberg.org/moxxy/moxxmpp
|
||||||
publish_to: https://git.polynom.me/api/packages/Moxxy/pub
|
publish_to: https://git.polynom.me/api/packages/Moxxy/pub
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ dependencies:
|
|||||||
meta: ^1.6.0
|
meta: ^1.6.0
|
||||||
moxxmpp:
|
moxxmpp:
|
||||||
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
hosted: https://git.polynom.me/api/packages/Moxxy/pub
|
||||||
version: ^0.1.2+3
|
version: ^0.1.2+2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^2.0.0
|
lints: ^2.0.0
|
||||||
|
Loading…
Reference in New Issue
Block a user