gloox
1.0
|
00001 /* 00002 Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net> 00003 This file is part of the gloox library. http://camaya.net/gloox 00004 00005 This software is distributed under a license. The full license 00006 agreement can be found in the file LICENSE in this distribution. 00007 This software may not be copied, modified, sold or distributed 00008 other than expressed in the named license agreement. 00009 00010 This software is distributed without any warranty. 00011 */ 00012 00013 00014 #include "nonsaslauth.h" 00015 #include "client.h" 00016 #include "error.h" 00017 #include "sha.h" 00018 00019 #include <string> 00020 00021 namespace gloox 00022 { 00023 00024 // ---- NonSaslAuth::Query ---- 00025 NonSaslAuth::Query::Query( const std::string& user ) 00026 : StanzaExtension( ExtNonSaslAuth ), m_user( user ), m_digest( true ) 00027 { 00028 } 00029 00030 NonSaslAuth::Query::Query( const Tag* tag ) 00031 : StanzaExtension( ExtNonSaslAuth ) 00032 { 00033 if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_AUTH ) 00034 return; 00035 00036 m_digest = tag->hasChild( "digest" ); 00037 } 00038 00039 NonSaslAuth::Query* NonSaslAuth::Query::newInstance( const std::string& user, 00040 const std::string& sid, 00041 const std::string& pwd, 00042 const std::string& resource ) const 00043 { 00044 Query* q = new Query( user ); 00045 if( m_digest && !sid.empty() ) 00046 { 00047 SHA sha; 00048 sha.feed( sid ); 00049 sha.feed( pwd ); 00050 q->m_pwd = sha.hex(); 00051 } 00052 else 00053 q->m_pwd = pwd; 00054 00055 q->m_resource = resource; 00056 q->m_digest = m_digest; 00057 return q; 00058 } 00059 00060 const std::string& NonSaslAuth::Query::filterString() const 00061 { 00062 static const std::string filter = "/iq/query[@xmlns='" + XMLNS_AUTH + "']"; 00063 return filter; 00064 } 00065 00066 Tag* NonSaslAuth::Query::tag() const 00067 { 00068 if( m_user.empty() ) 00069 return 0; 00070 00071 Tag* t = new Tag( "query" ); 00072 t->setXmlns( XMLNS_AUTH ); 00073 new Tag( t, "username", m_user ); 00074 00075 if( !m_pwd.empty() && !m_resource.empty() ) 00076 { 00077 new Tag( t, m_digest ? "digest" : "password", m_pwd ); 00078 new Tag( t, "resource", m_resource ); 00079 } 00080 00081 return t; 00082 } 00083 // ---- ~NonSaslAuth::Query ---- 00084 00085 // ---- NonSaslAuth ---- 00086 NonSaslAuth::NonSaslAuth( Client* parent ) 00087 : m_parent( parent ) 00088 { 00089 if( m_parent ) 00090 { 00091 m_parent->registerStanzaExtension( new Query() ); 00092 m_parent->registerIqHandler( this, ExtNonSaslAuth ); 00093 } 00094 } 00095 00096 NonSaslAuth::~NonSaslAuth() 00097 { 00098 if( m_parent ) 00099 { 00100 m_parent->removeStanzaExtension( ExtNonSaslAuth ); 00101 m_parent->removeIqHandler( this, ExtNonSaslAuth ); 00102 m_parent->removeIDHandler( this ); 00103 } 00104 } 00105 00106 void NonSaslAuth::doAuth( const std::string& sid ) 00107 { 00108 m_sid = sid; 00109 const std::string& id = m_parent->getID(); 00110 00111 IQ iq( IQ::Get, m_parent->jid().server(), id ); 00112 iq.addExtension( new Query( m_parent->username() ) ); 00113 m_parent->send( iq, this, TrackRequestAuthFields ); 00114 } 00115 00116 void NonSaslAuth::handleIqID( const IQ& iq, int context ) 00117 { 00118 switch( iq.subtype() ) 00119 { 00120 case IQ::Error: 00121 { 00122 const Error* e = iq.error(); 00123 if( e ) 00124 { 00125 switch( e->error() ) 00126 { 00127 case StanzaErrorConflict: 00128 m_parent->setAuthFailure( NonSaslConflict ); 00129 break; 00130 case StanzaErrorNotAcceptable: 00131 m_parent->setAuthFailure( NonSaslNotAcceptable ); 00132 break; 00133 case StanzaErrorNotAuthorized: 00134 m_parent->setAuthFailure( NonSaslNotAuthorized ); 00135 break; 00136 default: 00137 break; 00138 } 00139 } 00140 m_parent->setAuthed( false ); 00141 m_parent->disconnect( ConnAuthenticationFailed ); 00142 break; 00143 } 00144 case IQ::Result: 00145 switch( context ) 00146 { 00147 case TrackRequestAuthFields: 00148 { 00149 const Query* q = iq.findExtension<Query>( ExtNonSaslAuth ); 00150 if( !q ) 00151 return; 00152 00153 const std::string& id = m_parent->getID(); 00154 00155 IQ re( IQ::Set, JID(), id ); 00156 re.addExtension( q->newInstance( m_parent->username(), m_sid, 00157 m_parent->password(), 00158 m_parent->jid().resource() ) ); 00159 m_parent->send( re, this, TrackSendAuth ); 00160 break; 00161 } 00162 case TrackSendAuth: 00163 m_parent->setAuthed( true ); 00164 m_parent->connected(); 00165 break; 00166 } 00167 break; 00168 00169 default: 00170 break; 00171 } 00172 } 00173 00174 }