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