gloox  0.9.9.12
nonsaslauth.cpp
1 /*
2  Copyright (c) 2005-2008 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 #include "nonsaslauth.h"
15 #include "client.h"
16 #include "sha.h"
17 
18 #include <string>
19 
20 namespace gloox
21 {
22 
24  : m_parent( parent )
25  {
26  if( m_parent )
27  m_parent->registerIqHandler( this, XMLNS_AUTH );
28  }
29 
31  {
32  if( m_parent )
33  {
34  m_parent->removeIqHandler( XMLNS_AUTH );
35  m_parent->removeIDHandler( this );
36  }
37  }
38 
39  void NonSaslAuth::doAuth( const std::string& sid )
40  {
41  m_sid = sid;
42  const std::string& id = m_parent->getID();
43 
44  Tag *iq = new Tag( "iq" );
45  iq->addAttribute( "to", m_parent->jid().server() );
46  iq->addAttribute( "id", id );
47  iq->addAttribute( "type", "get" );
48  Tag *q = new Tag( iq, "query" );
49  q->addAttribute( "xmlns", XMLNS_AUTH );
50  new Tag( q, "username", m_parent->username() );
51 
52  m_parent->trackID( this, id, TRACK_REQUEST_AUTH_FIELDS );
53  m_parent->send( iq );
54  }
55 
56  bool NonSaslAuth::handleIqID( Stanza *stanza, int context )
57  {
58  switch( stanza->subtype() )
59  {
60  case StanzaIqError:
61  {
62  m_parent->setAuthed( false );
64 
65  Tag *t = stanza->findChild( "error" );
66  if( t )
67  {
68  if( t->hasChild( "conflict" ) || t->hasAttribute( "code", "409" ) )
69  m_parent->setAuthFailure( NonSaslConflict );
70  else if( t->hasChild( "not-acceptable" ) || t->hasAttribute( "code", "406" ) )
71  m_parent->setAuthFailure( NonSaslNotAcceptable );
72  else if( t->hasChild( "not-authorized" ) || t->hasAttribute( "code", "401" ) )
73  m_parent->setAuthFailure( NonSaslNotAuthorized );
74  }
75  break;
76  }
77  case StanzaIqResult:
78  switch( context )
79  {
80  case TRACK_REQUEST_AUTH_FIELDS:
81  {
82  const std::string& id = m_parent->getID();
83 
84  Tag *iq = new Tag( "iq" );
85  iq->addAttribute( "id", id );
86  iq->addAttribute( "type", "set" );
87  Tag *query = new Tag( iq, "query" );
88  query->addAttribute( "xmlns", XMLNS_AUTH );
89  new Tag( query, "username", m_parent->jid().username() );
90  new Tag( query, "resource", m_parent->jid().resource() );
91 
92  Tag *q = stanza->findChild( "query" );
93  if( ( q->hasChild( "digest" ) ) && !m_sid.empty() )
94  {
95  SHA sha;
96  sha.feed( m_sid );
97  sha.feed( m_parent->password() );
98  sha.finalize();
99  new Tag( query, "digest", sha.hex() );
100  }
101  else
102  {
103  new Tag( query, "password", m_parent->password() );
104  }
105 
106  m_parent->trackID( this, id, TRACK_SEND_AUTH );
107  m_parent->send( iq );
108  break;
109  }
110  case TRACK_SEND_AUTH:
111  m_parent->setAuthed( true );
112  m_parent->connected();
113  break;
114  }
115  break;
116 
117  default:
118  break;
119  }
120  return false;
121  }
122 
123  bool NonSaslAuth::handleIq( Stanza * /*stanza*/ )
124  {
125  return false;
126  }
127 
128 }