nonsaslauth.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00084
00085
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 }