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] */