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(©_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), ©_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() */