nonsaslauth.cpp

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 }
Generated on Tue Jun 8 23:37:54 2010 for gloox by  doxygen 1.6.3