## modules/pm/protocol_mirror.c

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. parse_request
2. PM_interact

       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)
         /* [<][>][^][v][top][bottom][index][help] */
      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) {
         /* [<][>][^][v][top][bottom][index][help] */
     145   char input[MAX_INPUT_SIZE];
     146   ca_dbSource_t *source_hdl;
     147   int read_result;
     148   int parse_result;
     149   ip_addr_t address;
     150
     151
     152
     153   char *hostaddress=NULL;
     154 //  acl_st acl_rip,   acl_eip;
     155
     156   sk_conn_st condat;
     157   nrtm_q_t nrtm_q;
     158   long current_serial;
     159   long oldest_serial;
     160
     161   char *object;
     162   int operation;
     163   char buff[STR_S];
     164
     165   const char *db_host;
     166   int  db_port;
     167   const char *db_name;
     168   const char *db_user;
     169   const char *db_pswd;
     170
     171   GString *gbuff;
     172
     173   SQ_connection_t *sql_connection;
     174
     175   /* make a record for thread accounting */
     176   TA_add(sock, "nrtm_srv");
     177
     178
     179   /* Get the IP of the client */
     180   hostaddress = SK_getpeername(sock);
     181   printf("SK address: %s\n", hostaddress);
     182
     183   /* initialise the connection structure */
     184   memset( &condat, 0, sizeof(sk_conn_st));
     185   /* set the connection data: both rIP and eIP to real IP */
     186   condat.sock = sock;
     187   condat.ip = hostaddress;
     188   SK_getpeerip(sock, &(condat.rIP));
     189   memcpy( &(condat.eIP), &(condat.rIP), sizeof(ip_addr_t));
     190
     191
     192   /* Read input */
     193   read_result = SK_cd_gets(&(condat), input, MAX_INPUT_SIZE);
     194
     195   /* read_result < 0 is an error and connection should be closed */
     196   if (read_result < 0 ) {
     197       /* log the fact, rtc was set */
     198 //not yet, SK_... returns arb number      return;
     199   }
     200
     201   parse_result = parse_request(input, &nrtm_q);
     202   if (parse_result < 0 ) {
     203       fprintf(stderr, "Garbage received: %s\n", input);
     204       /* log the fact and exit */
     205       /* Free the hostaddress */
     206       SK_cd_close(&(condat));
     207       free(hostaddress);
     208       free(nrtm_q.source);
     209       return;
     210   }
     211   if (parse_result == 1 ) {
     212
     213      fprintf(stderr, "-q sources\n");
     214      gbuff=PM_get_nrtm_sources(&(condat.rIP), nrtm_q.source);
     215      SK_cd_puts(&condat, gbuff->str);
     216      /* Free allocated memory  */
     217      g_string_free(gbuff, TRUE);
     218      free(hostaddress);
     219      free(nrtm_q.source);
     220      SK_cd_close(&(condat));
     221      return;
     222   }
     223
     224   source_hdl = ca_get_SourceHandleByName(nrtm_q.source);
     225   if (source_hdl == NULL){
     226      sprintf(buff, "\n%%ERROR 6: Unknown source\n\n");
     227      SK_cd_puts(&condat, buff);
     228      free(hostaddress);
     229      free(nrtm_q.source);
     230      SK_cd_close(&(condat));
     231      return;
     232   }
     233
     234   /* check if the client is authorized to mirror */
     235   SK_getpeerip(sock, &address);
     236   if(!AA_can_mirror(&address, nrtm_q.source)){
     237      sprintf(buff, "\n%%ERROR 5: You are not authorized to mirror the database\n\n");
     238      SK_cd_puts(&condat, buff);
     239      free(hostaddress);
     240      free(nrtm_q.source);
     241      SK_cd_close(&(condat));
     242      return;
     243   }
     244
     245
     246
     247   /* get database */
     248 /*  db_name=CO_get_database(); */
     249   db_name = ca_get_srcdbname(source_hdl);
     250
     251   /* get database host*/
     252 /*  db_host=CO_get_host();*/
     253   db_host = ca_get_srcdbmachine(source_hdl);
     254   /* get database port*/
     255 /*  db_port=CO_get_database_port();*/
     256   db_port = ca_get_srcdbport(source_hdl);
     257   /* get database user*/
     258 /*  db_user=CO_get_user(); */
     259   db_user = ca_get_srcdbuser(source_hdl);
     260   /* get database password*/
     261 /*  db_pswd=CO_get_password(); */
     262   db_pswd = ca_get_srcdbpassword(source_hdl);
     263
     264   fprintf(stderr, "D: Making SQL connection to %s@%s ...", db_name, db_host);
     265   sql_connection = SQ_get_connection(db_host, db_port,db_name, db_user, db_pswd);
     266   if(!sql_connection) {
     267       fprintf(stderr, "E: ERROR: no SQL connection\n");
     268       return;
     269   }
     270   fprintf(stderr, "OK\n");
     271
     272   /* free copies of the variables */
     273   free(db_host);
     274   free(db_name);
     275   free(db_user);
     276   free(db_pswd);
     277
     278   current_serial=PM_get_current_serial(sql_connection);
     279   oldest_serial=PM_get_oldest_serial(sql_connection);
     280
     281   if((current_serial==-1) || (oldest_serial==-1)) {
     282       fprintf(stderr, "E: ERROR: cannot get serial #\n");
     283       /* Free the hostaddress */
     284       SK_cd_close(&(condat));
     285       free(hostaddress);
     286       free(nrtm_q.source);
     287       return;
     288   }
     289
     290   /* zero indicates that LAST keyword has been used */
     291   if(nrtm_q.last==0)nrtm_q.last=current_serial;
     292
     293
     294   if((nrtm_q.first>nrtm_q.last) || (nrtm_q.first<oldest_serial) || (nrtm_q.last>current_serial)) {
     295       if(nrtm_q.first<oldest_serial) nrtm_q.last=oldest_serial-1;
     296       if(nrtm_q.last>current_serial) nrtm_q.first=current_serial+1;
     297       fprintf(stderr, "E: ERROR: invalid range\n");
     298       /* write error message back to the client */
     299 /*      sprintf(buff, "%%ERROR:4: Invalid range: serial(s) %ld-%ld don't exist\n", nrtm_q.first, nrtm_q.last); */
     300       sprintf(buff, "\n%%ERROR:4: Invalid range: Not within %ld-%ld\n\n", oldest_serial, current_serial);
     301       SK_cd_puts(&condat, buff);
     302       SK_cd_close(&(condat));
     303
     304       /* Free the hostaddress */
     305       free(hostaddress);
     306       free(nrtm_q.source);
     307       return;
     308   }
     309
     310   current_serial=nrtm_q.first;
     311   /* print banner */
     312
     313   sprintf(buff, "%%START Version:%d %s %ld-%ld\n", nrtm_q.version, nrtm_q.source, nrtm_q.first, nrtm_q.last);
     314   SK_cd_puts(&condat, buff);
     315
     316   /* make a record for thread accounting */
     317   TA_setactivity(buff);
     318
     319 /* now start feeding client with data */
     320   do {
     321
     322     object=PM_get_serial_object(sql_connection, current_serial, &operation);
     323     if (operation == OP_ADD) SK_cd_puts(&condat, "\nADD\n\n");
     324     else SK_cd_puts(&condat, "\nDEL\n\n");
     325
     326     SK_cd_puts(&condat, object);
     327
     328     free(object);
     329     current_serial++;
     330
     331
     332   } /* do */
     333    while((current_serial<=nrtm_q.last) && (condat.rtc == 0));
     334
     335
     336   sprintf(buff, "\n%%END %s\n\n", nrtm_q.source);
     337   SK_cd_puts(&condat, buff);
     338
     339   /* make a record for thread accounting */
     340   TA_delete();
     341
     342   SK_cd_close(&(condat));
     343   /* Free the hostaddress */
     344   free(hostaddress);
     345   free(nrtm_q.source);
     346
     347
     348
     349 } /* PM_interact() */

/* [<][>][^][v][top][bottom][index][help] */