00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "nonsaslauth.h"
00015 #include "client.h"
00016
00017 #include <string>
00018
00019 #include <iksemel.h>
00020
00021 namespace gloox
00022 {
00023
00024 NonSaslAuth::NonSaslAuth( Client *parent )
00025 : m_parent( parent )
00026 {
00027 if( m_parent )
00028 m_parent->registerIqHandler( this, XMLNS_AUTH );
00029 }
00030
00031 NonSaslAuth::~NonSaslAuth()
00032 {
00033 if( m_parent )
00034 m_parent->removeIqHandler( XMLNS_AUTH );
00035 }
00036
00037 void NonSaslAuth::doAuth( const std::string& sid )
00038 {
00039 m_sid = sid;
00040 std::string id = m_parent->getID();
00041
00042 Tag *iq = new Tag( "iq" );
00043 iq->addAttribute( "to", m_parent->jid().server() );
00044 iq->addAttribute( "id", id );
00045 iq->addAttribute( "type", "get" );
00046 Tag *q = new Tag( iq, "query" );
00047 q->addAttribute( "xmlns", XMLNS_AUTH );
00048 new Tag( q, "username", m_parent->username() );
00049
00050 m_parent->trackID( this, id, TRACK_REQUEST_AUTH_FIELDS );
00051 m_parent->send( iq );
00052 }
00053
00054 bool NonSaslAuth::handleIqID( Stanza *stanza, int context )
00055 {
00056 switch( stanza->subtype() )
00057 {
00058 case StanzaIqError:
00059 {
00060 m_parent->setAuthed( false );
00061 m_parent->disconnect( ConnAuthenticationFailed );
00062
00063 Tag *t = stanza->findChild( "error" );
00064 if( t )
00065 {
00066 if( t->hasChild( "conflict" ) || t->hasAttribute( "code", "409" ) )
00067 m_parent->setAuthFailure( NonSaslConflict );
00068 else if( t->hasChild( "not-acceptable" ) || t->hasAttribute( "code", "406" ) )
00069 m_parent->setAuthFailure( NonSaslNotAcceptable );
00070 else if( t->hasChild( "not-authorized" ) || t->hasAttribute( "code", "401" ) )
00071 m_parent->setAuthFailure( NonSaslNotAuthorized );
00072 }
00073 break;
00074 }
00075 case StanzaIqResult:
00076 switch( context )
00077 {
00078 case TRACK_REQUEST_AUTH_FIELDS:
00079 {
00080 std::string id = m_parent->getID();
00081
00082 Tag *iq = new Tag( "iq" );
00083 iq->addAttribute( "id", id );
00084 iq->addAttribute( "type", "set" );
00085 Tag *query = new Tag( iq, "query" );
00086 query->addAttribute( "xmlns", XMLNS_AUTH );
00087 new Tag( query, "username", m_parent->jid().username() );
00088 new Tag( query, "resource", m_parent->jid().resource() );
00089
00090 Tag *q = stanza->findChild( "query" );
00091 if( ( q->hasChild( "digest" ) ) && !m_sid.empty() )
00092 {
00093 const std::string pwd = m_parent->password();
00094 char buf[41];
00095 iksha *sha;
00096 sha = iks_sha_new();
00097 iks_sha_hash( sha, (const unsigned char*)m_sid.c_str(), m_sid.length(), 0 );
00098 iks_sha_hash( sha, (const unsigned char*)pwd.c_str(), pwd.length(), 1 );
00099 iks_sha_print( sha, buf );
00100 iks_sha_delete( sha );
00101 new Tag( query, "digest", buf );
00102 }
00103 else
00104 {
00105 new Tag( query, "password", m_parent->password() );
00106 }
00107
00108 m_parent->trackID( this, id, TRACK_SEND_AUTH );
00109 m_parent->send( iq );
00110 break;
00111 }
00112 case TRACK_SEND_AUTH:
00113 m_parent->setAuthed( true );
00114 m_parent->connected();
00115 break;
00116 }
00117 break;
00118
00119 default:
00120 break;
00121 }
00122 return false;
00123 }
00124
00125 bool NonSaslAuth::handleIq( Stanza * )
00126 {
00127 return false;
00128 }
00129
00130 }