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, const std::string& sid )
00025 : m_parent( parent ), m_sid( sid )
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()
00038 {
00039 std::string id = m_parent->getID();
00040
00041 Tag *iq = new Tag( "iq" );
00042 iq->addAttrib( "to", m_parent->jid().server() );
00043 iq->addAttrib( "id", id );
00044 iq->addAttrib( "type", "get" );
00045 Tag *q = new Tag( "query" );
00046 q->addAttrib( "xmlns", XMLNS_AUTH );
00047 q->addChild( new Tag( "username", m_parent->username() ) );
00048 iq->addChild( q );
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 STANZA_IQ_ERROR:
00059 {
00060 m_parent->setAuthed( false );
00061 m_parent->disconnect( CONN_AUTHENTICATION_FAILED );
00062
00063 Tag *t = stanza->findChild( "error" );
00064 if( t )
00065 {
00066 if( t->hasChild( "conflict" ) || t->hasAttribute( "code", "409" ) )
00067 m_parent->setAuthFailure( NONSASL_CONFLICT );
00068 else if( t->hasChild( "not-acceptable" ) || t->hasAttribute( "code", "406" ) )
00069 m_parent->setAuthFailure( NONSASL_NOT_ACCEPTABLE );
00070 else if( t->hasChild( "not-authorized" ) || t->hasAttribute( "code", "401" ) )
00071 m_parent->setAuthFailure( NONSASL_NOT_AUTHORIZED );
00072 }
00073 break;
00074 }
00075 case STANZA_IQ_RESULT:
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->addAttrib( "id", id );
00084 iq->addAttrib( "type", "set" );
00085 Tag *query = new Tag( "query" );
00086 query->addAttrib( "xmlns", XMLNS_AUTH );
00087 query->addChild( new Tag( "username", m_parent->jid().username() ) );
00088 query->addChild( new Tag( "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 query->addChild( new Tag( "digest", buf ) );
00102 }
00103 else
00104 {
00105 query->addChild( new Tag( "password", m_parent->password() ) );
00106 }
00107
00108 iq->addChild( query );
00109 m_parent->trackID( this, id, TRACK_SEND_AUTH );
00110 m_parent->send( iq );
00111 break;
00112 }
00113 case TRACK_SEND_AUTH:
00114 m_parent->setAuthed( true );
00115 m_parent->connected();
00116 break;
00117 }
00118 break;
00119
00120 default:
00121 break;
00122 }
00123 return false;
00124 }
00125
00126 }