#include #include #include #include #include #include #include /* hlavičkový soubor tcp_wrappers */ #include /* číslo portu serveru */ #define PORT_NUM 5000 /* syslog facility */ #define LOG_FACILITY LOG_AUTHPRIV /* tyto proměnné jsou vyžadovány tcp_wrappers */ int allow_severity=4; int deny_severity=4; /* deskriptory socketů apod. */ int fd,fd2; struct sockaddr_in serv_addr, client_addr; int client_addr_len; struct hostent *client_info; /* request_info pro tcp_wrappers */ struct request_info request; char client_name[80]; /* do_exit() zapíše chybu do logu a ukončí aplikaci */ void do_exit(char *s) { syslog(LOG_WARNING,"%s, exiting.",s); exit(1); } int main (int argc, char ** argv) { /* argv[0] může být absolutní cesta, potřebujeme jen jméno programu */ if (strrchr(argv[0],'/')) argv[0] = strrchr(argv[0],'/')+1; /* nastavíme způsob logování */ openlog(argv[0],LOG_PID,LOG_FACILITY); /* otevíráme socket (TCP) */ if ((fd=socket(AF_INET,SOCK_STREAM,0))<0) do_exit("error in socket()"); /* navážeme se na port */ bzero((char *)&serv_addr,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(PORT_NUM); serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); if (bind(fd,&serv_addr,sizeof(serv_addr))<0) do_exit("error in bind()"); if (listen(fd,5)<0) do_exit("error in listen()"); while(1) { client_addr_len=sizeof(client_addr); /* čekáme na spojení klienta */ if ((fd2=accept(fd,&client_addr,&client_addr_len))<0) do_exit("error in accept()"); /* zjistíme a uložíme jméno klientského počítače */ if (client_info=gethostbyaddr((char *)&(client_addr.sin_addr),\ sizeof(client_addr.sin_addr),AF_INET)) snprintf(client_name, sizeof(client_name)-1,"%s",client_info->h_name); else client_name[0]='\0'; /* naplníme request_info */ /* pokud zadáme i RQ_SERVER_SIN a RQ_CLIENT_SIN, tcp_wrappers */ /* se pokusí identifikovat vlastníka příchozího spojení */ request_init(&request, RQ_DAEMON, argv[0],\ RQ_SERVER_SIN, &serv_addr, RQ_CLIENT_SIN, &client_addr,\ RQ_CLIENT_ADDR, inet_ntoa(client_addr.sin_addr),\ RQ_CLIENT_NAME, client_name, 0); /* ověříme, zda je přístup povolen */ if (!hosts_access(&request)) { /* spojení zamítnuto tcp_wrappers, zapíšeme do logu */ /* jméno vlastníka příchozího spojení je dostupné přes eval_user() */ syslog(deny_severity, "rejected connection from %s (%s@%s)",\ inet_ntoa(client_addr.sin_addr),eval_user(&request),client_name); /* spojení ukončíme */ close(fd2); } else { /* spojení povoleno tcp_wrappers, zapíšeme do logu */ syslog(allow_severity, "accepted connection from %s (%s@%s)", inet_ntoa(client_addr.sin_addr),eval_user(&request),client_name); /* tady bychom zpracovali požadavek klienta */ /* spojení ukončíme */ close(fd2); } } } /* kompilace: gcc server2.c -lwrap -lnsl */