2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
14 #include "webrtc/libjingle/xmllite/xmlelement.h"
15 #include "webrtc/libjingle/xmpp/constants.h"
16 #include "webrtc/libjingle/xmpp/plainsaslhandler.h"
17 #include "webrtc/libjingle/xmpp/saslplainmechanism.h"
18 #include "webrtc/libjingle/xmpp/util_unittest.h"
19 #include "webrtc/libjingle/xmpp/xmppengine.h"
20 #include "webrtc/base/common.h"
21 #include "webrtc/base/cryptstring.h"
22 #include "webrtc/base/gunit.h"
26 using buzz::XmlElement;
27 using buzz::XmppEngine;
28 using buzz::XmppTestHandler;
31 XLTT_STAGE_CONNECT = 0,
32 XLTT_STAGE_STREAMSTART,
33 XLTT_STAGE_TLS_FEATURES,
34 XLTT_STAGE_TLS_PROCEED,
35 XLTT_STAGE_ENCRYPTED_START,
36 XLTT_STAGE_AUTH_FEATURES,
37 XLTT_STAGE_AUTH_SUCCESS,
38 XLTT_STAGE_AUTHENTICATED_START,
39 XLTT_STAGE_BIND_FEATURES,
40 XLTT_STAGE_BIND_SUCCESS,
41 XLTT_STAGE_SESSION_SUCCESS,
44 class XmppLoginTaskTest : public testing::Test {
46 XmppEngine* engine() { return engine_.get(); }
47 XmppTestHandler* handler() { return handler_.get(); }
48 virtual void SetUp() {
49 engine_.reset(XmppEngine::Create());
50 handler_.reset(new XmppTestHandler(engine_.get()));
52 Jid jid("david@my-server");
53 rtc::InsecureCryptStringImpl pass;
54 pass.password() = "david";
55 engine_->SetSessionHandler(handler_.get());
56 engine_->SetOutputHandler(handler_.get());
57 engine_->AddStanzaHandler(handler_.get());
58 engine_->SetUser(jid);
59 engine_->SetSaslHandler(
60 new buzz::PlainSaslHandler(jid, rtc::CryptString(pass), true));
62 virtual void TearDown() {
66 void RunPartialLogin(XlttStage startstage, XlttStage endstage);
67 void SetTlsOptions(buzz::TlsOptions option);
70 rtc::scoped_ptr<XmppEngine> engine_;
71 rtc::scoped_ptr<XmppTestHandler> handler_;
74 void XmppLoginTaskTest::SetTlsOptions(buzz::TlsOptions option) {
75 engine_->SetTls(option);
77 void XmppLoginTaskTest::RunPartialLogin(XlttStage startstage,
82 case XLTT_STAGE_CONNECT: {
84 XmlElement appStanza(QName("test", "app-stanza"));
85 appStanza.AddText("this-is-a-test");
86 engine_->SendStanza(&appStanza);
88 EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
89 "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
90 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
91 EXPECT_EQ("[OPENING]", handler_->SessionActivity());
92 EXPECT_EQ("", handler_->StanzaActivity());
93 if (endstage == XLTT_STAGE_CONNECT)
97 case XLTT_STAGE_STREAMSTART: {
98 input = "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
99 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
100 "xmlns=\"jabber:client\">";
101 engine_->HandleInput(input.c_str(), input.length());
102 EXPECT_EQ("", handler_->StanzaActivity());
103 EXPECT_EQ("", handler_->SessionActivity());
104 EXPECT_EQ("", handler_->OutputActivity());
105 if (endstage == XLTT_STAGE_STREAMSTART)
109 case XLTT_STAGE_TLS_FEATURES: {
110 input = "<stream:features>"
111 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
112 "</stream:features>";
113 engine_->HandleInput(input.c_str(), input.length());
114 EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
115 handler_->OutputActivity());
116 EXPECT_EQ("", handler_->StanzaActivity());
117 EXPECT_EQ("", handler_->SessionActivity());
118 if (endstage == XLTT_STAGE_TLS_FEATURES)
122 case XLTT_STAGE_TLS_PROCEED: {
123 input = std::string("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
124 engine_->HandleInput(input.c_str(), input.length());
125 EXPECT_EQ("[START-TLS my-server]"
126 "<stream:stream to=\"my-server\" xml:lang=\"*\" "
127 "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
128 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
129 EXPECT_EQ("", handler_->StanzaActivity());
130 EXPECT_EQ("", handler_->SessionActivity());
131 if (endstage == XLTT_STAGE_TLS_PROCEED)
135 case XLTT_STAGE_ENCRYPTED_START: {
136 input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
137 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
138 "xmlns=\"jabber:client\">");
139 engine_->HandleInput(input.c_str(), input.length());
140 EXPECT_EQ("", handler_->StanzaActivity());
141 EXPECT_EQ("", handler_->SessionActivity());
142 EXPECT_EQ("", handler_->OutputActivity());
143 if (endstage == XLTT_STAGE_ENCRYPTED_START)
147 case XLTT_STAGE_AUTH_FEATURES: {
148 input = "<stream:features>"
149 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
150 "<mechanism>DIGEST-MD5</mechanism>"
151 "<mechanism>PLAIN</mechanism>"
153 "</stream:features>";
154 engine_->HandleInput(input.c_str(), input.length());
155 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
156 "mechanism=\"PLAIN\" "
157 "auth:allow-non-google-login=\"true\" "
158 "auth:client-uses-full-bind-result=\"true\" "
159 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
160 ">AGRhdmlkAGRhdmlk</auth>",
161 handler_->OutputActivity());
162 EXPECT_EQ("", handler_->StanzaActivity());
163 EXPECT_EQ("", handler_->SessionActivity());
164 if (endstage == XLTT_STAGE_AUTH_FEATURES)
168 case XLTT_STAGE_AUTH_SUCCESS: {
169 input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
170 engine_->HandleInput(input.c_str(), input.length());
171 EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
172 "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
173 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
174 EXPECT_EQ("", handler_->StanzaActivity());
175 EXPECT_EQ("", handler_->SessionActivity());
176 if (endstage == XLTT_STAGE_AUTH_SUCCESS)
180 case XLTT_STAGE_AUTHENTICATED_START: {
181 input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
182 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
183 "xmlns=\"jabber:client\">");
184 engine_->HandleInput(input.c_str(), input.length());
185 EXPECT_EQ("", handler_->StanzaActivity());
186 EXPECT_EQ("", handler_->SessionActivity());
187 EXPECT_EQ("", handler_->OutputActivity());
188 if (endstage == XLTT_STAGE_AUTHENTICATED_START)
192 case XLTT_STAGE_BIND_FEATURES: {
193 input = "<stream:features>"
194 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
195 "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
196 "</stream:features>";
197 engine_->HandleInput(input.c_str(), input.length());
198 EXPECT_EQ("<iq type=\"set\" id=\"0\">"
199 "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
200 handler_->OutputActivity());
201 EXPECT_EQ("", handler_->StanzaActivity());
202 EXPECT_EQ("", handler_->SessionActivity());
203 if (endstage == XLTT_STAGE_BIND_FEATURES)
207 case XLTT_STAGE_BIND_SUCCESS: {
208 input = "<iq type='result' id='0'>"
209 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
210 "<jid>david@my-server/test</jid></bind></iq>";
211 engine_->HandleInput(input.c_str(), input.length());
212 EXPECT_EQ("<iq type=\"set\" id=\"1\">"
213 "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
214 handler_->OutputActivity());
215 EXPECT_EQ("", handler_->StanzaActivity());
216 EXPECT_EQ("", handler_->SessionActivity());
217 if (endstage == XLTT_STAGE_BIND_SUCCESS)
221 case XLTT_STAGE_SESSION_SUCCESS: {
222 input = "<iq type='result' id='1'/>";
223 engine_->HandleInput(input.c_str(), input.length());
224 EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
225 "</test:app-stanza>", handler_->OutputActivity());
226 EXPECT_EQ("[OPEN]", handler_->SessionActivity());
227 EXPECT_EQ("", handler_->StanzaActivity());
228 if (endstage == XLTT_STAGE_SESSION_SUCCESS)
234 TEST_F(XmppLoginTaskTest, TestUtf8Good) {
235 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
237 std::string input = "<?xml version='1.0' encoding='UTF-8'?>"
238 "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
239 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
240 "xmlns=\"jabber:client\">";
241 engine()->HandleInput(input.c_str(), input.length());
242 EXPECT_EQ("", handler()->OutputActivity());
243 EXPECT_EQ("", handler()->SessionActivity());
244 EXPECT_EQ("", handler()->StanzaActivity());
247 TEST_F(XmppLoginTaskTest, TestNonUtf8Bad) {
248 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
250 std::string input = "<?xml version='1.0' encoding='ISO-8859-1'?>"
251 "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
252 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
253 "xmlns=\"jabber:client\">";
254 engine()->HandleInput(input.c_str(), input.length());
255 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
256 EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
257 EXPECT_EQ("", handler()->StanzaActivity());
260 TEST_F(XmppLoginTaskTest, TestNoFeatures) {
261 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
263 std::string input = "<iq type='get' id='1'/>";
264 engine()->HandleInput(input.c_str(), input.length());
266 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
267 EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
268 EXPECT_EQ("", handler()->StanzaActivity());
271 TEST_F(XmppLoginTaskTest, TestTlsRequiredNotPresent) {
272 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
274 std::string input = "<stream:features>"
275 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
276 "<mechanism>DIGEST-MD5</mechanism>"
277 "<mechanism>PLAIN</mechanism>"
279 "</stream:features>";
280 engine()->HandleInput(input.c_str(), input.length());
282 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
283 EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
284 EXPECT_EQ("", handler()->StanzaActivity());
287 TEST_F(XmppLoginTaskTest, TestTlsRequeiredAndPresent) {
288 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
290 std::string input = "<stream:features>"
291 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
294 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
295 "<mechanism>X-GOOGLE-TOKEN</mechanism>"
296 "<mechanism>PLAIN</mechanism>"
297 "<mechanism>X-OAUTH2</mechanism>"
299 "</stream:features>";
300 engine()->HandleInput(input.c_str(), input.length());
302 EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
303 handler()->OutputActivity());
304 EXPECT_EQ("", handler()->SessionActivity());
305 EXPECT_EQ("", handler()->StanzaActivity());
308 TEST_F(XmppLoginTaskTest, TestTlsEnabledNotPresent) {
309 SetTlsOptions(buzz::TLS_ENABLED);
310 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
312 std::string input = "<stream:features>"
313 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
314 "<mechanism>DIGEST-MD5</mechanism>"
315 "<mechanism>PLAIN</mechanism>"
317 "</stream:features>";
318 engine()->HandleInput(input.c_str(), input.length());
320 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
321 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
322 "auth:client-uses-full-bind-result=\"true\" "
323 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
324 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
325 EXPECT_EQ("", handler()->SessionActivity());
326 EXPECT_EQ("", handler()->StanzaActivity());
329 TEST_F(XmppLoginTaskTest, TestTlsEnabledAndPresent) {
330 SetTlsOptions(buzz::TLS_ENABLED);
331 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
333 std::string input = "<stream:features>"
334 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
335 "<mechanism>X-GOOGLE-TOKEN</mechanism>"
336 "<mechanism>PLAIN</mechanism>"
337 "<mechanism>X-OAUTH2</mechanism>"
339 "</stream:features>";
340 engine()->HandleInput(input.c_str(), input.length());
342 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
343 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
344 "auth:client-uses-full-bind-result=\"true\" "
345 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
346 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
347 EXPECT_EQ("", handler()->SessionActivity());
348 EXPECT_EQ("", handler()->StanzaActivity());
351 TEST_F(XmppLoginTaskTest, TestTlsDisabledNotPresent) {
352 SetTlsOptions(buzz::TLS_DISABLED);
353 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
355 std::string input = "<stream:features>"
356 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
357 "<mechanism>DIGEST-MD5</mechanism>"
358 "<mechanism>PLAIN</mechanism>"
360 "</stream:features>";
361 engine()->HandleInput(input.c_str(), input.length());
363 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
364 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
365 "auth:client-uses-full-bind-result=\"true\" "
366 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
367 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
368 EXPECT_EQ("", handler()->SessionActivity());
369 EXPECT_EQ("", handler()->StanzaActivity());
372 TEST_F(XmppLoginTaskTest, TestTlsDisabledAndPresent) {
373 SetTlsOptions(buzz::TLS_DISABLED);
374 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
376 std::string input = "<stream:features>"
377 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
378 "<mechanism>X-GOOGLE-TOKEN</mechanism>"
379 "<mechanism>PLAIN</mechanism>"
380 "<mechanism>X-OAUTH2</mechanism>"
382 "</stream:features>";
383 engine()->HandleInput(input.c_str(), input.length());
385 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
386 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
387 "auth:client-uses-full-bind-result=\"true\" "
388 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
389 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
390 EXPECT_EQ("", handler()->SessionActivity());
391 EXPECT_EQ("", handler()->StanzaActivity());
394 TEST_F(XmppLoginTaskTest, TestTlsFailure) {
395 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_FEATURES);
397 std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
398 engine()->HandleInput(input.c_str(), input.length());
400 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
401 EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
402 EXPECT_EQ("", handler()->StanzaActivity());
405 TEST_F(XmppLoginTaskTest, TestTlsBadStream) {
406 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_PROCEED);
408 std::string input = "<wrongtag>";
409 engine()->HandleInput(input.c_str(), input.length());
411 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
412 EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
413 EXPECT_EQ("", handler()->StanzaActivity());
416 TEST_F(XmppLoginTaskTest, TestMissingSaslPlain) {
417 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_ENCRYPTED_START);
419 std::string input = "<stream:features>"
420 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
421 "<mechanism>DIGEST-MD5</mechanism>"
423 "</stream:features>";
424 engine()->HandleInput(input.c_str(), input.length());
426 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
427 EXPECT_EQ("[CLOSED][ERROR-AUTH]", handler()->SessionActivity());
428 EXPECT_EQ("", handler()->StanzaActivity());
431 TEST_F(XmppLoginTaskTest, TestWrongPassword) {
432 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_FEATURES);
434 std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
435 engine()->HandleInput(input.c_str(), input.length());
437 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
438 EXPECT_EQ("[CLOSED][ERROR-UNAUTHORIZED]", handler()->SessionActivity());
439 EXPECT_EQ("", handler()->StanzaActivity());
442 TEST_F(XmppLoginTaskTest, TestAuthBadStream) {
443 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_SUCCESS);
445 std::string input = "<wrongtag>";
446 engine()->HandleInput(input.c_str(), input.length());
448 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
449 EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
450 EXPECT_EQ("", handler()->StanzaActivity());
453 TEST_F(XmppLoginTaskTest, TestMissingBindFeature) {
454 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
456 std::string input = "<stream:features>"
457 "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
458 "</stream:features>";
459 engine()->HandleInput(input.c_str(), input.length());
461 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
462 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
465 TEST_F(XmppLoginTaskTest, TestMissingSessionFeature) {
466 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
468 std::string input = "<stream:features>"
469 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
470 "</stream:features>";
471 engine()->HandleInput(input.c_str(), input.length());
473 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
474 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
475 EXPECT_EQ("", handler()->StanzaActivity());
478 /* TODO: Handle this case properly inside XmppLoginTask.
479 TEST_F(XmppLoginTaskTest, TestBindFailure1) {
481 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
483 std::string input = "<iq type='result' id='0'>"
484 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
485 "<jid>davey@my-server/test</jid></bind></iq>";
486 engine()->HandleInput(input.c_str(), input.length());
488 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
489 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
490 EXPECT_EQ("", handler()->StanzaActivity());
494 TEST_F(XmppLoginTaskTest, TestBindFailure2) {
496 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
498 std::string input = "<iq type='result' id='0'>"
499 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>";
500 engine()->HandleInput(input.c_str(), input.length());
502 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
503 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
504 EXPECT_EQ("", handler()->StanzaActivity());
507 TEST_F(XmppLoginTaskTest, TestBindFailure3) {
508 // check plain failure
509 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
511 std::string input = "<iq type='error' id='0'/>";
512 engine()->HandleInput(input.c_str(), input.length());
514 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
515 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
516 EXPECT_EQ("", handler()->StanzaActivity());
519 TEST_F(XmppLoginTaskTest, TestBindFailure4) {
520 // check wrong id to ignore
521 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
523 std::string input = "<iq type='error' id='1'/>";
524 engine()->HandleInput(input.c_str(), input.length());
526 // continue after an ignored iq
527 RunPartialLogin(XLTT_STAGE_BIND_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
530 TEST_F(XmppLoginTaskTest, TestSessionFailurePlain1) {
531 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
533 std::string input = "<iq type='error' id='1'/>";
534 engine()->HandleInput(input.c_str(), input.length());
536 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
537 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
540 TEST_F(XmppLoginTaskTest, TestSessionFailurePlain2) {
541 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
543 // check reverse iq to ignore
544 // TODO: consider queueing or passing through?
545 std::string input = "<iq type='get' id='1'/>";
546 engine()->HandleInput(input.c_str(), input.length());
548 EXPECT_EQ("", handler()->OutputActivity());
549 EXPECT_EQ("", handler()->SessionActivity());
551 // continue after an ignored iq
552 RunPartialLogin(XLTT_STAGE_SESSION_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
555 TEST_F(XmppLoginTaskTest, TestBadXml) {
557 for (XlttStage stage = XLTT_STAGE_CONNECT;
558 stage <= XLTT_STAGE_SESSION_SUCCESS;
559 stage = static_cast<XlttStage>(stage + 1)) {
560 RunPartialLogin(XLTT_STAGE_CONNECT, stage);
563 switch (errorKind++ % 5) {
564 case 0: input = "&syntax;"; break;
565 case 1: input = "<nons:iq/>"; break;
566 case 2: input = "<iq a='b' a='dupe'/>"; break;
567 case 3: input = "<>"; break;
568 case 4: input = "<iq a='<wrong>'>"; break;
571 engine()->HandleInput(input.c_str(), input.length());
573 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
574 EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
581 TEST_F(XmppLoginTaskTest, TestStreamError) {
582 for (XlttStage stage = XLTT_STAGE_CONNECT;
583 stage <= XLTT_STAGE_SESSION_SUCCESS;
584 stage = static_cast<XlttStage>(stage + 1)) {
586 case XLTT_STAGE_CONNECT:
587 case XLTT_STAGE_TLS_PROCEED:
588 case XLTT_STAGE_AUTH_SUCCESS:
594 RunPartialLogin(XLTT_STAGE_CONNECT, stage);
596 std::string input = "<stream:error>"
597 "<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>"
598 "<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>"
599 "Some special application diagnostic information!"
601 "<escape-your-data xmlns='application-ns'/>"
604 engine()->HandleInput(input.c_str(), input.length());
606 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
607 EXPECT_EQ("[CLOSED][ERROR-STREAM]", handler()->SessionActivity());
609 EXPECT_EQ("<str:error xmlns:str=\"http://etherx.jabber.org/streams\">"
610 "<xml-not-well-formed xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\"/>"
611 "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\">"
612 "Some special application diagnostic information!"
614 "<escape-your-data xmlns=\"application-ns\"/>"
615 "</str:error>", engine()->GetStreamError()->Str());