X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fresolve.c;h=8e1749a30eaa574e76dfaed2c3e9679ea47fa701;hp=846e5236d40b1d630c22405a9e1477aa81622a9b;hb=2e794a6943a74f2ba4f3769703e3500fe9008461;hpb=5e929effcae7a273f55a0011632b86a0811cf35f diff --git a/src/ngircd/resolve.c b/src/ngircd/resolve.c index 846e5236..8e1749a3 100644 --- a/src/ngircd/resolve.c +++ b/src/ngircd/resolve.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: resolve.c,v 1.10 2005/03/05 12:57:14 alex Exp $"; +static char UNUSED id[] = "$Id: resolve.c,v 1.15 2005/07/25 09:20:10 fw Exp $"; #include "imp.h" #include @@ -39,30 +39,29 @@ static char UNUSED id[] = "$Id: resolve.c,v 1.10 2005/03/05 12:57:14 alex Exp $" #include "exp.h" #include "resolve.h" +#include "io.h" #ifdef IDENTAUTH -LOCAL VOID Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, INT Sock, INT w_fd )); +LOCAL void Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, int Sock, int w_fd )); #else -LOCAL VOID Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, INT w_fd )); +LOCAL void Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, int w_fd )); #endif -LOCAL VOID Do_ResolveName PARAMS(( CHAR *Host, INT w_fd )); +LOCAL void Do_ResolveName PARAMS(( char *Host, int w_fd )); #ifdef h_errno -LOCAL CHAR *Get_Error PARAMS(( INT H_Error )); +LOCAL char *Get_Error PARAMS(( int H_Error )); #endif -LOCAL RES_STAT *New_Res_Stat PARAMS(( VOID )); +LOCAL RES_STAT *New_Res_Stat PARAMS(( void )); -GLOBAL VOID -Resolve_Init( VOID ) -{ - /* Initialize module */ - - FD_ZERO( &Resolver_FDs ); -} /* Resolve_Init */ +static void +cb_resolver(int fd, short unused) { + (void) unused; /* shut up compiler warning */ + Read_Resolver_Result(fd); +} #ifdef IDENTAUTH @@ -77,7 +76,7 @@ Resolve_Addr( struct sockaddr_in *Addr ) * can't be forked, this functions returns NULL. */ RES_STAT *s; - INT pid; + int pid; s = New_Res_Stat( ); if( ! s ) return NULL; @@ -86,15 +85,24 @@ Resolve_Addr( struct sockaddr_in *Addr ) pid = fork( ); if( pid > 0 ) { + close( s->pipe[1] ); /* Main process */ Log( LOG_DEBUG, "Resolver for %s created (PID %d).", inet_ntoa( Addr->sin_addr ), pid ); - FD_SET( s->pipe[0], &Resolver_FDs ); - if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0]; + if (!io_setnonblock( s->pipe[0] )) { + Log( LOG_DEBUG, "Could not set Non-Blocking mode for pipefd %d", s->pipe[0] ); + goto out; + } + if (!io_event_create( s->pipe[0], IO_WANTREAD, cb_resolver )) { + Log( LOG_DEBUG, "Could not add pipefd %dto event watchlist: %s", + s->pipe[0], strerror(errno) ); + goto out; + } s->pid = pid; return s; } else if( pid == 0 ) { + close( s->pipe[0] ); /* Sub process */ Log_Init_Resolver( ); #ifdef IDENTAUTH @@ -105,24 +113,24 @@ Resolve_Addr( struct sockaddr_in *Addr ) Log_Exit_Resolver( ); exit( 0 ); } - else - { - /* Error! */ - free( s ); - Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); - return NULL; - } + + Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); + +out: /* Error! */ + close( s->pipe[0] ); + free( s ); +return NULL; } /* Resolve_Addr */ GLOBAL RES_STAT * -Resolve_Name( CHAR *Host ) +Resolve_Name( char *Host ) { /* Resolve hostname (asynchronous!). On errors, e.g. if the child * process can't be forked, this functions returns NULL. */ RES_STAT *s; - INT pid; + int pid; s = New_Res_Stat( ); if( ! s ) return NULL; @@ -131,61 +139,92 @@ Resolve_Name( CHAR *Host ) pid = fork( ); if( pid > 0 ) { + close( s->pipe[1] ); /* Main process */ Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid ); - FD_SET( s->pipe[0], &Resolver_FDs ); - if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0]; + if (!io_setnonblock( s->pipe[0] )) { + Log( LOG_DEBUG, "Could not set Non-Blocking mode for pipefd %d", s->pipe[0] ); + goto out; + } + if (!io_event_create( s->pipe[0], IO_WANTREAD, cb_resolver )) { + Log( LOG_DEBUG, "Could not add pipefd %dto event watchlist: %s", + s->pipe[0], strerror(errno) ); + goto out; + } s->pid = pid; return s; } else if( pid == 0 ) { + close( s->pipe[0] ); /* Sub process */ Log_Init_Resolver( ); Do_ResolveName( Host, s->pipe[1] ); Log_Exit_Resolver( ); exit( 0 ); } - else - { - /* Error! */ - free( s ); - Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); - return NULL; - } + + Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); + +out: /* Error! */ + close( s->pipe[0] ); + free( s ); + return NULL; } /* Resolve_Name */ #ifdef IDENTAUTH -LOCAL VOID -Do_ResolveAddr( struct sockaddr_in *Addr, int Sock, INT w_fd ) +LOCAL void +Do_ResolveAddr( struct sockaddr_in *Addr, int Sock, int w_fd ) #else -LOCAL VOID -Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd ) +LOCAL void +Do_ResolveAddr( struct sockaddr_in *Addr, int w_fd ) #endif { /* Resolver sub-process: resolve IP address and write result into * pipe to parent. */ - CHAR hostname[HOST_LEN]; + char hostname[HOST_LEN]; + char ipstr[HOST_LEN]; struct hostent *h; - INT len; + size_t len; + struct in_addr *addr; + char *ntoaptr; #ifdef IDENTAUTH - CHAR *res; + char *res; #endif /* Resolve IP address */ +#ifdef DEBUG Log_Resolver( LOG_DEBUG, "Now resolving %s ...", inet_ntoa( Addr->sin_addr )); - h = gethostbyaddr( (CHAR *)&Addr->sin_addr, sizeof( Addr->sin_addr ), AF_INET ); - if( h ) strlcpy( hostname, h->h_name, sizeof( hostname )); - else - { +#endif + h = gethostbyaddr( (char *)&Addr->sin_addr, sizeof( Addr->sin_addr ), AF_INET ); + if (!h) { #ifdef h_errno Log_Resolver( LOG_WARNING, "Can't resolve address \"%s\": %s!", inet_ntoa( Addr->sin_addr ), Get_Error( h_errno )); #else Log_Resolver( LOG_WARNING, "Can't resolve address \"%s\"!", inet_ntoa( Addr->sin_addr )); #endif strlcpy( hostname, inet_ntoa( Addr->sin_addr ), sizeof( hostname )); + } else { + strlcpy( hostname, h->h_name, sizeof( hostname )); + + h = gethostbyname( hostname ); + if ( h ) { + if (memcmp(h->h_addr, &Addr->sin_addr, sizeof (struct in_addr))) { + addr = (struct in_addr*) h->h_addr; + strlcpy(ipstr, inet_ntoa(*addr), sizeof ipstr); + ntoaptr = inet_ntoa( Addr->sin_addr ); + Log(LOG_WARNING,"Possible forgery: %s resolved to %s (which is at ip %s!)", + ntoaptr, hostname, ipstr); + strlcpy( hostname, ntoaptr, sizeof hostname); + } + } else { + ntoaptr = inet_ntoa( Addr->sin_addr ); + Log(LOG_WARNING, "Possible forgery: %s resolved to %s (which has no ip address)", + ntoaptr, hostname); + strlcpy( hostname, ntoaptr, sizeof hostname); + } } Log_Resolver( LOG_DEBUG, "Ok, translated %s to \"%s\".", inet_ntoa( Addr->sin_addr ), hostname ); @@ -206,9 +245,12 @@ Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd ) Log_Resolver( LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"", Sock, res ? res : "" ); /* Write IDENT result into pipe to parent */ - len = strlen( res ? res : "" ); - if( res != NULL ) res[len] = '\n'; - len++; + if (res) { + len = strlen(res); + res[len] = '\n'; + len++; + } else len = 1; + if( (size_t)write( w_fd, res ? res : "\n", len ) != (size_t)len ) { Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent (IDENT): %s!", strerror( errno )); @@ -219,16 +261,16 @@ Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd ) } /* Do_ResolveAddr */ -LOCAL VOID -Do_ResolveName( CHAR *Host, INT w_fd ) +LOCAL void +Do_ResolveName( char *Host, int w_fd ) { /* Resolver sub-process: resolve name and write result into pipe * to parent. */ - CHAR ip[16]; + char ip[16]; struct hostent *h; struct in_addr *addr; - INT len; + int len; Log_Resolver( LOG_DEBUG, "Now resolving \"%s\" ...", Host ); @@ -263,8 +305,8 @@ Do_ResolveName( CHAR *Host, INT w_fd ) #ifdef h_errno -LOCAL CHAR * -Get_Error( INT H_Error ) +LOCAL char * +Get_Error( int H_Error ) { /* Get error message for H_Error */ @@ -287,7 +329,7 @@ Get_Error( INT H_Error ) LOCAL RES_STAT * -New_Res_Stat( VOID ) +New_Res_Stat( void ) { RES_STAT *s;