1    | /***************************************
2    |   $Revision: 1.19 $
3    | 
4    |   Protocol whois module (pw).  Whois protocol.
5    | 
6    |   Status: NOT REVUED, NOT TESTED
7    | 
8    |   ******************/ /******************
9    |   Filename            : protocol_whois.c
10   |   Author              : ottrey@ripe.net
11   |   OSs Tested          : Solaris
12   |   ******************/ /******************
13   |   Copyright (c) 1999                              RIPE NCC
14   |  
15   |   All Rights Reserved
16   |   
17   |   Permission to use, copy, modify, and distribute this software and its
18   |   documentation for any purpose and without fee is hereby granted,
19   |   provided that the above copyright notice appear in all copies and that
20   |   both that copyright notice and this permission notice appear in
21   |   supporting documentation, and that the name of the author not be
22   |   used in advertising or publicity pertaining to distribution of the
23   |   software without specific, written prior permission.
24   |   
25   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
26   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
27   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
28   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
29   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
30   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31   |   ***************************************/
32   | #include <stdio.h>
33   | #include <glib.h>
34   | 
35   | #include "NAME"
36   | 
37   | #include "defs.h"
38   | #include "protocol_whois.h"
39   | #include "mysql_driver.h"
40   | #include "query_command.h"
41   | #include "query_instructions.h"
42   | #include "constants.h"
43   | /*
44   | #include "objects.h"
45   | */
46   | #include "access_control.h"
47   | #include "socket.h"
48   | #include "stubs.h"
49   | 
50   | void print_hello_banner(Query_environ *qe) { 
51   |   char *str1=NULL;
52   | 
53   |   SK_cd_puts(&(qe->condat), CVS_NAME);
54   |   SK_cd_puts(&(qe->condat), "% Rights restricted by copyright. See http://www.ripe.net/db/dbcopyright.html\n");
55   |   /* Send the environment aswell. */
56   |   SK_cd_puts(&(qe->condat), "% Environment={");
57   |   str1 = QC_environ_to_string(*qe);
58   |   SK_cd_puts(&(qe->condat), str1);
59   |   wr_free(str1);
60   |   SK_cd_puts(&(qe->condat), "}\n\n");
61   | }
62   | 
63   | /* PW_interact() */
64   | /*++++++++++++++++++++++++++++++++++++++
65   |   Interact with the client.
66   | 
67   |   int sock Socket that client is connected to.
68   | 
69   |   More:
70   |   +html+ <PRE>
71   |   Authors:
72   |         ottrey
73   | 
74   |   +html+ </PRE><DL COMPACT>
75   |   +html+ <DT>Online References:
76   |   +html+ <DD><UL>
77   |   +html+ </UL></DL>
78   | 
79   |   ++++++++++++++++++++++++++++++++++++++*/
80   | void PW_interact(int sock) {
81   |   char input[MAX_INPUT_SIZE];
82   |   int read_result;
83   |   char *hostaddress=NULL;
84   |   acl_st acl_rip,   acl_eip;
85   |   acc_st acc_credit, copy_credit;
86   |   int permanent_ban=0;  
87   |   Query_environ *qe=NULL;
88   |   Query_instructions *qis=NULL;
89   |   Query_command *qc=NULL;
90   |   GList *qitem;
91   |   int new_connection=1;
92   |   int acc_deny=0;
93   | 
94   |   /* Get the IP of the client */
95   |   hostaddress = SK_getpeername(sock);
96   |   printf("SK address: %s\n", hostaddress);
97   |   
98   |   /* Initialize the query environment. */
99   |   qe = QC_environ_new(hostaddress, sock);
100  |   
101  |   /* init to zeros */
102  |   memset( &(qe->condat), 0, sizeof(sk_conn_st));
103  | 
104  |   /* set the connection data: both rIP and eIP to real IP */
105  |   qe->condat.sock = sock;
106  |   qe->condat.ip = hostaddress;
107  |   SK_getpeerip(sock, &(qe->condat.rIP));
108  |   memcpy( &(qe->condat.eIP), &(qe->condat.rIP), sizeof(ip_addr_t));
109  | 
110  |   /* see if we should be talking at all */
111  |   /* check the acl using the realIP, get a copy applicable to this IP */
112  |   AC_check_acl( &(qe->condat.rIP), NULL, &acl_rip);
113  |   if( acl_rip.deny ) {
114  |     permanent_ban=1;
115  |   }
116  |   
117  |   /* XXX log new connection here ?*/
118  | 
119  |   do {
120  |     /* Read input */
121  |     read_result = SK_cd_gets(&(qe->condat), input, MAX_INPUT_SIZE);
122  |     
123  |     /* read_result < 0 is an error and connection should be closed */
124  |     if (read_result < 0 ) {
125  |       /* log the fact, rtc was set */
126  |     }
127  |     
128  |     qc = QC_create(input, qe);
129  | 
130  |     /* ADDRESS PASSING: check if -V option has passed IP in it */
131  |     if( ! STRUCT_EQUAL(qe->pIP,IP_ADDR_UNSPEC)) {
132  |       if(acl_rip.trustpass) {     
133  | 	acc_st pass_acc;
134  | 
135  | 	/* accounting */
136  | 	memset(&pass_acc, 0, sizeof(acc_st));
137  | 	pass_acc.addrpasses=1;
138  | 	AC_commit( &qe->condat.rIP, &pass_acc, &acl_rip);
139  | 
140  | 	/* set eIP to this IP */
141  | 	qe->condat.eIP = qe->pIP;                 
142  |       }
143  |       else {
144  | 	/* XXX shall we deny such user ? Now we can... */
145  | 	log_inst_print("unathorised address passing");
146  |       }
147  |     }
148  |     else {
149  |       qe->condat.eIP = qe->condat.rIP;               /* set eIP to rIP */
150  |     }
151  |     
152  |     /* start setting counters in the connection acc from here on 
153  |        decrement the credit counter (needed to prevent QI_execute from
154  |        returning too many results */
155  |     
156  |     /* check ACL. Get the proper acl record. Calculate credit */
157  |     AC_check_acl( &(qe->condat.eIP), &acc_credit, &acl_eip);
158  |     /* save the original credit, later check how much was used */
159  |     copy_credit = acc_credit;
160  | 
161  |     if( acl_eip.deny ) {
162  |       permanent_ban = 1;
163  |     }
164  |     
165  |     if( qe->condat.rtc == 0 ) {
166  |       print_hello_banner(qe);
167  | 
168  |       if( permanent_ban ) {
169  |         SK_cd_puts(&(qe->condat), 
170  | "% Sorry, access from your host has been permanently denied\n"
171  | "% because of a repeated abusive behaviour.\n"
172  | "% Please contact <ripe-dbm@ripe.net> for unblocking the access\n");
173  |       }
174  |       else {
175  | 
176  |         switch( qc->query_type ) {
177  | 	case PW_NOKEY:
178  | 	  /* some operational stuff, like -k */
179  | 	  break;
180  |         case PW_EMPTY:
181  |         
182  |           /* The user didn't specify a key, so
183  |              - print moron banner
184  |              - force disconnection of the user. */
185  |           SK_cd_puts(&(qe->condat), "% No search key specified\n");
186  |           qe->condat.rtc = SK_NOTEXT;
187  |           break;
188  |         case PW_HELP:
189  |           SK_cd_puts(&(qe->condat), "% Nothing can help you anymore...:-)\n");
190  |           break;
191  |         case PW_TEMPLATE:
192  |           if (qc->q != 0) {
193  |             SK_cd_puts(&(qe->condat), DF_get_server_query(qc->q)); 
194  |           }
195  |           if (qc->t != 0) {
196  |             SK_cd_puts(&(qe->condat), DF_get_class_template(qc->t)); 
197  |           }
198  |           if (qc->v != 0) {
199  |             SK_cd_puts(&(qe->condat), DF_get_class_template_v(qc->v)); 
200  |           }
201  |           break;
202  |         case PW_REAL:
203  |           qis = QI_new(qc,qe);
204  | 
205  | 	  /* stop as soon as further action considered meaningless */
206  |           for( qitem = g_list_first(qe->sources_list);
207  |                qitem != NULL && qe->condat.rtc == 0;
208  |                qitem = g_list_next(qitem)) {
209  |             
210  |             /* QI will decrement the credit counters */
211  |             QI_execute(qitem->data, qis, qe, &acc_credit, &acl_eip );
212  |             
213  |           }
214  |           QI_free(qis);
215  | 	  copy_credit.queries ++;
216  |           break;
217  |         default: die;
218  |         }
219  | 
220  |         /* log the connection/query/#results/time/denial to file */ 
221  | 
222  |       }
223  |       QC_free(qc);      
224  | 
225  |       /* calc. the credit used, result  into copy_credit */
226  |       AC_acc_addup(&copy_credit, &acc_credit, ACC_MINUS);
227  |       
228  |       if( new_connection ) {
229  | 	copy_credit.connections = 1;
230  | 	new_connection = 0;
231  |       }      
232  |       
233  |       if( copy_credit.denials != 0 ) {
234  | 	acc_deny = 1;
235  |       }
236  |       
237  |       /* Commit the credit. This will deny if bonus limit hit */ 
238  |       AC_commit(&(qe->condat.eIP), &copy_credit, &acl_eip); 
239  | 
240  |     } /* if still considered connected */
241  | 
242  |   } /* do */
243  |   while( qe->k && qe->condat.rtc == 0 && acc_deny == 0
244  | 	 && CO_get_whois_suspended() == 0);
245  | 
246  |   /* Free the hostaddress */
247  |   wr_free(hostaddress);
248  | 
249  |   SK_cd_close(&(qe->condat));
250  |   
251  |   /* Free the query_environ */
252  |   QC_environ_free(qe);
253  | 
254  | } /* PW_interact() */