ircproxy The Ultimate Cyborg |
00001 // ircproxy -- An IRC bouncer. 00002 // 00003 //! @file Authentication.cc 00004 //! @brief This file contains the implementation of class Authentication. 00005 // 00006 // Copyright (C) 2006, 2007 by 00007 // 00008 // Carlo Wood, Run on IRC <carlo@alinoe.com> 00009 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 00010 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 00011 // 00012 // This file may be distributed under the terms of the Q Public License 00013 // version 1.0 as appearing in the file LICENSE.QPL included in the 00014 // packaging of this file. 00015 00016 #ifndef USE_PCH 00017 #include "sys.h" 00018 #include "debug.h" 00019 #endif 00020 00021 #include "MessageIn.h" 00022 #include "Authentication.h" 00023 #include "keys.h" 00024 #include "exceptions.h" 00025 #include "ClientSession.h" 00026 #include "Identity.h" 00027 #include "Target.h" 00028 #include "Nick.h" 00029 00030 //! \brief Decode a PASS message. 00031 // 00032 // Decode message \a pass_msg, which must be a PASS client message. 00033 // The expected format of the message is: 00034 // 00035 // Param 0: login/identity 00036 // Param 1: ircproxy authentication password. 00037 // Param 2: service password (for example to authenticate with X). 00038 // Param 3: server password. 00039 // 00040 // Parameter 0 was already used to create the Identity. 00041 // 00042 void Authentication::decode_pass(ClientMessageIn const& pass_msg) 00043 { 00044 DoutEntering(dc::debug, "Authentication::decode_pass(" << pass_msg << ")"); 00045 ASSERT(pass_msg.key() == keys::PASS); 00046 00047 if (identity().has_authentication_password() && pass_msg.param(1) != identity().authentication_password()) 00048 THROW_EXCEPTION(FatalError("Bad authentication"), 00049 "Received pass \"" << pass_msg.param(1) << "\" is unequal expected pass \"" << 00050 identity().authentication_password() << '"'); 00051 00052 M_service_pass = pass_msg.param(2); 00053 M_server_pass = pass_msg.param(3); 00054 } 00055 00056 void Authentication::received_nick(void) 00057 { 00058 DoutEntering(dc::debug, "Authentication::received_nick()"); 00059 M_received_nick = true; 00060 if (M_received_user) 00061 received_nick_and_user(); 00062 } 00063 00064 //! \brief Decode a USER message. 00065 // 00066 // Decode message \a user_msg, which must be a USER client message. 00067 // The expect format of the message is: 00068 // 00069 // Param 0: username 00070 // Param 1: hostname (ignored) 00071 // Param 2: servername (ignored) 00072 // Param 3: Real name. 00073 // 00074 void Authentication::decode_user(ClientMessageIn const& user_msg) 00075 { 00076 DoutEntering(dc::debug, "Authentication::decode_user(" << user_msg << ")"); 00077 ASSERT(user_msg.key() == keys::USER); 00078 00079 M_ident = user_msg.param(0); 00080 M_realname = user_msg.param(3); 00081 00082 M_received_user = true; 00083 if (M_received_nick) 00084 received_nick_and_user(); 00085 } 00086 00087 void Authentication::received_nick_and_user(void) 00088 { 00089 DoutEntering(dc::debug, "Authentication::received_nick_and_user()"); 00090 00091 // Be kind and already try to connect to a server at this point. 00092 if (!identity().server_connection().is_connected()) 00093 identity().server_connection().connect(true); 00094 } 00095 00096 //! Send the authentication messages to the server. 00097 // 00098 // This function is called when ServerConnection::connect is called, which causes 00099 // ServerSession::do_connect to be called which calls ServerSession::start_authentication() 00100 // which creates a new AuthState object, which calls this function. 00101 void Authentication::send_authentication(ServerConnection& server_connection) 00102 { 00103 DoutEntering(dc::debug, "Authentication::send_authentication(" << server_connection << ")"); 00104 00105 // Generate a new random nick! 00106 identity().mynick()->set_out_nick(server_connection.server_session(), random_nick()); 00107 00108 if (!M_server_pass.empty()) 00109 server_connection.server_session() << "PASS " << M_server_pass << "\r\n"; 00110 server_connection.server_session().nicks().send_nick(identity().mynick()->out_name(server_connection.server_session())); 00111 char service_mode = 'x'; // FIXME: also used in ServerConnection::send_pong_and_mode 00112 server_connection.server_session() << "USER " << M_ident << " +i" << service_mode << " myserver :" << M_realname << "\r\n"; 00113 00114 // No NICK confirmation is sent for our initial NICK, but no other nick can be used. Pretend we received a confirmation. 00115 identity().mynick()->set_in_nick(server_connection.server_session(), identity().mynick()->out_name(server_connection.server_session())); 00116 server_connection.server_session().nicks().nick_received(identity().mynick()->in_name(server_connection.server_session())); 00117 } 00118
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|