]> jfr.im git - irc/quakenet/newserv.git/blob - proxyscan/proxyscandb.c
Added 'showkill' and 'spew' commands (with associated functions) - also cleaned up...
[irc/quakenet/newserv.git] / proxyscan / proxyscandb.c
1
2 /*
3 * proxyscandb:
4 * Handles the database interface routines for proxyscan.
5 */
6
7 #include "proxyscan.h"
8
9 #include <mysql/mysql.h>
10 #include "../core/config.h"
11 #include "../lib/sstring.h"
12 #include "../irc/irc_config.h"
13 #include "../lib/irc_string.h"
14 #include "../core/error.h"
15 #include "../nick/nick.h"
16 #include "../localuser/localuser.h"
17 #include <string.h>
18 #include <stdio.h>
19
20 MYSQL proxyscansql;
21 unsigned int lastid;
22 int sqlconnected;
23
24 /*
25 * proxyscandbinit():
26 * Connects to the database and recovers the last gline ID
27 */
28
29 int proxyscandbinit() {
30 sstring *dbhost,*dbusername,*dbpassword,*dbdatabase,*dbport;
31 MYSQL_RES *myres;
32 MYSQL_ROW myrow;
33
34 sqlconnected=0;
35
36 dbhost=getcopyconfigitem("proxyscan","dbhost","localhost",HOSTLEN);
37 dbusername=getcopyconfigitem("proxyscan","dbusername","proxyscan",20);
38 dbpassword=getcopyconfigitem("proxyscan","dbpassword","moo",20);
39 dbdatabase=getcopyconfigitem("proxyscan","dbdatabase","proxyscan",20);
40 dbport=getcopyconfigitem("proxyscan","dbport","3306",8);
41
42 mysql_init(&proxyscansql);
43 if (!mysql_real_connect(&proxyscansql,dbhost->content,dbusername->content,
44 dbpassword->content,dbdatabase->content,
45 strtol(dbport->content,NULL,10), NULL, 0)) {
46 Error("proxyscan",ERR_ERROR,"Unable to connect to database");
47 return 1;
48 }
49
50 freesstring(dbhost);
51 freesstring(dbusername);
52 freesstring(dbpassword);
53 freesstring(dbdatabase);
54 freesstring(dbport);
55
56 sqlconnected=1;
57
58 /* Set up the table */
59 mysql_query(&proxyscansql,"CREATE TABLE openproxies (ID BIGINT not null, IP VARCHAR (20) not null, PM INT not null, TS DATETIME not null, RH TEXT not null, PRIMARY KEY (ID), INDEX (ID), UNIQUE (ID))");
60
61 /* Get max ID */
62 if ((mysql_query(&proxyscansql,"SELECT max(ID) FROM openproxies"))!=0) {
63 Error("proxyscan",ERR_ERROR,"Unable to retrieve max ID from database");
64 return 1;
65 }
66
67 myres=mysql_store_result(&proxyscansql);
68 if (mysql_num_fields(myres)!=1) {
69 Error("proxyscan",ERR_ERROR,"Weird format retrieving max ID");
70 mysql_free_result(myres);
71 return 1;
72 }
73
74 lastid=0;
75 if ((myrow=mysql_fetch_row(myres))) {
76 if (myrow[0]==NULL) {
77 lastid=0;
78 } else {
79 lastid=strtol(myrow[0],NULL,10);
80 }
81 Error("proxyscan",ERR_INFO,"Retrieved lastid %d from database.",lastid);
82 }
83
84 mysql_free_result(myres);
85 return 0;
86 }
87
88 /*
89 * scantostr:
90 * Given a scan number, returns the string associated.
91 */
92
93 const char *scantostr(int type) {
94 char *reason="UNKNOWN";
95
96 switch (type) {
97 case STYPE_SOCKS4:
98 reason="socks4";
99 break;
100
101 case STYPE_SOCKS5:
102 reason="socks5";
103 break;
104
105 case STYPE_HTTP:
106 reason="http";
107 break;
108
109 case STYPE_WINGATE:
110 reason="wingate";
111 break;
112
113 case STYPE_CISCO:
114 reason="router";
115 break;
116
117 case STYPE_DIRECT:
118 reason="forward";
119 break;
120 }
121
122 return reason;
123 }
124
125 /*
126 * scantobm:
127 * Given a scan number, returns the bitmask associated (as used in the
128 * previous version of P)
129 */
130
131 int scantodm(int scannum) {
132 return (1<<scannum);
133 }
134
135 /*
136 * loggline:
137 * This function takes the given scanhost (which is assumed to have
138 * at least one "OPEN" scan) and logs it to the database. It returns
139 * the unique ID assigned to this gline (for the gline message itself).
140 */
141
142 void loggline(cachehost *chp) {
143 char reasonlist[100];
144 char reasonesc[100];
145 char sqlquery[4000];
146 int reasonmask=0;
147 int reasonpos=0;
148 foundproxy *fpp;
149
150 if (brokendb) {
151 chp->glineid=1;
152 return;
153 }
154
155 reasonlist[0]='\0';
156 reasonmask=0;
157 for (fpp=chp->proxies;fpp;fpp=fpp->next) {
158 reasonpos += sprintf(reasonlist+reasonpos, "%s:%d ",scantostr(fpp->type), fpp->port);
159 }
160
161 if (chp->glineid==0) {
162 chp->glineid=++lastid;
163
164 mysql_escape_string(reasonesc,reasonlist,strlen(reasonlist));
165 sprintf(sqlquery,"INSERT INTO openproxies VALUES(%u,'%s',%d,NOW(),'%s')",chp->glineid,
166 IPtostr(chp->IP),reasonmask,reasonesc);
167 mysql_query(&proxyscansql,sqlquery);
168 } else {
169 mysql_escape_string(reasonesc,reasonlist,strlen(reasonlist));
170 sprintf(sqlquery,"UPDATE openproxies SET PM=%d,RH='%s' where ID=%u",
171 reasonmask,reasonesc,chp->glineid);
172 mysql_query(&proxyscansql,sqlquery);
173 }
174 }
175
176 /*
177 * proxyscandbclose:
178 * Closes the db socket when proxyscan is unloaded
179 */
180
181 void proxyscandbclose() {
182 if (sqlconnected==1) {
183 mysql_close(&proxyscansql);
184 }
185 }
186
187 /*
188 * proxyscandolistopen:
189 * Lists all the open proxies found since <since> to user usernick.
190 */
191
192 void proxyscandolistopen(nick *mynick, nick *usernick, time_t snce) {
193 char mysqlquery[2000];
194 char timestmp[30];
195 MYSQL_RES *myres;
196 MYSQL_ROW myrow;
197
198 strftime(timestmp,30,"%Y-%m-%d %H:%M:%S",localtime(&snce));
199 sprintf(mysqlquery,"SELECT IP,TS,RH FROM openproxies WHERE TS>'%s' ORDER BY TS",timestmp);
200
201 if ((mysql_query(&proxyscansql,mysqlquery))!=0) {
202 sendnoticetouser(mynick,usernick,"Error performing database query!");
203 Error("proxyscan",ERR_ERROR,"Error performing listopen query");
204 return;
205 }
206
207 myres=mysql_use_result(&proxyscansql);
208 if (mysql_num_fields(myres)!=3) {
209 sendnoticetouser(mynick,usernick,"Error performing database query!");
210 Error("proxyscan",ERR_ERROR,"Error performing listopen query");
211 return;
212 }
213
214 sendnoticetouser(mynick,usernick,"%-20s %-22s %s","IP","Found at","What was open");
215 while ((myrow=mysql_fetch_row(myres))) {
216 sendnoticetouser(mynick,usernick,"%-20s %-22s %s",myrow[0],myrow[1],myrow[2]);
217 }
218 sendnoticetouser(mynick,usernick,"--- End of list ---");
219 mysql_free_result(myres);
220 }
221
222 /*
223 * proxyscanspewip
224 * Check db for open proxies matching the given IP, send to user usernick.
225 */
226
227 void proxyscanspewip(nick *mynick, nick *usernick, unsigned long a, unsigned long b, unsigned long c, unsigned long d) {
228 char mysqlquery[2000];
229 MYSQL_RES *myres;
230 MYSQL_ROW myrow;
231
232 sprintf(mysqlquery, "SELECT ID,IP,TS,RH FROM openproxies WHERE IP='%lu.%lu.%lu.%lu' ORDER BY TS DESC LIMIT 10",a,b,c,d);
233
234 if ((mysql_query(&proxyscansql,mysqlquery))!=0) {
235 sendnoticetouser(mynick,usernick,"Error performing database query!");
236 Error("proxyscan",ERR_ERROR,"Error performing spew query");
237 return;
238 }
239
240 myres=mysql_use_result(&proxyscansql);
241 if (mysql_num_fields(myres)!=4) {
242 sendnoticetouser(mynick,usernick,"Error performing database query!");
243 Error("proxyscan",ERR_ERROR,"Error performing spew query");
244 return;
245 }
246
247 sendnoticetouser(mynick,usernick,"%-5s %-20s %-22s %s","ID","IP","Found at","What was open");
248 while ((myrow=mysql_fetch_row(myres))) {
249 sendnoticetouser(mynick,usernick,"%-5s %-20s %-22s %s",myrow[0],myrow[1],myrow[2],myrow[3]);
250 }
251 sendnoticetouser(mynick,usernick,"--- End of list ---");
252 mysql_free_result(myres);
253 }
254
255 /*
256 * proxyscanshowkill
257 * Check db for open proxies matching the given kill/gline ID, send to user usernick.
258 */
259
260 void proxyscanshowkill(nick *mynick, nick *usernick, unsigned long a) {
261 char mysqlquery[2000];
262 MYSQL_RES *myres;
263 MYSQL_ROW myrow;
264
265 sprintf(mysqlquery, "SELECT ID,IP,TS,RH FROM openproxies WHERE ID='%lu'",a);
266
267 if ((mysql_query(&proxyscansql,mysqlquery))!=0) {
268 sendnoticetouser(mynick,usernick,"Error performing database query!");
269 Error("proxyscan",ERR_ERROR,"Error performing showkill query");
270 return;
271 }
272
273 myres=mysql_use_result(&proxyscansql);
274 if (mysql_num_fields(myres)!=4) {
275 sendnoticetouser(mynick,usernick,"Error performing database query!");
276 Error("proxyscan",ERR_ERROR,"Error performing showkill query");
277 return;
278 }
279
280 sendnoticetouser(mynick,usernick,"%-5s %-20s %-22s %s","ID","IP","Found at","What was open");
281 /* even though we should only ever have 1 result, still loop below - who knows eh? */
282 while ((myrow=mysql_fetch_row(myres))) {
283 sendnoticetouser(mynick,usernick,"%-5s %-20s %-22s %s",myrow[0],myrow[1],myrow[2],myrow[3]);
284 }
285 sendnoticetouser(mynick,usernick,"--- End of list ---");
286 mysql_free_result(myres);
287 }