modules/pw/protocol_whois.c

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

FUNCTIONS

This source file includes following functions.
  1. print_hello_banner
  2. PW_interact

   1 /***************************************
   2   $Revision: 1.25 $
   3 
   4   Protocol whois module (pw).  Whois protocol.
   5 
   6   Status: NOT REVUED, TESTED
   7 
   8   ******************/ /******************
   9   Filename            : protocol_whois.c
  10   Authors             : ottrey@ripe.net
  11                         marek@ripe.net
  12   OSs Tested          : Solaris
  13   ******************/ /******************
  14   Copyright (c) 1999                              RIPE NCC
  15  
  16   All Rights Reserved
  17   
  18   Permission to use, copy, modify, and distribute this software and its
  19   documentation for any purpose and without fee is hereby granted,
  20   provided that the above copyright notice appear in all copies and that
  21   both that copyright notice and this permission notice appear in
  22   supporting documentation, and that the name of the author not be
  23   used in advertising or publicity pertaining to distribution of the
  24   software without specific, written prior permission.
  25   
  26   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  27   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  28   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  29   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  30   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  31   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  32   ***************************************/
  33 #include <stdio.h>
  34 #include <glib.h>
  35 
  36 #include "NAME"
  37 
  38 #include "defs.h"
  39 #include "protocol_whois.h"
  40 #include "mysql_driver.h"
  41 #include "query_command.h"
  42 #include "query_instructions.h"
  43 #include "constants.h"
  44 /*
  45 #include "objects.h"
  46 */
  47 #include "access_control.h"
  48 #include "socket.h"
  49 #include "stubs.h"
  50 
  51 #include  <sys/time.h> /* in Solaris, or time.h in BSD, 
  52                             wrrrr... the fun begins... */
  53 
  54 void print_hello_banner(Query_environ *qe) { 
     /* [<][>][^][v][top][bottom][index][help] */
  55   SK_cd_puts(&(qe->condat), CVS_NAME);
  56   SK_cd_puts(&(qe->condat), "% Rights restricted by copyright. \n% See http://www.ripe.net/ripencc/pub-services/db/copyright.html\n");
  57 
  58 #if 0
  59   /* Send the environment aswell. */
  60   SK_cd_puts(&(qe->condat), "% Environment={");
  61   str1 = QC_environ_to_string(*qe);
  62   SK_cd_puts(&(qe->condat), str1);
  63   wr_free(str1);
  64   SK_cd_puts(&(qe->condat), "}\n");
  65 #endif
  66 
  67   SK_cd_puts(&(qe->condat), "\n");
  68 }
  69 
  70 /* PW_interact() */
  71 /*++++++++++++++++++++++++++++++++++++++
  72   Interact with the client.
  73 
  74   int sock Socket that client is connected to.
  75 
  76   More:
  77   +html+ <PRE>
  78   Authors:
  79         ottrey
  80 
  81   +html+ </PRE><DL COMPACT>
  82   +html+ <DT>Online References:
  83   +html+ <DD><UL>
  84   +html+ </UL></DL>
  85 
  86   ++++++++++++++++++++++++++++++++++++++*/
  87 void PW_interact(int sock) {
     /* [<][>][^][v][top][bottom][index][help] */
  88   char input[MAX_INPUT_SIZE];
  89   int read_result;
  90   char *hostaddress=NULL;
  91   acl_st acl_rip,   acl_eip;
  92   acc_st acc_credit, copy_credit;
  93   int permanent_ban=0;  
  94   Query_environ *qe=NULL;
  95   Query_instructions *qis=NULL;
  96   Query_command *qc=NULL;
  97   GList *qitem;
  98   int new_connection=1;
  99   int acc_deny=0;
 100   struct timeval begintime, endtime;
 101   er_ret_t err;
 102   
 103   /* Get the IP of the client */
 104   hostaddress = SK_getpeername(sock);     
 105   ER_dbg_va(FAC_PW, 1, "connection from %s", hostaddress);
 106   
 107   /* Initialize the query environment. */
 108   qe = QC_environ_new(hostaddress, sock);
 109   
 110   /* init to zeros */
 111   memset( &(qe->condat), 0, sizeof(sk_conn_st));
 112 
 113   /* set the connection data: both rIP and eIP to real IP */
 114   qe->condat.sock = sock;
 115   qe->condat.ip = hostaddress;
 116   SK_getpeerip(sock, &(qe->condat.rIP));
 117   qe->condat.eIP = qe->condat.rIP;
 118 
 119   /* see if we should be talking at all */
 120   /* check the acl using the realIP, get a copy applicable to this IP */
 121   AC_check_acl( &(qe->condat.rIP), NULL, &acl_rip);
 122   if( acl_rip.deny ) {
 123     permanent_ban=1;
 124   }
 125   
 126   /* XXX log new connection here ?*/
 127   
 128   do {
 129     /* Read input */
 130     read_result = SK_cd_gets(&(qe->condat), input, MAX_INPUT_SIZE);
 131 
 132 
 133     gettimeofday(&begintime, NULL);
 134     
 135     /* read_result < 0 is an error and connection should be closed */
 136     if (read_result < 0 ) {
 137       /*  XXX log the fact, rtc was set */
 138       /* EMPTY */
 139     }
 140     
 141     qc = QC_create(input, qe);
 142 
 143     /* ADDRESS PASSING: check if -V option has passed IP in it */
 144     if( ! STRUCT_EQUAL(qe->pIP,IP_ADDR_UNSPEC)) {
 145       if(acl_rip.trustpass) {     
 146         acc_st pass_acc;
 147 
 148         /* accounting */
 149         memset(&pass_acc, 0, sizeof(acc_st));
 150         pass_acc.addrpasses=1;
 151         AC_commit( &qe->condat.rIP, &pass_acc, &acl_rip);
 152 
 153         /* set eIP to this IP */
 154         qe->condat.eIP = qe->pIP;                 
 155       }
 156       else {
 157         /* XXX shall we deny such user ? Now we can... */
 158         ER_inf_va(FAC_PW, ASP_PWI_PASSUN, 
 159                   "unauthorised address passing by %s", hostaddress);
 160       }
 161     }
 162     
 163     
 164     /* start setting counters in the connection acc from here on 
 165        decrement the credit counter (needed to prevent QI_execute from
 166        returning too many results */
 167     
 168     /* check ACL. Get the proper acl record. Calculate credit */
 169     AC_check_acl( &(qe->condat.eIP), &acc_credit, &acl_eip);
 170     /* save the original credit, later check how much was used */
 171     copy_credit = acc_credit;
 172 
 173     if( acl_eip.deny ) {
 174       permanent_ban = 1;
 175     }
 176     
 177     if( qe->condat.rtc == 0 ) {
 178       print_hello_banner(qe);
 179 
 180       if( permanent_ban ) {
 181         SK_cd_puts(&(qe->condat), 
 182 "% Sorry, access from your host has been permanently denied\n"
 183 "% because of a repeated abusive behaviour.\n"
 184 "% Please contact <ripe-dbm@ripe.net> for unblocking\n");
 185 
 186         ER_inf_va(FAC_PW, ASP_PWI_DENTRY,
 187                   "connection from host %s DENIED", hostaddress);
 188         
 189       }
 190       else {
 191         switch( qc->query_type ) {
 192         case QC_ERROR:
 193           SK_cd_puts(&(qe->condat), USAGE);
 194           break;
 195         case QC_NOKEY:
 196           /* some operational stuff, like -k */
 197           break;
 198         case QC_EMPTY:
 199         
 200           /* The user didn't specify a key, so
 201              - print moron banner
 202              - force disconnection of the user. */
 203           SK_cd_puts(&(qe->condat), "% No search key specified\n");
 204           qe->condat.rtc = SK_NOTEXT;
 205           break;
 206         case QC_HELP:
 207           SK_cd_puts(&(qe->condat), "% Nothing can help you anymore...:-)\n");
 208           break;
 209         case QC_TEMPLATE:
 210           if (qc->q >= 0) {
 211             SK_cd_puts(&(qe->condat), DF_get_server_query(qc->q)); 
 212           }
 213           if (qc->t >= 0) {
 214             SK_cd_puts(&(qe->condat), DF_get_class_template(qc->t)); 
 215           }
 216           if (qc->v >= 0) {
 217             SK_cd_puts(&(qe->condat), DF_get_class_template_v(qc->v)); 
 218           }
 219           break;
 220 
 221         case QC_FILTERED:
 222           SK_cd_puts(&(qe->condat), "% Note: this output has been filtered.\n% Only primary keys will be visible.\n% Contact information will not be shown\n\n");
 223           
 224           /* FALLTROUGH */
 225         case QC_REAL:
 226           qis = QI_new(qc,qe);
 227           
 228           /* stop as soon as further action considered meaningless */
 229           for( qitem = g_list_first(qe->sources_list);
 230                qitem != NULL && qe->condat.rtc == 0;
 231                qitem = g_list_next(qitem)) {
 232             
 233             /* QI will decrement the credit counters */
 234             err = QI_execute(qitem->data, qis, qe, &acc_credit, &acl_eip );
 235             
 236             if( !NOERR(err) ) { 
 237               if( err == QI_CANTDB ) {
 238                 SK_cd_puts(&(qe->condat), "% WARNING: Failed to make connection to ");
 239                 SK_cd_puts(&(qe->condat), (char *)qitem->data);
 240                 SK_cd_puts(&(qe->condat), " database.\n\n");
 241               }
 242 
 243               break; /* quit the loop after any error */
 244             }/* if */
 245 
 246           }/* for */
 247 
 248           /* end-of-result -> one extra line */
 249           SK_cd_puts(&(qe->condat), "\n");
 250 
 251           QI_free(qis);
 252           copy_credit.queries ++;
 253 
 254           if( acc_credit.denials != 0 ) {
 255             SK_cd_puts(&(qe->condat),
 256  "% You have reached the limit of returned contact information objects.\n"
 257  "% This connection will be terminated now.\n"
 258  "% This is a mechanism to prevent abusive use of contact data in the RIPE Database.\n"
 259  "% You will not be allowed to query for more CONTACT information for a while.\n"
 260  "% Continued attempts to return excessive amounts of contact\n"
 261  "% information will result in permanent denial of service.\n"
 262  "% Please do not try to use CONTACT information information in the\n"
 263  "% RIPE Database for non-operational purposes.\n"
 264  "% Refer to http://www.ripe.net/db/dbcopyright.html for more information.\n"
 265                        );
 266           }
 267 
 268           break;
 269         default: die;
 270         }
 271         /* calc. the credit used, result  into copy_credit */
 272         AC_acc_addup(&copy_credit, &acc_credit, ACC_MINUS);
 273         
 274         {
 275           char *qrystat = AC_credit_to_string(&copy_credit);
 276           float elapsed;          
 277           char *qrytypestr =
 278             qc->query_type == QC_REAL ? "" : QC_get_qrytype(qc->query_type);
 279 
 280           gettimeofday(&endtime, NULL);
 281 
 282           elapsed = ( endtime.tv_sec - begintime.tv_sec ) +
 283             1e-6 * ( endtime.tv_usec - begintime.tv_usec ) ;
 284 
 285           /* log the connection/query/#results/time/denial to file */ 
 286           ER_inf_va(FAC_PW, ASP_PWI_QRYLOG,
 287                     "<%s> %s %.2fs [%s] --  %s",
 288                     qrystat, qrytypestr,
 289                     elapsed, hostaddress, input
 290                     );
 291           wr_free(qrystat);
 292         }
 293         
 294       }/* if denied ... else */
 295       
 296       QC_free(qc);      
 297       
 298       if( new_connection ) {
 299         copy_credit.connections = 1;
 300         new_connection = 0;
 301       }      
 302       
 303       if( copy_credit.denials != 0 ) {
 304         acc_deny = 1;
 305       }
 306       
 307       /* Commit the credit. This will deny if bonus limit hit */ 
 308       AC_commit(&(qe->condat.eIP), &copy_credit, &acl_eip); 
 309 
 310     } /* if still considered connected */
 311 
 312   } /* do */
 313   while( qe->k && qe->condat.rtc == 0 && acc_deny == 0
 314          && CO_get_whois_suspended() == 0);
 315 
 316   /* Free the hostaddress */
 317   wr_free(hostaddress);
 318 
 319   SK_cd_close(&(qe->condat));
 320   
 321   /* Free the query_environ */
 322   QC_environ_free(qe);
 323 
 324 } /* PW_interact() */

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