root/trunk/src/renetcolSender.c @ 77

Revision 77, 10.4 KB (checked in by andreu, 14 years ago)

some updates to prepare release 0.0.12

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