fix: A certificate rejection does not crash the connection
Fixes moxxy/moxxyv2#137.
This commit is contained in:
parent
848d83dc1f
commit
3172450b70
@ -12,3 +12,4 @@ analyzer:
|
|||||||
- "**/*.g.dart"
|
- "**/*.g.dart"
|
||||||
- "**/*.freezed.dart"
|
- "**/*.freezed.dart"
|
||||||
- "test/"
|
- "test/"
|
||||||
|
- "integration_test/"
|
||||||
|
@ -796,6 +796,15 @@ class XmppConnection {
|
|||||||
|
|
||||||
_updateRoutingState(RoutingState.handleStanzas);
|
_updateRoutingState(RoutingState.handleStanzas);
|
||||||
await _onNegotiationsDone();
|
await _onNegotiationsDone();
|
||||||
|
} else if (_currentNegotiator!.state == NegotiatorState.error) {
|
||||||
|
_log.severe('Negotiator returned an error');
|
||||||
|
|
||||||
|
_updateRoutingState(RoutingState.error);
|
||||||
|
await _setConnectionState(XmppConnectionState.error);
|
||||||
|
_connectionCompleter?.complete(const XmppConnectionResult(false));
|
||||||
|
_connectionCompleter = null;
|
||||||
|
|
||||||
|
_closeSocket();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
|
import 'package:moxxmpp_socket_tcp/moxxmpp_socket_tcp.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
Future<void> _runTest(String domain) async {
|
||||||
|
var gotTLSException = false;
|
||||||
|
final socket = TCPSocketWrapper(false);
|
||||||
|
final log = Logger('TestLogger');
|
||||||
|
socket.getEventStream().listen((event) {
|
||||||
|
if (event is XmppSocketTLSFailedEvent) {
|
||||||
|
log.info('Got XmppSocketTLSFailedEvent from socket');
|
||||||
|
gotTLSException = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final connection = XmppConnection(
|
||||||
|
ExponentialBackoffReconnectionPolicy(),
|
||||||
|
socket,
|
||||||
|
);
|
||||||
|
connection.registerFeatureNegotiators([
|
||||||
|
StartTlsNegotiator(),
|
||||||
|
]);
|
||||||
|
connection.registerManagers([
|
||||||
|
DiscoManager(),
|
||||||
|
RosterManager(),
|
||||||
|
PingManager(),
|
||||||
|
MessageManager(),
|
||||||
|
PresenceManager('http://moxxmpp.example'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
connection.setConnectionSettings(
|
||||||
|
ConnectionSettings(
|
||||||
|
jid: JID.fromString('testuser@$domain'),
|
||||||
|
password: 'abc123',
|
||||||
|
useDirectTLS: true,
|
||||||
|
allowPlainAuth: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await connection.connectAwaitable();
|
||||||
|
expect(result.success, false);
|
||||||
|
expect(gotTLSException, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
Logger.root.level = Level.ALL;
|
||||||
|
Logger.root.onRecord.listen((record) {
|
||||||
|
print('${record.level.name}: ${record.time}: ${record.message}');
|
||||||
|
});
|
||||||
|
|
||||||
|
for (final domain in [
|
||||||
|
'self-signed.badxmpp.eu',
|
||||||
|
'expired.badxmpp.eu',
|
||||||
|
'wrong-name.badxmpp.eu',
|
||||||
|
'missing-chain.badxmpp.eu',
|
||||||
|
// TODO(Unknown): Technically, this one should not fail
|
||||||
|
//'ecdsa.badxmpp.eu',
|
||||||
|
]) {
|
||||||
|
test('$domain with connectAwaitable', () async {
|
||||||
|
await _runTest(domain);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
library moxxmpp_socket_tcp;
|
library moxxmpp_socket_tcp;
|
||||||
|
|
||||||
|
export 'src/events.dart';
|
||||||
export 'src/record.dart';
|
export 'src/record.dart';
|
||||||
export 'src/socket.dart';
|
export 'src/socket.dart';
|
||||||
|
4
packages/moxxmpp_socket_tcp/lib/src/events.dart
Normal file
4
packages/moxxmpp_socket_tcp/lib/src/events.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
|
|
||||||
|
/// Triggered when TLS errors occur
|
||||||
|
class XmppSocketTLSFailedEvent extends XmppSocketEvent {}
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:moxxmpp/moxxmpp.dart';
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
|
import 'package:moxxmpp_socket_tcp/src/events.dart';
|
||||||
import 'package:moxxmpp_socket_tcp/src/record.dart';
|
import 'package:moxxmpp_socket_tcp/src/record.dart';
|
||||||
import 'package:moxxmpp_socket_tcp/src/rfc_2782.dart';
|
import 'package:moxxmpp_socket_tcp/src/rfc_2782.dart';
|
||||||
|
|
||||||
@ -66,6 +67,7 @@ class TCPSocketWrapper extends BaseSocketWrapper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var failedDueToTLS = false;
|
||||||
results.sort(srvRecordSortComparator);
|
results.sort(srvRecordSortComparator);
|
||||||
for (final srv in results) {
|
for (final srv in results) {
|
||||||
try {
|
try {
|
||||||
@ -91,11 +93,19 @@ class TCPSocketWrapper extends BaseSocketWrapper {
|
|||||||
_secure = true;
|
_secure = true;
|
||||||
_log.finest('Success!');
|
_log.finest('Success!');
|
||||||
return true;
|
return true;
|
||||||
} on SocketException catch(e) {
|
} on Exception catch(e) {
|
||||||
_log.finest('Failure! $e');
|
_log.finest('Failure! $e');
|
||||||
_ignoreSocketClosure = false;
|
_ignoreSocketClosure = false;
|
||||||
|
|
||||||
|
if (e is HandshakeException) {
|
||||||
|
failedDueToTLS = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failedDueToTLS) {
|
||||||
|
_eventStream.add(XmppSocketTLSFailedEvent());
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -118,7 +128,7 @@ class TCPSocketWrapper extends BaseSocketWrapper {
|
|||||||
_ignoreSocketClosure = false;
|
_ignoreSocketClosure = false;
|
||||||
_log.finest('Success!');
|
_log.finest('Success!');
|
||||||
return true;
|
return true;
|
||||||
} on SocketException catch(e) {
|
} on Exception catch(e) {
|
||||||
_log.finest('Failure! $e');
|
_log.finest('Failure! $e');
|
||||||
_ignoreSocketClosure = false;
|
_ignoreSocketClosure = false;
|
||||||
continue;
|
continue;
|
||||||
@ -142,7 +152,7 @@ class TCPSocketWrapper extends BaseSocketWrapper {
|
|||||||
);
|
);
|
||||||
_log.finest('Success!');
|
_log.finest('Success!');
|
||||||
return true;
|
return true;
|
||||||
} on SocketException catch(e) {
|
} on Exception catch(e) {
|
||||||
_log.finest('Failure! $e');
|
_log.finest('Failure! $e');
|
||||||
_ignoreSocketClosure = false;
|
_ignoreSocketClosure = false;
|
||||||
return false;
|
return false;
|
||||||
@ -183,8 +193,14 @@ class TCPSocketWrapper extends BaseSocketWrapper {
|
|||||||
_ignoreSocketClosure = false;
|
_ignoreSocketClosure = false;
|
||||||
_setupStreams();
|
_setupStreams();
|
||||||
return true;
|
return true;
|
||||||
} on SocketException {
|
} on Exception catch (e) {
|
||||||
|
_log.severe('Failed to secure socket: $e');
|
||||||
_ignoreSocketClosure = false;
|
_ignoreSocketClosure = false;
|
||||||
|
|
||||||
|
if (e is HandshakeException) {
|
||||||
|
_eventStream.add(XmppSocketTLSFailedEvent());
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,7 +309,7 @@ class TCPSocketWrapper extends BaseSocketWrapper {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
_socket!.write(data);
|
_socket!.write(data);
|
||||||
} on SocketException catch (e) {
|
} on Exception catch (e) {
|
||||||
_log.severe(e);
|
_log.severe(e);
|
||||||
_eventStream.add(XmppSocketErrorEvent(e));
|
_eventStream.add(XmppSocketErrorEvent(e));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user