gloox  1.0
nonsaslauth.cpp
1 /*
2  Copyright (c) 2005-2009 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 "error.h"
17 #include "sha.h"
18 
19 #include <string>
20 
21 namespace gloox
22 {
23 
24  // ---- NonSaslAuth::Query ----
25  NonSaslAuth::Query::Query( const std::string& user )
26  : StanzaExtension( ExtNonSaslAuth ), m_user( user ), m_digest( true )
27  {
28  }
29 
30  NonSaslAuth::Query::Query( const Tag* tag )
31  : StanzaExtension( ExtNonSaslAuth )
32  {
33  if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_AUTH )
34  return;
35 
36  m_digest = tag->hasChild( "digest" );
37  }
38 
39  NonSaslAuth::Query* NonSaslAuth::Query::newInstance( const std::string& user,
40  const std::string& sid,
41  const std::string& pwd,
42  const std::string& resource ) const
43  {
44  Query* q = new Query( user );
45  if( m_digest && !sid.empty() )
46  {
47  SHA sha;
48  sha.feed( sid );
49  sha.feed( pwd );
50  q->m_pwd = sha.hex();
51  }
52  else
53  q->m_pwd = pwd;
54 
55  q->m_resource = resource;
56  q->m_digest = m_digest;
57  return q;
58  }
59 
60  const std::string& NonSaslAuth::Query::filterString() const
61  {
62  static const std::string filter = "/iq/query[@xmlns='" + XMLNS_AUTH + "']";
63  return filter;
64  }
65 
66  Tag* NonSaslAuth::Query::tag() const
67  {
68  if( m_user.empty() )
69  return 0;
70 
71  Tag* t = new Tag( "query" );
72  t->setXmlns( XMLNS_AUTH );
73  new Tag( t, "username", m_user );
74 
75  if( !m_pwd.empty() && !m_resource.empty() )
76  {
77  new Tag( t, m_digest ? "digest" : "password", m_pwd );
78  new Tag( t, "resource", m_resource );
79  }
80 
81  return t;
82  }
83  // ---- ~NonSaslAuth::Query ----
84 
85  // ---- NonSaslAuth ----
87  : m_parent( parent )
88  {
89  if( m_parent )
90  {
91  m_parent->registerStanzaExtension( new Query() );
92  m_parent->registerIqHandler( this, ExtNonSaslAuth );
93  }
94  }
95 
97  {
98  if( m_parent )
99  {
101  m_parent->removeIqHandler( this, ExtNonSaslAuth );
102  m_parent->removeIDHandler( this );
103  }
104  }
105 
106  void NonSaslAuth::doAuth( const std::string& sid )
107  {
108  m_sid = sid;
109  const std::string& id = m_parent->getID();
110 
111  IQ iq( IQ::Get, m_parent->jid().server(), id );
112  iq.addExtension( new Query( m_parent->username() ) );
113  m_parent->send( iq, this, TrackRequestAuthFields );
114  }
115 
116  void NonSaslAuth::handleIqID( const IQ& iq, int context )
117  {
118  switch( iq.subtype() )
119  {
120  case IQ::Error:
121  {
122  const Error* e = iq.error();
123  if( e )
124  {
125  switch( e->error() )
126  {
127  case StanzaErrorConflict:
128  m_parent->setAuthFailure( NonSaslConflict );
129  break;
132  break;
135  break;
136  default:
137  break;
138  }
139  }
140  m_parent->setAuthed( false );
142  break;
143  }
144  case IQ::Result:
145  switch( context )
146  {
147  case TrackRequestAuthFields:
148  {
149  const Query* q = iq.findExtension<Query>( ExtNonSaslAuth );
150  if( !q )
151  return;
152 
153  const std::string& id = m_parent->getID();
154 
155  IQ re( IQ::Set, JID(), id );
156  re.addExtension( q->newInstance( m_parent->username(), m_sid,
157  m_parent->password(),
158  m_parent->jid().resource() ) );
159  m_parent->send( re, this, TrackSendAuth );
160  break;
161  }
162  case TrackSendAuth:
163  m_parent->setAuthed( true );
164  m_parent->connected();
165  break;
166  }
167  break;
168 
169  default:
170  break;
171  }
172  }
173 
174 }