Source File modules/pm/protocol_mirror.c

    1    | /***************************************
    2    |
    3    |   Protocol mirror module (pw).  Whois protocol.
    4    |
    5    |   Status: NOT REVUED, NOT TESTED
    6    |
    7    |   ******************/ /******************
    8    |   Filename            : protocol_mirror.c
    9    |   Author              : andrei
    10   |   OSs Tested          : Solaris
    11   |   ******************/ /******************
    12   |   Copyright (c) 1999                              RIPE NCC
    13   |
    14   |   All Rights Reserved
    15   |
    16   |   Permission to use, copy, modify, and distribute this software and its
    17   |   documentation for any purpose and without fee is hereby granted,
    18   |   provided that the above copyright notice appear in all copies and that
    19   |   both that copyright notice and this permission notice appear in
    20   |   supporting documentation, and that the name of the author not be
    21   |   used in advertising or publicity pertaining to distribution of the
    22   |   software without specific, written prior permission.
    23   |
    24   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
    25   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
    26   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    27   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    28   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    29   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    30   |   ***************************************/
    31   | #include <stdio.h>
    32   | #include <glib.h>
    33   |
    34   | #include "protocol_mirror.h"
    35   | #include "mysql_driver.h"
    36   | #include "constants.h"
    37   |
    38   | //#include "access_control.h"
    39   | #include "socket.h"
    40   | #include "stubs.h"
    41   | #include "ud.h"
    42   | #include "ta.h"
    43   |
    44   | #include "ca_configFns.h"
    45   | #include "ca_dictSyms.h"
    46   | #include "ca_macros.h"
    47   | #include "ca_srcAttribs.h"
    48   |
    49   |
    50   |
    51   | #define MIN_ARG_LENGTH  6
    52   | #define NRTM_DELIM "-:"
    53   | /*
    54   | * parses input and fills nrtm_q_t structure
    55   | *
    56   | * Returns:
    57   | *  -1 in case of garbage
    58   | *  0  in case of valid -g
    59   | *  1  in case of -q sources
    60   | *
    61   | */
    62   | static int parse_request(char *input, nrtm_q_t *nrtm_q)
    63   | {
    64   |  char *ptr=input;
    65   |  char *token;
    66   |  char **tokens;
    67   |  char **tokens2;
    68   |  int res=0;
    69   |
    70   | // return(-1);
    71   |
    72   |  if(strlen(input)<MIN_ARG_LENGTH) return(-1);
    73   |  g_strchug(input);
    74   |  res=strncmp(input, "-g", 2);
    75   |  if(res!=0) {
    76   | 	 /* may be this is -q source query */
    77   | 	 res=strncmp(input, "-q", 2);
    78   | 	 if(res!=0)return(-1);
    79   | 	 ptr+=2;
    80   | 	 g_strchug(ptr);
    81   | 	 res=strncmp(ptr, "sources", 7);
    82   | 	 if(res!=0)return(-1);
    83   | 	 ptr+=7;
    84   | 	 g_strchug(ptr);
    85   | 	 token=ptr;
    86   | 	 if ((*token=='\0') || (*token=='\n'))nrtm_q->source=NULL;
    87   | 	 else {
    88   | 	   ptr=index(token, ' ');
    89   | 	   if (ptr) nrtm_q->source=g_strndup(token, (ptr-token));
    90   | 	   else nrtm_q->source=g_strdup(token);
    91   | 	 }
    92   | 	 return(1);
    93   |  }
    94   |
    95   |  /* this is -q query */
    96   |  ptr+=2;
    97   |
    98   |
    99   |  g_strchug(ptr);
    100  |  g_strdelimit(ptr, NRTM_DELIM, ':');
    101  |  tokens=g_strsplit(ptr, ":", 4);
    102  |  if(tokens==NULL) return(-1);
    103  |
    104  |  if(tokens[0]) {
    105  |     /* first token is source name */
    106  |     nrtm_q->source=g_strdup(tokens[0]);
    107  |     if(tokens[1]) {
    108  |       /* second token is version number */
    109  |       nrtm_q->version=atoi(tokens[1]);
    110  |       if(tokens[2]) {
    111  | 	/* this is first serial */
    112  |         nrtm_q->first=atol(tokens[2]);
    113  |           if(tokens[3]) {
    114  |             /* this is last serial */
    115  |               nrtm_q->last=atol(tokens[3]);
    116  |           } else res=-1;
    117  |       } else res=-1;
    118  |     } else res=-1;
    119  |  } else res=-1;
    120  |  g_strfreev(tokens);
    121  |
    122  | return(res);
    123  | }
    124  |
    125  |
    126  | /* PM_interact() */
    127  | /*++++++++++++++++++++++++++++++++++++++
    128  |   Interact with the client.
    129  |
    130  |   int sock Socket that client is connected to.
    131  |
    132  |   More:
    133  |   +html+ <PRE>
    134  |   Authors:
    135  |         ottrey
    136  |         andrei
    137  |
    138  |   +html+ </PRE><DL COMPACT>
    139  |   +html+ <DT>Online References:
    140  |   +html+ <DD><UL>
    141  |   +html+ </UL></DL>
    142  |
    143  |   ++++++++++++++++++++++++++++++++++++++*/
    144  | void PM_interact(int sock) {
    145  |   char input[MAX_INPUT_SIZE];
    146  |   ca_dbSource_t *source_hdl;
    147  |   int read_result;
    148  |   int parse_result;
    149  |
    150  |
    151  |   char *hostaddress=NULL;
    152  | //  acl_st acl_rip,   acl_eip;
    153  |
    154  |   sk_conn_st condat;
    155  |   nrtm_q_t nrtm_q;
    156  |   long current_serial;
    157  |   long oldest_serial;
    158  |
    159  |   char *object;
    160  |   int operation;
    161  |   char buff[STR_S];
    162  |
    163  |   const char *db_host;
    164  |   int  db_port;
    165  |   const char *db_name;
    166  |   const char *db_user;
    167  |   const char *db_pswd;
    168  |
    169  |   GString *gbuff;
    170  |
    171  |   SQ_connection_t *sql_connection;
    172  |
    173  |   /* make a record for thread accounting */
    174  |   TA_add(sock, "nrtm_srv");
    175  |
    176  |
    177  |   /* Get the IP of the client */
    178  |   hostaddress = SK_getpeername(sock);
    179  |   printf("SK address: %s\n", hostaddress);
    180  |
    181  |   /* initialise the connection structure */
    182  |   memset( &condat, 0, sizeof(sk_conn_st));
    183  |   /* set the connection data: both rIP and eIP to real IP */
    184  |   condat.sock = sock;
    185  |   condat.ip = hostaddress;
    186  |   SK_getpeerip(sock, &(condat.rIP));
    187  |   memcpy( &(condat.eIP), &(condat.rIP), sizeof(ip_addr_t));
    188  |
    189  |
    190  |   /* Read input */
    191  |   read_result = SK_cd_gets(&(condat), input, MAX_INPUT_SIZE);
    192  |
    193  |   /* read_result < 0 is an error and connection should be closed */
    194  |   if (read_result < 0 ) {
    195  |       /* log the fact, rtc was set */
    196  | //not yet, SK_... returns arb number      return;
    197  |   }
    198  |
    199  |   parse_result = parse_request(input, &nrtm_q);
    200  |   if (parse_result < 0 ) {
    201  |       fprintf(stderr, "Garbage received: %s\n", input);
    202  |       /* log the fact and exit */
    203  |       /* Free the hostaddress */
    204  |       SK_cd_close(&(condat));
    205  |       free(hostaddress);
    206  |       return;
    207  |   }
    208  |   if (parse_result == 1 ) {
    209  |
    210  |      fprintf(stderr, "-q sources\n");
    211  |      gbuff=PM_get_nrtm_sources(&(condat.rIP), nrtm_q.source);
    212  |      SK_cd_puts(&condat, gbuff->str);
    213  |      /* Free allocated memory  */
    214  |      g_string_free(gbuff, TRUE);
    215  |      free(hostaddress);
    216  |      free(nrtm_q.source);
    217  |      SK_cd_close(&(condat));
    218  |      return;
    219  |   }
    220  |
    221  |
    222  |
    223  |   source_hdl = ca_get_SourceHandleByName(nrtm_q.source);
    224  |   /* get database */
    225  | /*  db_name=CO_get_database(); */
    226  |   db_name = ca_get_srcdbname(source_hdl);
    227  |
    228  |   /* get database host*/
    229  | /*  db_host=CO_get_host();*/
    230  |   db_host = ca_get_srcdbmachine(source_hdl);
    231  |   /* get database port*/
    232  | /*  db_port=CO_get_database_port();*/
    233  |   db_port = ca_get_srcdbport(source_hdl);
    234  |   /* get database user*/
    235  | /*  db_user=CO_get_user(); */
    236  |   db_user = ca_get_srcdbuser(source_hdl);
    237  |   /* get database password*/
    238  | /*  db_pswd=CO_get_password(); */
    239  |   db_pswd = ca_get_srcdbpassword(source_hdl);
    240  |
    241  |   fprintf(stderr, "D: Making SQL connection to %s@%s ...", db_name, db_host);
    242  |   sql_connection = SQ_get_connection(db_host, db_port,db_name, db_user, db_pswd);
    243  |   if(!sql_connection) {
    244  |       fprintf(stderr, "E: ERROR: no SQL connection\n");
    245  |       return;
    246  |   }
    247  |   fprintf(stderr, "OK\n");
    248  |
    249  |   /* free copies of the variables */
    250  |   free(db_host);
    251  |   free(db_name);
    252  |   free(db_user);
    253  |   free(db_pswd);
    254  |
    255  |   current_serial=PM_get_current_serial(sql_connection);
    256  |   oldest_serial=PM_get_oldest_serial(sql_connection);
    257  |
    258  |   if((current_serial==-1) || (oldest_serial==-1)) {
    259  |       fprintf(stderr, "E: ERROR: cannot get serial #\n");
    260  |       /* Free the hostaddress */
    261  |       SK_cd_close(&(condat));
    262  |       free(hostaddress);
    263  |       return;
    264  |   }
    265  |
    266  |   /* zero indicates that LAST keyword has been used */
    267  |   if(nrtm_q.last==0)nrtm_q.last=current_serial;
    268  |
    269  |
    270  |   if((nrtm_q.first>nrtm_q.last) || (nrtm_q.first<oldest_serial) || (nrtm_q.last>current_serial)) {
    271  |       if(nrtm_q.first<oldest_serial) nrtm_q.last=oldest_serial-1;
    272  |       if(nrtm_q.last>current_serial) nrtm_q.first=current_serial+1;
    273  |       fprintf(stderr, "E: ERROR: invalid range\n");
    274  |       /* write error message back to the client */
    275  |       sprintf(buff, "%%ERROR:4: Invalid range: serial(s) %ld-%ld don't exist\n", nrtm_q.first, nrtm_q.last);
    276  |       sprintf(buff, "%%ERROR:4: Invalid range: Not within %ld-%ld \n", oldest_serial, current_serial);
    277  |       SK_cd_puts(&condat, buff);
    278  |       /* Free the hostaddress */
    279  |       free(hostaddress);
    280  |       free(nrtm_q.source);
    281  |       SK_cd_close(&(condat));
    282  |       return;
    283  |   }
    284  |
    285  |   current_serial=nrtm_q.first;
    286  |   /* print banner */
    287  |
    288  |   sprintf(buff, "%%START Version:%d %s %ld-%ld\n", nrtm_q.version, nrtm_q.source, nrtm_q.first, nrtm_q.last);
    289  |   SK_cd_puts(&condat, buff);
    290  |
    291  |   /* make a record for thread accounting */
    292  |   TA_setactivity(buff);
    293  |
    294  | /* now start feeding client with data */
    295  |   do {
    296  |
    297  |     object=PM_get_serial_object(sql_connection, current_serial, &operation);
    298  |     if (operation == OP_ADD) SK_cd_puts(&condat, "\nADD\n\n");
    299  |     else SK_cd_puts(&condat, "\nDEL\n\n");
    300  |
    301  |     SK_cd_puts(&condat, object);
    302  |
    303  |
    304  |     current_serial++;
    305  |
    306  |
    307  |   } /* do */
    308  |    while((current_serial<=nrtm_q.last) && (condat.rtc == 0));
    309  |
    310  |
    311  |   sprintf(buff, "\n%%END %s\n\n", nrtm_q.source);
    312  |   SK_cd_puts(&condat, buff);
    313  |
    314  |   /* make a record for thread accounting */
    315  |   TA_delete();
    316  |
    317  |   SK_cd_close(&(condat));
    318  |   /* Free the hostaddress */
    319  |   free(hostaddress);
    320  |   free(nrtm_q.source);
    321  |
    322  |
    323  |
    324  | } /* PM_interact() */