run method

  1. @override
Future<AuditResult> run(
  1. TelnetTransport transport
)
override

Implementation

@override
Future<AuditResult> run(TelnetTransport transport) async {
  final completer = Completer<AuditResult>();

  final stateManager = NegotiationStateManager(
    onSend: (bytes) => transport.write(bytes),
  );

  final subscription = transport.events.listen(
    (event) {
      if (!completer.isCompleted) {
        if (event.type == TelnetEventType.iac) {
          stateManager.handleCommand(event.bytes);
          completer.complete(
            AuditResult(
              name,
              AuditStatus.pass,
              'Server responded to AYT with a Telnet command: ${event.bytes}',
            ),
          );
        } else if (event.type == TelnetEventType.data) {
          completer.complete(
            AuditResult(
              name,
              AuditStatus.pass,
              'Server responded to AYT with data.',
            ),
          );
        }
      }
    },
    onError: (error) {
      if (!completer.isCompleted) {
        completer.complete(
          AuditResult(
            name,
            AuditStatus.fail,
            'Error during AYT probe: $error',
          ),
        );
      }
    },
  );

  try {
    // Send IAC AYT (255, 246)
    transport.write(Uint8List.fromList([255, 246]));

    return await completer.future.timeout(
      const Duration(seconds: 5),
      onTimeout: () {
        return AuditResult(
          name,
          AuditStatus.fail,
          'Timeout waiting for AYT response.',
        );
      },
    );
  } catch (e) {
    if (e is TimeoutException) {
      return AuditResult(
        name,
        AuditStatus.fail,
        'Timeout waiting for AYT response.',
      );
    }
    return AuditResult(
      name,
      AuditStatus.fail,
      'Exception during AYT probe: $e',
    );
  } finally {
    await subscription.cancel();
  }
}