1 // Copyright 2004 Google Inc. All Rights Reserved
7 #include "webrtc/libjingle/xmllite/xmlelement.h"
8 #include "webrtc/libjingle/xmpp/constants.h"
9 #include "webrtc/libjingle/xmpp/plainsaslhandler.h"
10 #include "webrtc/libjingle/xmpp/saslplainmechanism.h"
11 #include "webrtc/libjingle/xmpp/util_unittest.h"
12 #include "webrtc/libjingle/xmpp/xmppengine.h"
13 #include "webrtc/base/common.h"
14 #include "webrtc/base/cryptstring.h"
15 #include "webrtc/base/gunit.h"
19 using buzz::XmlElement;
20 using buzz::XmppEngine;
21 using buzz::XmppTestHandler;
24 XLTT_STAGE_CONNECT = 0,
25 XLTT_STAGE_STREAMSTART,
26 XLTT_STAGE_TLS_FEATURES,
27 XLTT_STAGE_TLS_PROCEED,
28 XLTT_STAGE_ENCRYPTED_START,
29 XLTT_STAGE_AUTH_FEATURES,
30 XLTT_STAGE_AUTH_SUCCESS,
31 XLTT_STAGE_AUTHENTICATED_START,
32 XLTT_STAGE_BIND_FEATURES,
33 XLTT_STAGE_BIND_SUCCESS,
34 XLTT_STAGE_SESSION_SUCCESS,
37 class XmppLoginTaskTest : public testing::Test {
39 XmppEngine* engine() { return engine_.get(); }
40 XmppTestHandler* handler() { return handler_.get(); }
41 virtual void SetUp() {
42 engine_.reset(XmppEngine::Create());
43 handler_.reset(new XmppTestHandler(engine_.get()));
45 Jid jid("david@my-server");
46 rtc::InsecureCryptStringImpl pass;
47 pass.password() = "david";
48 engine_->SetSessionHandler(handler_.get());
49 engine_->SetOutputHandler(handler_.get());
50 engine_->AddStanzaHandler(handler_.get());
51 engine_->SetUser(jid);
52 engine_->SetSaslHandler(
53 new buzz::PlainSaslHandler(jid, rtc::CryptString(pass), true));
55 virtual void TearDown() {
59 void RunPartialLogin(XlttStage startstage, XlttStage endstage);
60 void SetTlsOptions(buzz::TlsOptions option);
63 rtc::scoped_ptr<XmppEngine> engine_;
64 rtc::scoped_ptr<XmppTestHandler> handler_;
67 void XmppLoginTaskTest::SetTlsOptions(buzz::TlsOptions option) {
68 engine_->SetTls(option);
70 void XmppLoginTaskTest::RunPartialLogin(XlttStage startstage,
75 case XLTT_STAGE_CONNECT: {
77 XmlElement appStanza(QName("test", "app-stanza"));
78 appStanza.AddText("this-is-a-test");
79 engine_->SendStanza(&appStanza);
81 EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
82 "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
83 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
84 EXPECT_EQ("[OPENING]", handler_->SessionActivity());
85 EXPECT_EQ("", handler_->StanzaActivity());
86 if (endstage == XLTT_STAGE_CONNECT)
90 case XLTT_STAGE_STREAMSTART: {
91 input = "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
92 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
93 "xmlns=\"jabber:client\">";
94 engine_->HandleInput(input.c_str(), input.length());
95 EXPECT_EQ("", handler_->StanzaActivity());
96 EXPECT_EQ("", handler_->SessionActivity());
97 EXPECT_EQ("", handler_->OutputActivity());
98 if (endstage == XLTT_STAGE_STREAMSTART)
102 case XLTT_STAGE_TLS_FEATURES: {
103 input = "<stream:features>"
104 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
105 "</stream:features>";
106 engine_->HandleInput(input.c_str(), input.length());
107 EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
108 handler_->OutputActivity());
109 EXPECT_EQ("", handler_->StanzaActivity());
110 EXPECT_EQ("", handler_->SessionActivity());
111 if (endstage == XLTT_STAGE_TLS_FEATURES)
115 case XLTT_STAGE_TLS_PROCEED: {
116 input = std::string("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
117 engine_->HandleInput(input.c_str(), input.length());
118 EXPECT_EQ("[START-TLS my-server]"
119 "<stream:stream to=\"my-server\" xml:lang=\"*\" "
120 "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
121 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
122 EXPECT_EQ("", handler_->StanzaActivity());
123 EXPECT_EQ("", handler_->SessionActivity());
124 if (endstage == XLTT_STAGE_TLS_PROCEED)
128 case XLTT_STAGE_ENCRYPTED_START: {
129 input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
130 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
131 "xmlns=\"jabber:client\">");
132 engine_->HandleInput(input.c_str(), input.length());
133 EXPECT_EQ("", handler_->StanzaActivity());
134 EXPECT_EQ("", handler_->SessionActivity());
135 EXPECT_EQ("", handler_->OutputActivity());
136 if (endstage == XLTT_STAGE_ENCRYPTED_START)
140 case XLTT_STAGE_AUTH_FEATURES: {
141 input = "<stream:features>"
142 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
143 "<mechanism>DIGEST-MD5</mechanism>"
144 "<mechanism>PLAIN</mechanism>"
146 "</stream:features>";
147 engine_->HandleInput(input.c_str(), input.length());
148 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
149 "mechanism=\"PLAIN\" "
150 "auth:allow-non-google-login=\"true\" "
151 "auth:client-uses-full-bind-result=\"true\" "
152 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
153 ">AGRhdmlkAGRhdmlk</auth>",
154 handler_->OutputActivity());
155 EXPECT_EQ("", handler_->StanzaActivity());
156 EXPECT_EQ("", handler_->SessionActivity());
157 if (endstage == XLTT_STAGE_AUTH_FEATURES)
161 case XLTT_STAGE_AUTH_SUCCESS: {
162 input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
163 engine_->HandleInput(input.c_str(), input.length());
164 EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
165 "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
166 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
167 EXPECT_EQ("", handler_->StanzaActivity());
168 EXPECT_EQ("", handler_->SessionActivity());
169 if (endstage == XLTT_STAGE_AUTH_SUCCESS)
173 case XLTT_STAGE_AUTHENTICATED_START: {
174 input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
175 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
176 "xmlns=\"jabber:client\">");
177 engine_->HandleInput(input.c_str(), input.length());
178 EXPECT_EQ("", handler_->StanzaActivity());
179 EXPECT_EQ("", handler_->SessionActivity());
180 EXPECT_EQ("", handler_->OutputActivity());
181 if (endstage == XLTT_STAGE_AUTHENTICATED_START)
185 case XLTT_STAGE_BIND_FEATURES: {
186 input = "<stream:features>"
187 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
188 "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
189 "</stream:features>";
190 engine_->HandleInput(input.c_str(), input.length());
191 EXPECT_EQ("<iq type=\"set\" id=\"0\">"
192 "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
193 handler_->OutputActivity());
194 EXPECT_EQ("", handler_->StanzaActivity());
195 EXPECT_EQ("", handler_->SessionActivity());
196 if (endstage == XLTT_STAGE_BIND_FEATURES)
200 case XLTT_STAGE_BIND_SUCCESS: {
201 input = "<iq type='result' id='0'>"
202 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
203 "<jid>david@my-server/test</jid></bind></iq>";
204 engine_->HandleInput(input.c_str(), input.length());
205 EXPECT_EQ("<iq type=\"set\" id=\"1\">"
206 "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
207 handler_->OutputActivity());
208 EXPECT_EQ("", handler_->StanzaActivity());
209 EXPECT_EQ("", handler_->SessionActivity());
210 if (endstage == XLTT_STAGE_BIND_SUCCESS)
214 case XLTT_STAGE_SESSION_SUCCESS: {
215 input = "<iq type='result' id='1'/>";
216 engine_->HandleInput(input.c_str(), input.length());
217 EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
218 "</test:app-stanza>", handler_->OutputActivity());
219 EXPECT_EQ("[OPEN]", handler_->SessionActivity());
220 EXPECT_EQ("", handler_->StanzaActivity());
221 if (endstage == XLTT_STAGE_SESSION_SUCCESS)
227 TEST_F(XmppLoginTaskTest, TestUtf8Good) {
228 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
230 std::string input = "<?xml version='1.0' encoding='UTF-8'?>"
231 "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
232 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
233 "xmlns=\"jabber:client\">";
234 engine()->HandleInput(input.c_str(), input.length());
235 EXPECT_EQ("", handler()->OutputActivity());
236 EXPECT_EQ("", handler()->SessionActivity());
237 EXPECT_EQ("", handler()->StanzaActivity());
240 TEST_F(XmppLoginTaskTest, TestNonUtf8Bad) {
241 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
243 std::string input = "<?xml version='1.0' encoding='ISO-8859-1'?>"
244 "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
245 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
246 "xmlns=\"jabber:client\">";
247 engine()->HandleInput(input.c_str(), input.length());
248 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
249 EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
250 EXPECT_EQ("", handler()->StanzaActivity());
253 TEST_F(XmppLoginTaskTest, TestNoFeatures) {
254 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
256 std::string input = "<iq type='get' id='1'/>";
257 engine()->HandleInput(input.c_str(), input.length());
259 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
260 EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
261 EXPECT_EQ("", handler()->StanzaActivity());
264 TEST_F(XmppLoginTaskTest, TestTlsRequiredNotPresent) {
265 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
267 std::string input = "<stream:features>"
268 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
269 "<mechanism>DIGEST-MD5</mechanism>"
270 "<mechanism>PLAIN</mechanism>"
272 "</stream:features>";
273 engine()->HandleInput(input.c_str(), input.length());
275 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
276 EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
277 EXPECT_EQ("", handler()->StanzaActivity());
280 TEST_F(XmppLoginTaskTest, TestTlsRequeiredAndPresent) {
281 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
283 std::string input = "<stream:features>"
284 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
287 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
288 "<mechanism>X-GOOGLE-TOKEN</mechanism>"
289 "<mechanism>PLAIN</mechanism>"
290 "<mechanism>X-OAUTH2</mechanism>"
292 "</stream:features>";
293 engine()->HandleInput(input.c_str(), input.length());
295 EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
296 handler()->OutputActivity());
297 EXPECT_EQ("", handler()->SessionActivity());
298 EXPECT_EQ("", handler()->StanzaActivity());
301 TEST_F(XmppLoginTaskTest, TestTlsEnabledNotPresent) {
302 SetTlsOptions(buzz::TLS_ENABLED);
303 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
305 std::string input = "<stream:features>"
306 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
307 "<mechanism>DIGEST-MD5</mechanism>"
308 "<mechanism>PLAIN</mechanism>"
310 "</stream:features>";
311 engine()->HandleInput(input.c_str(), input.length());
313 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
314 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
315 "auth:client-uses-full-bind-result=\"true\" "
316 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
317 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
318 EXPECT_EQ("", handler()->SessionActivity());
319 EXPECT_EQ("", handler()->StanzaActivity());
322 TEST_F(XmppLoginTaskTest, TestTlsEnabledAndPresent) {
323 SetTlsOptions(buzz::TLS_ENABLED);
324 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
326 std::string input = "<stream:features>"
327 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
328 "<mechanism>X-GOOGLE-TOKEN</mechanism>"
329 "<mechanism>PLAIN</mechanism>"
330 "<mechanism>X-OAUTH2</mechanism>"
332 "</stream:features>";
333 engine()->HandleInput(input.c_str(), input.length());
335 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
336 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
337 "auth:client-uses-full-bind-result=\"true\" "
338 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
339 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
340 EXPECT_EQ("", handler()->SessionActivity());
341 EXPECT_EQ("", handler()->StanzaActivity());
344 TEST_F(XmppLoginTaskTest, TestTlsDisabledNotPresent) {
345 SetTlsOptions(buzz::TLS_DISABLED);
346 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
348 std::string input = "<stream:features>"
349 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
350 "<mechanism>DIGEST-MD5</mechanism>"
351 "<mechanism>PLAIN</mechanism>"
353 "</stream:features>";
354 engine()->HandleInput(input.c_str(), input.length());
356 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
357 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
358 "auth:client-uses-full-bind-result=\"true\" "
359 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
360 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
361 EXPECT_EQ("", handler()->SessionActivity());
362 EXPECT_EQ("", handler()->StanzaActivity());
365 TEST_F(XmppLoginTaskTest, TestTlsDisabledAndPresent) {
366 SetTlsOptions(buzz::TLS_DISABLED);
367 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
369 std::string input = "<stream:features>"
370 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
371 "<mechanism>X-GOOGLE-TOKEN</mechanism>"
372 "<mechanism>PLAIN</mechanism>"
373 "<mechanism>X-OAUTH2</mechanism>"
375 "</stream:features>";
376 engine()->HandleInput(input.c_str(), input.length());
378 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
379 "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
380 "auth:client-uses-full-bind-result=\"true\" "
381 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
382 ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
383 EXPECT_EQ("", handler()->SessionActivity());
384 EXPECT_EQ("", handler()->StanzaActivity());
387 TEST_F(XmppLoginTaskTest, TestTlsFailure) {
388 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_FEATURES);
390 std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
391 engine()->HandleInput(input.c_str(), input.length());
393 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
394 EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
395 EXPECT_EQ("", handler()->StanzaActivity());
398 TEST_F(XmppLoginTaskTest, TestTlsBadStream) {
399 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_PROCEED);
401 std::string input = "<wrongtag>";
402 engine()->HandleInput(input.c_str(), input.length());
404 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
405 EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
406 EXPECT_EQ("", handler()->StanzaActivity());
409 TEST_F(XmppLoginTaskTest, TestMissingSaslPlain) {
410 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_ENCRYPTED_START);
412 std::string input = "<stream:features>"
413 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
414 "<mechanism>DIGEST-MD5</mechanism>"
416 "</stream:features>";
417 engine()->HandleInput(input.c_str(), input.length());
419 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
420 EXPECT_EQ("[CLOSED][ERROR-AUTH]", handler()->SessionActivity());
421 EXPECT_EQ("", handler()->StanzaActivity());
424 TEST_F(XmppLoginTaskTest, TestWrongPassword) {
425 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_FEATURES);
427 std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
428 engine()->HandleInput(input.c_str(), input.length());
430 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
431 EXPECT_EQ("[CLOSED][ERROR-UNAUTHORIZED]", handler()->SessionActivity());
432 EXPECT_EQ("", handler()->StanzaActivity());
435 TEST_F(XmppLoginTaskTest, TestAuthBadStream) {
436 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_SUCCESS);
438 std::string input = "<wrongtag>";
439 engine()->HandleInput(input.c_str(), input.length());
441 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
442 EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
443 EXPECT_EQ("", handler()->StanzaActivity());
446 TEST_F(XmppLoginTaskTest, TestMissingBindFeature) {
447 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
449 std::string input = "<stream:features>"
450 "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
451 "</stream:features>";
452 engine()->HandleInput(input.c_str(), input.length());
454 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
455 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
458 TEST_F(XmppLoginTaskTest, TestMissingSessionFeature) {
459 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
461 std::string input = "<stream:features>"
462 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
463 "</stream:features>";
464 engine()->HandleInput(input.c_str(), input.length());
466 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
467 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
468 EXPECT_EQ("", handler()->StanzaActivity());
471 /* TODO: Handle this case properly inside XmppLoginTask.
472 TEST_F(XmppLoginTaskTest, TestBindFailure1) {
474 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
476 std::string input = "<iq type='result' id='0'>"
477 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
478 "<jid>davey@my-server/test</jid></bind></iq>";
479 engine()->HandleInput(input.c_str(), input.length());
481 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
482 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
483 EXPECT_EQ("", handler()->StanzaActivity());
487 TEST_F(XmppLoginTaskTest, TestBindFailure2) {
489 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
491 std::string input = "<iq type='result' id='0'>"
492 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>";
493 engine()->HandleInput(input.c_str(), input.length());
495 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
496 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
497 EXPECT_EQ("", handler()->StanzaActivity());
500 TEST_F(XmppLoginTaskTest, TestBindFailure3) {
501 // check plain failure
502 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
504 std::string input = "<iq type='error' id='0'/>";
505 engine()->HandleInput(input.c_str(), input.length());
507 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
508 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
509 EXPECT_EQ("", handler()->StanzaActivity());
512 TEST_F(XmppLoginTaskTest, TestBindFailure4) {
513 // check wrong id to ignore
514 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
516 std::string input = "<iq type='error' id='1'/>";
517 engine()->HandleInput(input.c_str(), input.length());
519 // continue after an ignored iq
520 RunPartialLogin(XLTT_STAGE_BIND_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
523 TEST_F(XmppLoginTaskTest, TestSessionFailurePlain1) {
524 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
526 std::string input = "<iq type='error' id='1'/>";
527 engine()->HandleInput(input.c_str(), input.length());
529 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
530 EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
533 TEST_F(XmppLoginTaskTest, TestSessionFailurePlain2) {
534 RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
536 // check reverse iq to ignore
537 // TODO: consider queueing or passing through?
538 std::string input = "<iq type='get' id='1'/>";
539 engine()->HandleInput(input.c_str(), input.length());
541 EXPECT_EQ("", handler()->OutputActivity());
542 EXPECT_EQ("", handler()->SessionActivity());
544 // continue after an ignored iq
545 RunPartialLogin(XLTT_STAGE_SESSION_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
548 TEST_F(XmppLoginTaskTest, TestBadXml) {
550 for (XlttStage stage = XLTT_STAGE_CONNECT;
551 stage <= XLTT_STAGE_SESSION_SUCCESS;
552 stage = static_cast<XlttStage>(stage + 1)) {
553 RunPartialLogin(XLTT_STAGE_CONNECT, stage);
556 switch (errorKind++ % 5) {
557 case 0: input = "&syntax;"; break;
558 case 1: input = "<nons:iq/>"; break;
559 case 2: input = "<iq a='b' a='dupe'/>"; break;
560 case 3: input = "<>"; break;
561 case 4: input = "<iq a='<wrong>'>"; break;
564 engine()->HandleInput(input.c_str(), input.length());
566 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
567 EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
574 TEST_F(XmppLoginTaskTest, TestStreamError) {
575 for (XlttStage stage = XLTT_STAGE_CONNECT;
576 stage <= XLTT_STAGE_SESSION_SUCCESS;
577 stage = static_cast<XlttStage>(stage + 1)) {
579 case XLTT_STAGE_CONNECT:
580 case XLTT_STAGE_TLS_PROCEED:
581 case XLTT_STAGE_AUTH_SUCCESS:
587 RunPartialLogin(XLTT_STAGE_CONNECT, stage);
589 std::string input = "<stream:error>"
590 "<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>"
591 "<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>"
592 "Some special application diagnostic information!"
594 "<escape-your-data xmlns='application-ns'/>"
597 engine()->HandleInput(input.c_str(), input.length());
599 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
600 EXPECT_EQ("[CLOSED][ERROR-STREAM]", handler()->SessionActivity());
602 EXPECT_EQ("<str:error xmlns:str=\"http://etherx.jabber.org/streams\">"
603 "<xml-not-well-formed xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\"/>"
604 "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\">"
605 "Some special application diagnostic information!"
607 "<escape-your-data xmlns=\"application-ns\"/>"
608 "</str:error>", engine()->GetStreamError()->Str());