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