1    | /***************************************
2    | 
3    |   Protocol mirror module (pw).  Whois protocol.
4    | 
5    |   Status: NOT REVUED, NOT TESTED
6    | 
7    |   ******************/ /******************
8    |   Filename            : protocol_mirror.c
9    |   Author              : andrei
10   |   OSs Tested          : Solaris
11   |   ******************/ /******************
12   |   Copyright (c) 1999                              RIPE NCC
13   |  
14   |   All Rights Reserved
15   |   
16   |   Permission to use, copy, modify, and distribute this software and its
17   |   documentation for any purpose and without fee is hereby granted,
18   |   provided that the above copyright notice appear in all copies and that
19   |   both that copyright notice and this permission notice appear in
20   |   supporting documentation, and that the name of the author not be
21   |   used in advertising or publicity pertaining to distribution of the
22   |   software without specific, written prior permission.
23   |   
24   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
26   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
27   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30   |   ***************************************/
31   | #include <stdio.h>
32   | #include <glib.h>
33   | 
34   | #include "protocol_mirror.h"
35   | #include "mysql_driver.h"
36   | #include "constants.h"
37   | 
38   | //#include "access_control.h"
39   | #include "socket.h"
40   | #include "stubs.h"
41   | #include "ud.h"
42   | 
43   | #define MIN_ARG_LENGTH  6
44   | 
45   | static int parse_request(char *input, nrtm_q_t *nrtm_q)
46   | {
47   |  char *ptr=input;
48   |  char **tokens;
49   |  char **tokens2;
50   |  int res=0;
51   |  
52   | // return(-1);
53   |  
54   |  if(strlen(input)<MIN_ARG_LENGTH) return(-1);
55   |  res=strncmp(input, "-g", 2);
56   |  if(res!=0) return(-1);
57   |  
58   |  ptr+=2;
59   |  
60   |  
61   |  g_strchug(ptr);
62   |  tokens=g_strsplit(ptr, ":", 3);
63   |  if(tokens==NULL) return(-1);
64   |  
65   |  if(tokens[0]) {
66   |     res=strcmp(tokens[0], "RIPE");
67   |     if(res!=0) res=-1;
68   |     if(tokens[1]) {
69   |       nrtm_q->version=atoi(tokens[1]);
70   |       if(tokens[2]) {
71   |         tokens2=g_strsplit(tokens[2], "-", 2);  
72   |         if(tokens2) {
73   |           if(tokens2[0]) {
74   |              nrtm_q->first=atol(tokens2[0]);
75   |              if(tokens2[1]) {
76   |                nrtm_q->last=atol(tokens2[1]);
77   |              } else res=-1;  
78   |           } else res=-1; 
79   |          g_strfreev(tokens2);
80   |         } else res=-1;
81   |       } else res=-1;    
82   |     } else res=-1;  
83   |  } else res=-1;   
84   |  g_strfreev(tokens);
85   |  
86   | return(res);
87   | }
88   | 
89   | 
90   | /* PM_interact() */
91   | /*++++++++++++++++++++++++++++++++++++++
92   |   Interact with the client.
93   | 
94   |   int sock Socket that client is connected to.
95   | 
96   |   More:
97   |   +html+ <PRE>
98   |   Authors:
99   |         ottrey
100  |         andrei
101  | 
102  |   +html+ </PRE><DL COMPACT>
103  |   +html+ <DT>Online References:
104  |   +html+ <DD><UL>
105  |   +html+ </UL></DL>
106  | 
107  |   ++++++++++++++++++++++++++++++++++++++*/
108  | void PM_interact(int sock) {
109  |   char input[MAX_INPUT_SIZE];
110  | 
111  |   int read_result;
112  |   int parse_result;
113  |   
114  | 
115  |   char *hostaddress=NULL;
116  | //  acl_st acl_rip,   acl_eip;
117  |   
118  |   sk_conn_st condat;
119  |   nrtm_q_t nrtm_q;
120  |   long current_serial;
121  |   long oldest_serial;
122  |   
123  |   char *object;
124  |   int operation;
125  |   char buff[STR_S];
126  |   
127  |   const char *db_host;
128  |   int  db_port;
129  |   const char *db_name;
130  |   const char *db_user;
131  |   const char *db_pswd;
132  |   
133  |   SQ_connection_t *sql_connection;     
134  | 
135  |   
136  |   /* Get the IP of the client */
137  |   hostaddress = SK_getpeername(sock);
138  |   printf("SK address: %s\n", hostaddress);
139  |   
140  |   /* initialise the connection structure */
141  |   memset( &condat, 0, sizeof(sk_conn_st));
142  |   /* set the connection data: both rIP and eIP to real IP */
143  |   condat.sock = sock;
144  |   condat.ip = hostaddress;
145  |   SK_getpeerip(sock, &(condat.rIP));
146  |   memcpy( &(condat.eIP), &(condat.rIP), sizeof(ip_addr_t));
147  | 
148  | 
149  |   /* Read input */
150  |   read_result = SK_cd_gets(&(condat), input, MAX_INPUT_SIZE);
151  |     
152  |   /* read_result < 0 is an error and connection should be closed */
153  |   if (read_result < 0 ) {
154  |       /* log the fact, rtc was set */
155  | //not yet, SK_... returns arb number      return; 
156  |   }
157  |     
158  |   parse_result = parse_request(input, &nrtm_q);
159  |   if (parse_result < 0 ) {
160  |       fprintf(stderr, "Garbage received: %s\n", input);
161  |       /* log the fact and exit */
162  |       /* Free the hostaddress */
163  |       free(hostaddress);
164  |       SK_cd_close(&(condat));
165  |       return;
166  |   }
167  |     
168  |     
169  |   /* get database */
170  |   db_name=CO_get_database();
171  |       
172  |   /* get database host*/
173  |   db_host=CO_get_host();
174  |         
175  |   /* get database port*/
176  |   db_port=CO_get_database_port();
177  |           
178  |   /* get database user*/
179  |   db_user=CO_get_user();
180  |             
181  |   /* get database password*/
182  |   db_pswd=CO_get_password();
183  |               
184  |   fprintf(stderr, "D: Making SQL connection to %s@%s ...", db_name, db_host);
185  |   sql_connection = SQ_get_connection(db_host, db_port,db_name, db_user, db_pswd);
186  |   if(!sql_connection) {
187  |       fprintf(stderr, "E: ERROR: no SQL connection\n");
188  |       return;
189  |   }
190  |   fprintf(stderr, "OK\n");
191  |                                                         
192  |   current_serial=PM_get_current_serial(sql_connection);
193  |   oldest_serial=PM_get_oldest_serial(sql_connection);
194  |     
195  |   if((current_serial==-1) || (oldest_serial==-1)) {
196  |       fprintf(stderr, "E: ERROR: cannot get serial #\n");
197  |       /* Free the hostaddress */
198  |       free(hostaddress);
199  |       SK_cd_close(&(condat));
200  |       return;
201  |   }
202  |     
203  |   if(nrtm_q.last==0)nrtm_q.last=current_serial;
204  |     
205  |   if((nrtm_q.first>nrtm_q.last) || (nrtm_q.first<oldest_serial) || (nrtm_q.last>current_serial)) {
206  |       if(nrtm_q.first<oldest_serial) nrtm_q.last=oldest_serial-1;
207  |       if(nrtm_q.last>current_serial) nrtm_q.first=current_serial+1;
208  |       fprintf(stderr, "E: ERROR: invalid range\n");
209  |       /* write error message back to the client */
210  |       sprintf(buff, "%%ERROR:4: Invalid range: serial(s) %ld-%ld don't exist\n", nrtm_q.first, nrtm_q.last);
211  |       SK_cd_puts(&condat, buff);
212  |       /* Free the hostaddress */
213  |       free(hostaddress);
214  |       SK_cd_close(&(condat));
215  |       return;
216  |   }
217  |   
218  |   current_serial=nrtm_q.first;
219  |   /* print banner */
220  |   
221  |   sprintf(buff, "%%START Version:%d RIPE %ld-%ld\n", nrtm_q.version, nrtm_q.first, nrtm_q.last);
222  |   SK_cd_puts(&condat, buff);
223  |   
224  | /* now start feeding client with data */    
225  |   do {    
226  | 
227  |     object=PM_get_serial_object(sql_connection, current_serial, &operation);
228  |     if (operation == OP_ADD) SK_cd_puts(&condat, "\nADD\n\n");
229  |     else SK_cd_puts(&condat, "\nDEL\n\n");
230  |     
231  |     SK_cd_puts(&condat, object);
232  |       
233  | 
234  |     current_serial++;
235  | 
236  | 
237  |   } /* do */
238  |    while((current_serial<=nrtm_q.last) && (condat.rtc == 0));
239  | 
240  |   
241  |   sprintf(buff, "\n%%END RIPE\n\n");
242  |   SK_cd_puts(&condat, buff);
243  | 
244  |   /* Free the hostaddress */
245  |   free(hostaddress);
246  | 
247  |   SK_cd_close(&(condat));
248  |   
249  | } /* PM_interact() */