feat(xep): Guard against random data in the SASL2 result
This commit is contained in:
		
							parent
							
								
									30482c86f0
								
							
						
					
					
						commit
						af8bc606d6
					
				| @ -6,18 +6,6 @@ import 'package:moxxmpp/src/negotiators/sasl/negotiator.dart'; | ||||
| import 'package:moxxmpp/src/stringxml.dart'; | ||||
| import 'package:moxxmpp/src/types/result.dart'; | ||||
| 
 | ||||
| bool isInliningPossible(XMLNode nonza, String xmlns) { | ||||
|   assert(nonza.tag == 'authentication', 'Ensure we use the correct nonza'); | ||||
|   assert(nonza.xmlns == sasl2Xmlns, 'Ensure we use the correct nonza'); | ||||
|   final inline = nonza.firstTag('inline'); | ||||
|   if (inline == null) { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   return inline.children.firstWhereOrNull((child) => child.xmlns == xmlns) != | ||||
|       null; | ||||
| } | ||||
| 
 | ||||
| /// A special type of [XmppFeatureNegotiatorBase] that is aware of SASL2. | ||||
| abstract class Sasl2FeatureNegotiator extends XmppFeatureNegotiatorBase { | ||||
|   Sasl2FeatureNegotiator( | ||||
| @ -30,10 +18,14 @@ abstract class Sasl2FeatureNegotiator extends XmppFeatureNegotiatorBase { | ||||
|   /// Called by the SASL2 negotiator when we received the SASL2 stream features | ||||
|   /// [sasl2Features]. The return value is a list of XML elements that should be | ||||
|   /// added to the SASL2 <authenticate /> nonza. | ||||
|   /// This method is only called when the <inline /> element contains an item with | ||||
|   /// xmlns equal to [negotiatingXmlns]. | ||||
|   Future<List<XMLNode>> onSasl2FeaturesReceived(XMLNode sasl2Features); | ||||
| 
 | ||||
|   /// Called by the SASL2 negotiator when the SASL2 negotiations are done. [response] | ||||
|   /// is the entire response nonza. | ||||
|   /// This method is only called when the previous <inline /> element contains an | ||||
|   /// item with xmlns equal to [negotiatingXmlns]. | ||||
|   Future<Result<bool, NegotiatorError>> onSasl2Success(XMLNode response); | ||||
| } | ||||
| 
 | ||||
| @ -148,6 +140,18 @@ class Sasl2Negotiator extends XmppFeatureNegotiatorBase { | ||||
|     _featureNegotiators.add(negotiator); | ||||
|   } | ||||
| 
 | ||||
|   /// Returns true, if an item with xmlns of [xmlns] is contained inside [_sasl2Data]'s | ||||
|   /// <inline /> block. If not, returns false. | ||||
|   bool _isInliningPossible(String xmlns) { | ||||
|     final inline = _sasl2Data!.firstTag('inline'); | ||||
|     if (inline == null) { | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     return inline.children.firstWhereOrNull((child) => child.xmlns == xmlns) != | ||||
|         null; | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   bool matchesFeature(List<XMLNode> features) { | ||||
|     // Only do SASL2 when the socket is secure | ||||
| @ -182,7 +186,7 @@ class Sasl2Negotiator extends XmppFeatureNegotiatorBase { | ||||
|         // Collect additional data by interested negotiators | ||||
|         final children = List<XMLNode>.empty(growable: true); | ||||
|         for (final negotiator in _featureNegotiators) { | ||||
|           if (isInliningPossible(_sasl2Data!, negotiator.negotiatingXmlns)) { | ||||
|           if (_isInliningPossible(negotiator.negotiatingXmlns)) { | ||||
|             children.addAll( | ||||
|               await negotiator.onSasl2FeaturesReceived(_sasl2Data!), | ||||
|             ); | ||||
| @ -214,7 +218,7 @@ class Sasl2Negotiator extends XmppFeatureNegotiatorBase { | ||||
|           // Tell the dependent negotiators about the result | ||||
|           // TODO(Unknown): This can be written in a better way | ||||
|           for (final negotiator in _featureNegotiators) { | ||||
|             if (isInliningPossible(_sasl2Data!, negotiator.negotiatingXmlns)) { | ||||
|             if (_isInliningPossible(negotiator.negotiatingXmlns)) { | ||||
|               final result = await negotiator.onSasl2Success(nonza); | ||||
|               if (!result.isType<bool>()) { | ||||
|                 return Result(result.get<NegotiatorError>()); | ||||
|  | ||||
| @ -25,10 +25,6 @@ class ExampleNegotiator extends Sasl2FeatureNegotiator { | ||||
| 
 | ||||
|   @override | ||||
|   Future<List<XMLNode>> onSasl2FeaturesReceived(XMLNode nonza) async { | ||||
|     if (!isInliningPossible(nonza, 'invalid:example:dont:use')) { | ||||
|       return []; | ||||
|     } | ||||
| 
 | ||||
|     return [ | ||||
|       XMLNode.xmlns( | ||||
|         tag: 'test-data-request', | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user