00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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;
00062 s_socket identd_client;
00063 #ifdef IPv6
00064 s_socket identd_sock_ipv6;
00065 s_socket identd_client_ipv6;
00066 #endif
00067 time_t ident_last_response;
00068
00069
00070
00071
00072
00073
00074
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
00089
00090
00091
00092
00093
00094
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
00119
00120
00121
00122
00123
00124
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
00153
00154
00155
00156
00157
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
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
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
00305
00306
00307
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
00334
00335
00336
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
00352
00353
00354
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
00372
00373
00374
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