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->addAttribute( "to", m_parent->jid().server() );
00043 iq->addAttribute( "id", id );
00044 iq->addAttribute( "type", "get" );
00045 Tag *q = new Tag( iq, "query" );
00046 q->addAttribute( "xmlns", XMLNS_AUTH );
00047 new Tag( q, "username", m_parent->username() );
00048
00049 m_parent->trackID( this, id, TRACK_REQUEST_AUTH_FIELDS );
00050 m_parent->send( iq );
00051 }
00052
00053 bool NonSaslAuth::handleIqID( Stanza *stanza, int context )
00054 {
00055 switch( stanza->subtype() )
00056 {
00057 case StanzaIqError:
00058 {
00059 m_parent->setAuthed( false );
00060 m_parent->disconnect( ConnAuthenticationFailed );
00061
00062 Tag *t = stanza->findChild( "error" );
00063 if( t )
00064 {
00065 if( t->hasChild( "conflict" ) || t->hasAttribute( "code", "409" ) )
00066 m_parent->setAuthFailure( NonSaslConflict );
00067 else if( t->hasChild( "not-acceptable" ) || t->hasAttribute( "code", "406" ) )
00068 m_parent->setAuthFailure( NonSaslNotAcceptable );
00069 else if( t->hasChild( "not-authorized" ) || t->hasAttribute( "code", "401" ) )
00070 m_parent->setAuthFailure( NonSaslNotAuthorized );
00071 }
00072 break;
00073 }
00074 case StanzaIqResult:
00075 switch( context )
00076 {
00077 case TRACK_REQUEST_AUTH_FIELDS:
00078 {
00079 std::string id = m_parent->getID();
00080
00081 Tag *iq = new Tag( "iq" );
00082 iq->addAttribute( "id", id );
00083 iq->addAttribute( "type", "set" );
00084 Tag *query = new Tag( iq, "query" );
00085 query->addAttribute( "xmlns", XMLNS_AUTH );
00086 new Tag( query, "username", m_parent->jid().username() );
00087 new Tag( query, "resource", m_parent->jid().resource() );
00088
00089 Tag *q = stanza->findChild( "query" );
00090 if( ( q->hasChild( "digest" ) ) && !m_sid.empty() )
00091 {
00092 const std::string pwd = m_parent->password();
00093 char buf[41];
00094 iksha *sha;
00095 sha = iks_sha_new();
00096 iks_sha_hash( sha, (const unsigned char*)m_sid.c_str(), m_sid.length(), 0 );
00097 iks_sha_hash( sha, (const unsigned char*)pwd.c_str(), pwd.length(), 1 );
00098 iks_sha_print( sha, buf );
00099 iks_sha_delete( sha );
00100 new Tag( query, "digest", buf );
00101 }
00102 else
00103 {
00104 new Tag( query, "password", m_parent->password() );
00105 }
00106
00107 m_parent->trackID( this, id, TRACK_SEND_AUTH );
00108 m_parent->send( iq );
00109 break;
00110 }
00111 case TRACK_SEND_AUTH:
00112 m_parent->setAuthed( true );
00113 m_parent->connected();
00114 break;
00115 }
00116 break;
00117
00118 default:
00119 break;
00120 }
00121 return false;
00122 }
00123
00124 bool NonSaslAuth::handleIq( Stanza * )
00125 {
00126 return false;
00127 }
00128
00129 }