## 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.30 $
       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 "ca_configFns.h"
      52 #include "ca_dictSyms.h"
      53 #include "ca_macros.h"
      54 #include "ca_srcAttribs.h"
      55
      56 #include "protocol_mirror.h"
      57
      58 #include "ta.h"
      59
      60 #include  "timediff.h"
      61
      62 void print_hello_banner(Query_environ *qe) {
         /* [<][>][^][v][top][bottom][index][help] */
      63   SK_cd_puts(&(qe->condat), CVS_NAME);
      64   SK_cd_puts(&(qe->condat), "% Rights restricted by copyright. \n% See http://www.ripe.net/ripencc/pub-services/db/copyright.html\n");
      65
      66 #if 0
      67   /* Send the environment aswell. */
      68   SK_cd_puts(&(qe->condat), "% Environment={");
      69   str1 = QC_environ_to_string(*qe);
      70   SK_cd_puts(&(qe->condat), str1);
      71   wr_free(str1);
      72   SK_cd_puts(&(qe->condat), "}\n");
      73 #endif
      74
      75   SK_cd_puts(&(qe->condat), "\n");
      76 }
      77
      78 /* PW_interact() */
      79 /*++++++++++++++++++++++++++++++++++++++
      80   Interact with the client.
      81
      82   int sock Socket that client is connected to.
      83
      84   More:
      85   +html+ <PRE>
      86   Authors:
      87         ottrey
      88
      89   +html+ </PRE><DL COMPACT>
      90   +html+ <DT>Online References:
      91   +html+ <DD><UL>
      92   +html+ </UL></DL>
      93
      94   ++++++++++++++++++++++++++++++++++++++*/
      95 void PW_interact(int sock) {
         /* [<][>][^][v][top][bottom][index][help] */
      96   char input[MAX_INPUT_SIZE];
      97   int read_result;
      98   char *hostaddress=NULL;
      99   acl_st acl_rip,   acl_eip;
     100   acc_st acc_credit, copy_credit;
     101   int permanent_ban=0;
     102   Query_environ *qe=NULL;
     103   Query_instructions *qis=NULL;
     104   Query_command *qc=NULL;
     105   GList *qitem;
     106   ut_timer_t begintime, endtime;
     107   er_ret_t err;
     108
     109   /* Get the IP of the client */
     110   hostaddress = SK_getpeername(sock);
     111   ER_dbg_va(FAC_PW, 1, "connection from %s", hostaddress);
     112
     113   /* Initialize the query environment. */
     114   qe = QC_environ_new(hostaddress, sock);
     115
     116   /* init to zeros */
     117   memset( &(qe->condat), 0, sizeof(sk_conn_st));
     118
     119   /* set the connection data: both rIP and eIP to real IP */
     120   qe->condat.sock = sock;
     121   qe->condat.ip = hostaddress;
     122   SK_getpeerip(sock, &(qe->condat.rIP));
     123   qe->condat.eIP = qe->condat.rIP;
     124
     125   qe->condat.rd_timeout.tv_sec = 180; /* read timeout */
     126
     127   /* see if we should be talking at all */
     128   /* check the acl using the realIP, get a copy applicable to this IP */
     129   AC_check_acl( &(qe->condat.rIP), NULL, &acl_rip);
     130   if( acl_rip.deny ) {
     131     permanent_ban=1;
     132   }
     133
     134   do {
     135     /* Read input */
     136     read_result = SK_cd_gets(&(qe->condat), input, MAX_INPUT_SIZE);
     137
     138     TA_setactivity(input);
     139     TA_increment();
     140
     141     UT_timeget( &begintime );
     142
     143     /* read_result < 0 is an error and connection should be closed */
     144     if (read_result < 0 ) {
     145       /*  XXX log the fact, rtc was set */
     146       /* EMPTY */
     147     }
     148
     149     qc = QC_create(input, qe);
     150
     151     /* ADDRESS PASSING: check if -V option has passed IP in it */
     152     if( ! STRUCT_EQUAL(qe->pIP,IP_ADDR_UNSPEC)) {
     153       if(acl_rip.trustpass) {
     154         acc_st pass_acc;
     155
     156         /* accounting */
     157         memset(&pass_acc, 0, sizeof(acc_st));
     158         pass_acc.addrpasses=1;
     159         AC_commit( &qe->condat.rIP, &pass_acc, &acl_rip);
     160
     161         /* set eIP to this IP */
     162         qe->condat.eIP = qe->pIP;
     163       }
     164       else {
     165         /* XXX shall we deny such user ? Now we can... */
     166         ER_inf_va(FAC_PW, ASP_PWI_PASSUN,
     167                   "unauthorised address passing by %s", hostaddress);
     168       }
     169     }
     170
     171
     172     /* start setting counters in the connection acc from here on
     173        decrement the credit counter (needed to prevent QI_execute from
     174        returning too many results */
     175
     176     /* check ACL. Get the proper acl record. Calculate credit */
     177     AC_check_acl( &(qe->condat.eIP), &acc_credit, &acl_eip);
     178     /* save the original credit, later check how much was used */
     179     copy_credit = acc_credit;
     180
     181     if( acl_eip.deny ) {
     182       permanent_ban = 1;
     183     }
     184
     185     if( qe->condat.rtc == 0 ) {
     186       print_hello_banner(qe);
     187
     188       if( permanent_ban ) {
     189         SK_cd_puts(&(qe->condat),
     190 "% Sorry, access from your host has been permanently denied\n"
     191 "% because of a repeated abusive behaviour.\n"
     192 "% Please contact <ripe-dbm@ripe.net> for unblocking\n");
     193
     194         ER_inf_va(FAC_PW, ASP_PWI_DENTRY,
     195                   "connection from host %s DENIED", hostaddress);
     196
     197       }
     198       else {
     199         switch( qc->query_type ) {
     200         case QC_ERROR:
     201           SK_cd_puts(&(qe->condat), USAGE);
     202           qe->condat.rtc = SK_NOTEXT;
     203           break;
     204         case QC_NOKEY:
     205           /* no key (this is OK for some operational stuff, like -k) */
     206           break;
     207         case QC_EMPTY:
     208
     209           /* The user didn't specify a key, so
     210              - print moron banner
     211              - force disconnection of the user. */
     212           SK_cd_puts(&(qe->condat), "% No search key specified\n");
     213           qe->condat.rtc = SK_NOTEXT;
     214           break;
     215         case QC_HELP:
     216           SK_cd_puts(&(qe->condat), "% Nothing can help you anymore...:-)\n");
     217           break;
     218         case QC_TEMPLATE:
     219           switch(qc->q) {
     220           case QC_Q_SOURCES:
     221             /* print source & mirroring info */
     222             {
     223               GString *srcs = PM_get_nrtm_sources( & qe->condat.rIP, NULL);
     224               SK_cd_puts(&(qe->condat), srcs->str);
     225               g_string_free (srcs, TRUE);
     226             }
     227             break;
     228           case QC_Q_VERSION:
     229             SK_cd_puts(&(qe->condat), DF_get_server_query(qc->q));
     230             break;
     231           default:
     232             /* EMPTY */;
     233           } /* -q */
     234
     235           if (qc->t >= 0) {
     236             SK_cd_puts(&(qe->condat), DF_get_class_template(qc->t));
     237           }
     238           if (qc->v >= 0) {
     239             SK_cd_puts(&(qe->condat), DF_get_class_template_v(qc->v));
     240           }
     241           break;
     242
     243         case QC_FILTERED:
     244           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");
     245
     246           /* FALLTROUGH */
     247         case QC_REAL:
     248           qis = QI_new(qc,qe);
     249
     250           /* stop as soon as further action considered meaningless */
     251           for( qitem = g_list_first(qe->sources_list);
     252                qitem != NULL && qe->condat.rtc == 0;
     253                qitem = g_list_next(qitem)) {
     254
     255             /* QI will decrement the credit counters */
     256             err = QI_execute(qitem->data, qis, qe, &acc_credit, &acl_eip );
     257
     258             if( !NOERR(err) ) {
     259               if( err == QI_CANTDB ) {
     260                 SK_cd_puts(&(qe->condat), "% WARNING: Failed to make connection to ");
     261                 SK_cd_puts(&(qe->condat), (char *)qitem->data);
     262                 SK_cd_puts(&(qe->condat), " database.\n\n");
     263               }
     264
     265               break; /* quit the loop after any error */
     266             }/* if */
     267
     268           }/* for */
     269
     270           /* end-of-result -> one extra line */
     271           SK_cd_puts(&(qe->condat), "\n");
     272
     273           QI_free(qis);
     274           copy_credit.queries ++;
     275
     276           if( AC_credit_isdenied(&acc_credit) ) {
     277             SK_cd_puts(&(qe->condat),
     278  "% You have reached the limit of returned contact information objects.\n"
     279  "% This connection will be terminated now.\n"
     280  "% This is a mechanism to prevent abusive use of contact data in the RIPE Database.\n"
     281  "% You will not be allowed to query for more CONTACT information for a while.\n"
     282  "% Continued attempts to return excessive amounts of contact\n"
     283  "% information will result in permanent denial of service.\n"
     284  "% Please do not try to use CONTACT information in the\n"
     285  "% RIPE Database for non-operational purposes.\n"
     286  "% Refer to http://www.ripe.net/db/dbcopyright.html for more information.\n"
     287                        );
     288           }
     289
     290           break;
     291         default: die;
     292         }
     293         /* calc. the credit used, result  into copy_credit */
     294         AC_acc_addup(&copy_credit, &acc_credit, ACC_MINUS);
     295
     296         {
     297           char *qrystat = AC_credit_to_string(&copy_credit);
     298           float elapsed;
     299           char *qrytypestr =
     300             qc->query_type == QC_REAL ? "" : QC_get_qrytype(qc->query_type);
     301
     302           UT_timeget(&endtime);
     303
     304           elapsed = UT_timediff( &begintime, &endtime);
     305
     306           /* log the connection/query/#results/time/denial to file */
     307           ER_inf_va(FAC_PW, ASP_PWI_QRYLOG,
     308                     "<%s> %s%s %.2fs [%s] --  %s",
     309                     qrystat,
     310                     qe->condat.rtc ? "INT " : "",
     311                     qrytypestr,
     312                     elapsed, hostaddress, input
     313                     );
     314           wr_free(qrystat);
     315         }
     316
     317       }/* if denied ... else */
     318
     319       QC_free(qc);
     320
     321       copy_credit.connections = 1;
     322       /* Commit the credit. This will deny if bonus limit hit */
     323       AC_commit(&(qe->condat.eIP), &copy_credit, &acl_eip);
     324     } /* if still considered connected */
     325
     326   } /* do */
     327   while( qe->k && qe->condat.rtc == 0
     328          && AC_credit_isdenied( &copy_credit ) == 0
     329          && CO_get_whois_suspended() == 0);
     330
     331   /* Free the hostaddress */
     332   wr_free(hostaddress);
     333
     334   SK_cd_close(&(qe->condat));
     335
     336   /* Free the query_environ */
     337   QC_environ_free(qe);
     338
     339 } /* PW_interact() */

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