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