identd.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           identd.cpp  -  description
00003                              -------------------
00004     begin                : Thu Dec 9 2004
00005     copyright            : (C) 2004 by VooDooMan
00006     email                : vdmfun@hotmail.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010 
00011 VooDoo cIRCle - an IRC (ro)bot
00012 Copyright (C) 2004 by Marian VooDooMan Meravy (vdmfun@hotmail.com)
00013 
00014 This program is free software; you can redistribute it and/or
00015 modify it under the terms of the GNU General Public License
00016 as published by the Free Software Foundation; either version 2
00017 of the License, or (at your option) any later version.
00018 
00019 This program is distributed in the hope that it will be useful,
00020 but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License
00025 along with this program; if not, write to the Free Software
00026 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028 ****************************************************************************/
00029 
00030 /*!
00031     \file
00032     \brief Emulates Ident daemon
00033 */
00034 
00035 //---------------------------------------------------------------------------
00036 
00037 #include <time.h>
00038 
00039 #include "sock.h"
00040 #include "log.h"
00041 #include "stdlib.h"
00042 #include "stats.h"
00043 
00044 #pragma hdrstop
00045 
00046 #include "identd.h"
00047 
00048 #include "params.h"
00049 
00050 //---------------------------------------------------------------------------
00051 #ifdef __BORLANDC__
00052 #pragma package(smart_init)
00053 #endif
00054 
00055 #ifndef _WIN32
00056 #ifndef HAVE_LTOA
00057 extern char *ltoa(long value, char *buffer, int radix);
00058 #endif
00059 #endif
00060 
00061 s_socket identd_sock;                   //!< Stores socket handle of IDENT daemon
00062 s_socket identd_client;                 //!< Socket of IDENTD client
00063 #ifdef IPv6
00064 s_socket identd_sock_ipv6;              //!< Stores socket handle of IDENT daemon for IPv6 connections
00065 s_socket identd_client_ipv6;            //!< Socket of IDENTD client for IPv6 connections
00066 #endif
00067 time_t ident_last_response;             //!< Timestamp of last response
00068 
00069 /*!
00070     \brief Writes OS's socket I/O error to log file
00071     \author VooDooMan
00072     \version 1
00073     \date 2004
00074     \param io_error OS's socket I/O error code
00075 */
00076 void identd_error_log(int io_error)
00077 {
00078     char log[2*1024];
00079     strcpy(log,"I/O error, OS error code #");
00080     char tmp[64];
00081     strcat(log,ltoa(io_error,tmp,10));
00082     strcat(log,": ");
00083     strcat(log,sock_error(io_error));
00084     log_identd(log);
00085 }
00086 
00087 /*!
00088     \brief Starts IDENT daemon
00089     \author VooDooMan
00090     \version 2
00091     \date 2005
00092     \param bind IPv4 Address to bind
00093     \param port Port to bind
00094     \return Returns false for error
00095 */
00096 bool identd_startup(in_addr bind, unsigned short port)
00097 {
00098     if(identd_sock.cmp()) {
00099         sock_close(identd_sock);
00100         identd_sock.clear();
00101         sock_close(identd_client);
00102         identd_client.clear();
00103         ident_last_response=0;
00104     }
00105 
00106     int error_code=0;
00107     identd_sock=sock_bind(bind,port,error_code);
00108     if(!identd_sock.cmp()) {
00109         identd_error_log(error_code);
00110         return false;
00111     }
00112     log_identd("Started up (IPv4)");
00113 
00114     return true;
00115 }
00116 
00117 /*!
00118     \brief Starts IDENT daemon
00119     \author VooDooMan
00120     \version 1
00121     \date 2005
00122     \param bind_ipv6 IPv6 Address to bind
00123     \param port Port to bind
00124     \return Returns false for error
00125 */
00126 bool identd_startup(char* bind_ipv6, unsigned short port)
00127 {
00128 #ifdef IPv6
00129     if(identd_sock_ipv6.cmp()) {
00130         sock_close(identd_sock_ipv6);
00131         identd_sock_ipv6.clear();
00132         sock_close(identd_client_ipv6);
00133         identd_client_ipv6.clear();
00134         ident_last_response=0;
00135     }
00136 
00137     int error_code=0;
00138     identd_sock_ipv6=sock_bind6(bind_ipv6,port,error_code);
00139     if(!identd_sock_ipv6.cmp()) {
00140         identd_error_log(error_code);
00141         return false;
00142     }
00143     log_identd("Started up (IPv6)");
00144 
00145     return true;
00146 #else
00147     return false;
00148 #endif
00149 }
00150 
00151 /*!
00152     \brief Checks and handles IDENT request
00153     \author VooDooMan
00154     \version 2
00155     \date 2005
00156     \param ident_string IDENT string used as response to the request
00157     \return Returns false for error or nothing done, true for successful IDENT response
00158 */
00159 bool identd_check(const char* ident_string)
00160 {
00161     for(int i=0; i<2; i++) {
00162         s_socket* identd;
00163         s_socket* client;
00164         if(i==0) {
00165             identd=&identd_sock;
00166             client=&identd_client;
00167         } else {
00168 #ifdef IPv6
00169             identd=&identd_sock_ipv6;
00170             client=&identd_client_ipv6;
00171 #else
00172             return false;
00173 #endif
00174         }
00175 
00176         if(identd->cmp()==false)
00177             continue;
00178 
00179         if(!client->cmp()) {
00180             ident_last_response=0;
00181             s_socket s;
00182             if(i==0)
00183                 s=sock_accept(*identd);
00184             else
00185                 s=sock_accept6(*identd);
00186             if(s.cmp()) {
00187 
00188                 sock_async(s);
00189 
00190                 if(i==0)
00191                     identd_client=s;
00192 #ifdef IPv6
00193                 else
00194                     identd_client_ipv6=s;
00195 #endif
00196                 stats_identd_new_connection();
00197             }
00198         }
00199 
00200         if(client->cmp()) {
00201             if(ident_last_response) {
00202                 if(ident_last_response+20<time(NULL)) {
00203                     ident_last_response=0;
00204                     sock_close(*client);
00205                     client->clear();
00206                     ident_last_response=0;
00207                     //identd_shutdown();
00208                     return true;
00209                 }
00210             }
00211             char buff[1024];
00212             int ec=0;
00213             bool closed;
00214             size_t size=sock_read(*client,buff,sizeof(buff)-1,ec,closed);
00215             stats_identd_bytes_received(size);
00216             if(ec) {
00217                 sock_close(*client);
00218                 client->clear();
00219                 ident_last_response=0;
00220                 identd_error_log(ec);
00221                 return false;
00222             }
00223             buff[size]=0;
00224             char tmp[2*1024];
00225             if(size) {
00226                 strcpy(tmp,"Ident request ");
00227                 if(i==0)
00228                     strcat(tmp,"(IPv4)");
00229                 else
00230                     strcat(tmp,"(IPv6)");
00231                 strcat(tmp,": ");
00232                 strcat(tmp,buff);
00233                 tmp[strlen(tmp)-1]=0;
00234                 tmp[strlen(tmp)-1]=0;
00235                 log_identd(tmp);
00236 
00237                 //int i2=0;
00238                 int cnt=0;
00239                 unsigned int i1;
00240                 char num1[64], num2[64];
00241                 int num_c=0;
00242                 for(i1=0; i1<strlen(buff); i1++) {
00243                     if(cnt==0 && buff[i1]==',') {
00244                         cnt++;
00245                         num_c=0;
00246                         continue;
00247                     }
00248                     if(cnt==0 && (buff[i1]<'0' || buff[i1]>'9'))
00249                         continue;
00250                     if(cnt==0 && buff[i1]!=0x20 && buff[i1]!=',') {
00251                         num1[num_c++]=buff[i1];
00252                         num1[num_c]=0;
00253                         if(num_c>60)
00254                             break;
00255                         continue;
00256                     }
00257                     if(cnt==1 && (buff[i1]<'0' || buff[i1]>'9'))
00258                         continue;
00259                     if(cnt==1 && buff[i1]!=0x20 && buff[i1]!=',') {
00260                         num2[num_c++]=buff[i1];
00261                         num2[num_c]=0;
00262                         if(num_c>60)
00263                             break;
00264                         continue;
00265                     }
00266                 }
00267 
00268                 strcpy(tmp,num1);
00269                 strcat(tmp," , ");
00270                 strcat(tmp,num2);
00271                 strcat(tmp," ");
00272 
00273                 strcat(tmp,ident_string);
00274                 char tmp2[2*1024];
00275                 tmp2[0]='\r';
00276                 tmp2[1]='\n';
00277                 tmp2[2]=0;
00278                 strcat(tmp,tmp2);
00279 
00280                 size_t sent=sock_send(*client,tmp,strlen(tmp),ec);
00281                 stats_identd_bytes_sent(sent);
00282                 if(ec) {
00283                     sock_close(*client);
00284                     client->clear();
00285                     ident_last_response=0;
00286                     identd_error_log(ec);
00287                     return false;
00288                 }
00289                 strcpy(tmp2,"Ident reply: ");
00290                 strcat(tmp2,tmp);
00291                 tmp2[strlen(tmp2)-1]=0;
00292                 tmp2[strlen(tmp2)-1]=0;
00293                 log_identd(tmp2);
00294                 time(&ident_last_response);
00295                 return true;
00296             } else
00297                 return false;
00298         }
00299     }
00300     return false;
00301 }
00302 
00303 /*!
00304     \brief Shuts down IDENT daemon (both IPv4 and IPv6)
00305     \author VooDooMan
00306     \version 2
00307     \date 2005
00308 */
00309 void identd_shutdown()
00310 {
00311     if(identd_sock.cmp()) {
00312         log_identd("Shuted down (IPv4)");
00313         sock_close(identd_sock);
00314         identd_sock.clear();
00315         sock_close(identd_client);
00316         identd_client.clear();
00317         ident_last_response=0;
00318     }
00319 
00320 #ifdef IPv6
00321     if(identd_sock_ipv6.cmp()) {
00322         log_identd("Shuted down (IPv6)");
00323         sock_close(identd_sock_ipv6);
00324         identd_sock_ipv6.clear();
00325         sock_close(identd_client_ipv6);
00326         identd_client_ipv6.clear();
00327         ident_last_response=0;
00328     }
00329 #endif
00330 }
00331 
00332 /*!
00333     \brief Shuts down IDENT daemon (IPv4)
00334     \author VooDooMan
00335     \version 1
00336     \date 2005
00337 */
00338 void identd4_shutdown()
00339 {
00340     if(identd_sock.cmp()) {
00341         log_identd("Shuted down (IPv4)");
00342         sock_close(identd_sock);
00343         identd_sock.clear();
00344         sock_close(identd_client);
00345         identd_client.clear();
00346         ident_last_response=0;
00347     }
00348 }
00349 
00350 /*!
00351     \brief Shuts down IDENT daemon (IPv6)
00352     \author VooDooMan
00353     \version 1
00354     \date 2005
00355 */
00356 void identd6_shutdown()
00357 {
00358 #ifdef IPv6
00359     if(identd_sock_ipv6.cmp()) {
00360         log_identd("Shuted down (IPv6)");
00361         sock_close(identd_sock_ipv6);
00362         identd_sock_ipv6.clear();
00363         sock_close(identd_client_ipv6);
00364         identd_client_ipv6.clear();
00365         ident_last_response=0;
00366     }
00367 #endif
00368 }
00369 
00370 /*!
00371     \brief Resets IDENT daemon (both IPv4 and IPv6)
00372     \author VooDooMan
00373     \version 1
00374     \date 2005
00375 */
00376 void identd_renew()
00377 {
00378     if(identd_client.cmp()) {
00379         sock_close(identd_client);
00380         identd_client.clear();
00381         ident_last_response=0;
00382     }
00383 
00384 #ifdef IPv6
00385     if(identd_client_ipv6.cmp()) {
00386         sock_close(identd_client_ipv6);
00387         identd_client_ipv6.clear();
00388         ident_last_response=0;
00389     }
00390 #endif
00391 }
00392 

Generated on Sun Jul 10 03:22:53 2005 for VooDoo cIRCle by doxygen 1.4.3

Hosted by SourceForge.net Logo