root/trunk/src/renetcolSender.c @ 54

Revision 47, 10.2 KB (checked in by andreu, 15 years ago)

merge from tag REL-0.0.11beta

  • Property svn:eol-style set to native
Line 
1/*
2 * File: renetcolSender.c
3 *
4 * Authors: ANDREU Francois-Xavier
5 *
6 * Copyright (C) 2005 2006 2007 GIP RENATER
7 */
8
9/*  This file is part of renetcol.
10 *
11 *  renetcol is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  renetcol is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with renetcol; if not, write to the Free Software
23 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24 */
25
26#include "renetcolSender.h"
27
28key_t myKey = 0;
29int myQueue = 0;
30msgType myMsg;
31long type;
32RulesPtr rulesListPtr;
33char *rulesFileName;
34char *keyId;
35char *remoteHost;
36int i=0;
37int j=0;
38unsigned char *myText;
39unsigned char buffer2[2];
40unsigned char buffer4[4];
41unsigned short nb=0;
42unsigned short typeMsg = 0;
43RulesPtr tmp = NULL;
44
45/*
46 * todo
47 */
48int
49todo(int sock, char *host)
50{
51  char buffer[256];
52  int length;
53  FILE *ruleFile;
54  FILE *tmpFile;
55  char field[4];
56  char port[6];
57  char value[44];
58  char operator[2];
59  char lines[256][256];
60  char line[256];
61  char lineCopy[256];
62  char strTok[1];
63  char strName[100];
64  int cpt = 0;
65  int i = 0;
66  int ruleToDelete = 0;
67
68  while (1){
69    length = read(sock, buffer, 256);
70    if (length < 0){
71      syslog(LOG_ERR, " read : %s", strerror(errno));
72      close(sock);
73      return 1;
74    }
75    if (length == 0)
76      break;
77    buffer[length] = '\0';
78    if (strncmp("DELETE", buffer, 6)==0){
79      /* DELETE ALL RULES FROM A REMOTE CLIENT */
80      if (!(ruleFile = fopen(rulesFileName, "r"))) {
81        syslog (LOG_ERR, "error during %s opening\n", rulesFileName);
82        close(sock);
83        exit(1);
84      } else {
85        while ( fgets(line, 256, ruleFile) != 0) {
86          strncpy(lineCopy, line, 256);
87          if (strncmp("N", lineCopy, 1) == 0){
88            ruleToDelete = 0;
89            if (sscanf(lineCopy, "%1s %s\n",
90                       strTok,
91                       strName) != 0) {
92              if (strncmp(strName, host, strlen(host)) == 0){
93                ruleToDelete = 1;
94              } else {
95                strncpy(lines[cpt], line, strlen(line));
96              }
97            } else {
98              close(sock);
99              return 1;
100            }
101          } else {
102            if (ruleToDelete==0) {
103              strncpy(lines[cpt], lineCopy, strlen(lineCopy));
104            }
105          }
106          cpt++;
107        } /* while end */
108        fclose(ruleFile);
109        if (!(tmpFile = fopen(FILE_TEMPO, "w"))) {
110          syslog (LOG_ERR, "error during %s opening", FILE_TEMPO);
111          close(sock);
112          return 1;
113        } else {
114          for (i=0; i<cpt; i++){
115            fprintf(tmpFile, "%s", lines[i]);
116          }
117          fclose(tmpFile);
118          if (remove(rulesFileName)!=0){
119            syslog(LOG_ERR, "rules.txt remove pb: %s", strerror(errno));
120            close(sock);
121            return 1;
122          }
123          if (rename(FILE_TEMPO, rulesFileName)!=0){
124            syslog(LOG_ERR, "rename file pb: %s", strerror(errno));
125            close(sock);
126            return 1;
127          }
128        }
129      }
130    } else {
131      /* NEW RULE */
132      if (sscanf(buffer, "%s %s %1s %s\n",
133                 port,
134                 field,
135                 operator,
136                 value) == 0) {
137        syslog (LOG_ERR, "error in recept rule: %s", buffer);
138        close(sock);
139        return 1;
140      }
141      if (!(ruleFile = fopen(rulesFileName, "a"))) {
142        syslog (LOG_ERR, "error during %s opening", rulesFileName);
143        close(sock);
144        return 1;
145      } else {
146        fprintf(ruleFile, "N %s\n", host);
147        fprintf(ruleFile, "O socket %s %s\n", host, port);
148        fprintf(ruleFile, "C %s %s %s\n", field, operator, value);
149        fclose(ruleFile);
150      }
151    }
152  }
153  close(sock);
154  return 0;
155}
156
157/*
158 * tcpServer
159 */
160int
161tcpServer ()
162{
163  struct addrinfo index, *result;
164  struct sockaddr_storage listenAddress;
165  socklen_t listenAddressLen;
166  int listenSock;
167  int returnCode;
168  pid_t renetcolPID = 0;
169  FILE *pidFile;
170  unsigned pid;
171  char line[256];
172  int status;
173
174  memset(&index, 0, sizeof index);
175  index.ai_flags = AI_PASSIVE;
176  index.ai_family = AF_UNSPEC;
177  index.ai_socktype = SOCK_STREAM;
178  index.ai_protocol = IPPROTO_TCP;
179  returnCode = getaddrinfo(NULL, RECEPT_PORT, &index, &result);
180  if (returnCode != 0) {
181    syslog(LOG_ERR, "getaddrinfo : %s", strerror(errno));
182    return -1;
183  }
184  listenAddressLen = result->ai_addrlen;
185  memcpy(&listenAddress, result->ai_addr, (size_t) listenAddressLen);   
186  listenSock = socket(result->ai_family, result->ai_socktype,
187                      result->ai_protocol);
188  if ( listenSock < 0) {
189    syslog(LOG_ERR, "socket : %s", strerror(errno));
190    freeaddrinfo(result);
191    return -1;
192  }
193  freeaddrinfo(result);
194 
195  {
196    int on = 1;
197    setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);
198  }
199  if (bind(listenSock, (struct sockaddr *) &listenAddress,
200           listenAddressLen) < 0 ||
201      listen(listenSock, 8) < 0) {
202    syslog(LOG_ERR, "bind or listen : %s", strerror(errno));
203    return -1;
204  }
205  for (;;) {           
206    int clientSock;
207    struct sockaddr_storage clientAddress;
208    socklen_t clientAddressLen;
209    char host[NI_MAXHOST];
210   
211    memset(&clientAddress, 0, sizeof clientAddress);
212    clientAddressLen = (socklen_t) sizeof clientAddress;
213   
214    if ((clientSock =
215         accept(listenSock, (struct sockaddr *)
216                &clientAddress,
217                &clientAddressLen)) < 0) {
218      continue;
219    }
220    if (clientAddress.ss_family != AF_INET &&
221        clientAddress.ss_family != AF_INET6) {
222      close(clientSock);
223      continue;
224    }
225    if (getnameinfo((struct sockaddr *) &clientAddress,
226                    clientAddressLen, host, sizeof host,
227                    NULL, (size_t) 0, NI_NUMERICHOST) == 0) {
228      syslog(LOG_INFO,
229             "New connection from %s", host);
230    }
231    remoteHost = host;
232    switch (fork ()) {
233    case 0 :
234      close (listenSock);
235      todo(clientSock, remoteHost);
236      if (!(pidFile = fopen("/tmp/pidrenetcol.tmp", "r"))) {
237        syslog (LOG_ERR, "error during /tmp/pidrenetcol.tmp opening : %s\n",
238                strerror(errno));
239        exit(1);
240      } else {
241        fgets(line, 256, pidFile);
242        if (sscanf(line, "%u", &pid)==0)
243          syslog(LOG_ERR,"sscanf : %s", strerror(errno));
244        renetcolPID = pid;
245      }
246      fclose(pidFile);
247      if (renetcolPID==0){
248        syslog(LOG_INFO, "PID null");
249      }else{
250        if (kill(renetcolPID, SIGUSR1)<0)
251          syslog(LOG_ERR, "I can't send SIGUSR1 to renetcol process : %s",
252                 strerror(errno));
253      }
254      exit (0);
255    case -1 :
256      syslog (LOG_ERR, "fork : %s", strerror(errno));
257      return (-1);
258    default :
259      close (clientSock);
260      if (waitpid( -1, &status, WNOHANG)==-1){
261        syslog(LOG_ERR, "waitpid : %s", strerror(errno));
262        exit(1);
263      }
264    }
265  }
266  return (0);
267}
268
269/*
270 *
271 */
272void initConfSender(){
273  RulesPtr tmp = NULL;
274
275  tmp = rulesListPtr;
276  for ( ; tmp; tmp=tmp->next) {
277    rulesListPtr = delRule(tmp, rulesListPtr);
278  }
279  rulesListPtr = NULL;
280  rulesListPtr = getRules(rulesListPtr, rulesFileName);
281  tmp = rulesListPtr;
282  for ( ; tmp; tmp=tmp->next) {
283    if (tmp->type != 2) {
284      rulesListPtr = delRule(tmp, rulesListPtr);
285    }
286  }
287  tmp = NULL;
288}
289
290/*
291 * Main
292 * ----
293 */
294int 
295main (int argc, char *argv[])
296{
297  int s=0;
298  unsigned short rulesID = 0;
299  FILE *pidFile;
300  pid_t renetcolPID = 0;
301
302  if ( argc != 4) {
303    fprintf (stderr,
304             "%s: Usage: %s <key> <msg type> <rules file>\n exp: %s renetcol 1 rules.txt\n",
305             argv[0], argv[0], argv[0]);
306    exit(1);
307  }
308  if (sscanf (argv[2], "%ld", &type) != 1){
309    fprintf(stderr, "renetcolSender: Error, Invalid message type in command\n");
310    exit(1);
311  } 
312
313  openlog(argv[0], LOG_PID, LOG_USER);
314  keyId = (char *) malloc((strlen(argv[1])+1) * sizeof(char));
315  strcpy (keyId, argv[1]);
316  rulesFileName = (char *) malloc((strlen(argv[3])+1) * sizeof(char));
317  strcpy (rulesFileName, argv[3]);
318  rulesListPtr = NULL;
319  rulesListPtr = getRules(rulesListPtr, rulesFileName);
320  /* we delete rules which are not type socket */
321  tmp = rulesListPtr;
322  for ( ; tmp; tmp=tmp->next) {
323    if (tmp->type != 2) {
324      rulesListPtr = delRule(tmp, rulesListPtr);
325    }
326  }
327  tmp = NULL;
328  /* get IPC messages queue */
329  if ((myKey = ftok(keyId, 0))== -1){
330    syslog(LOG_ERR, "ftok : %s", strerror(errno));
331    exit(1);
332  }
333  if ((myQueue = msgget(myKey, 0)) == -1){
334    syslog(LOG_ERR, "msgget : %s", strerror(errno));
335    exit(1);
336  }
337
338/*   chdir ("/"); */
339  fprintf(stderr, "renetcolSender: I become a deamon, next messages via syslogd. By.\n");
340  if (fork () != 0)
341    exit (0);
342  if (setsid() == -1){
343    exit(4);
344  }
345/*   for (i = 0; i < FOPEN_MAX; i ++) */
346/*     close (i); */
347 
348  /* launch a TCP server to listen remote clients */
349  switch (fork ()) {
350  case 0 : /* son */
351    tcpServer();
352  case -1 :
353    syslog (LOG_ERR, "fork : %s", strerror(errno));
354    return (-1);
355  default : /* father */
356    break;
357  }
358  /* loop on the message queue */
359  while (1) {
360    i=0;
361    myText = msgRcv(myQueue, &myMsg, type);
362    buffer2[0]= *(myText+i); i++;
363    buffer2[1]= *(myText+i); i++;
364    typeMsg = *((unsigned short *)&buffer2);
365    if (1==typeMsg){
366      /* we send the template definition to all the known destination */
367      tmp = rulesListPtr;
368      for ( ; tmp; tmp=tmp->next) {
369        s = sendMessage(tmp->host->sockId, myText, sizeof(myMsg.text),
370                        tmp->host->hostAddressPtr);
371      }
372    } else if (11==*((unsigned short*)&buffer2)){
373      buffer2[0]= *(myText+i); i++;
374      buffer2[1]= *(myText+i); i++;
375      rulesID = *((unsigned short *)&buffer2);
376      /* here we send the flow to the correct remote client */
377      tmp = rulesListPtr;
378      for ( ; tmp; tmp=tmp->next) { /* FIXME while */
379        if (tmp->id == rulesID){
380          s = sendMessage(tmp->host->sockId, myText, sizeof(myMsg.text),
381                          tmp->host->hostAddressPtr);
382        }
383      }
384    } else if (12==*((unsigned short*)&buffer2)){
385      buffer4[0]= *(myText+i); i++;
386      buffer4[1]= *(myText+i); i++;
387      buffer4[2]= *(myText+i); i++;
388      buffer4[3]= *(myText+i); i++;
389      renetcolPID = *((pid_t *)&buffer4);
390      if (!(pidFile = fopen("/tmp/pidrenetcol.tmp", "w"))) {
391        syslog (LOG_ERR, "error during /tmp/pidrenetcol.tmp opening : %s\n",
392                strerror(errno));
393        exit(1);
394      } else {
395        if (fprintf(pidFile, "%u", renetcolPID)==0)
396          syslog(LOG_ERR,"fprintf : %s", strerror(errno));
397      }
398      fclose(pidFile);
399    } else if (13==*((unsigned short*)&buffer2)){
400      initConfSender();
401    } else {
402      syslog(LOG_INFO, "Msg type undefined ??");
403    }
404    i=0;
405  }
406  return(0);
407}
Note: See TracBrowser for help on using the browser.