]>
Commit | Line | Data |
---|---|---|
c86edd1d Q |
1 | |
2 | /* | |
3 | * proxyscandb: | |
4 | * Handles the database interface routines for proxyscan. | |
5 | */ | |
6 | ||
7 | #include "proxyscan.h" | |
8 | ||
96464e2c | 9 | #include "../pqsql/pqsql.h" |
c86edd1d Q |
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> | |
96464e2c | 19 | #include <libpq-fe.h> |
c86edd1d | 20 | |
c86edd1d | 21 | unsigned int lastid; |
96464e2c P |
22 | int sqlconnected = 0; |
23 | extern nick *proxyscannick; | |
24 | ||
25 | void proxyscan_get_last_id(PGconn *dbconn, void *arg); | |
c86edd1d Q |
26 | |
27 | /* | |
28 | * proxyscandbinit(): | |
29 | * Connects to the database and recovers the last gline ID | |
30 | */ | |
31 | ||
32 | int proxyscandbinit() { | |
96464e2c | 33 | if(!pqconnected()) |
c86edd1d | 34 | return 1; |
c86edd1d | 35 | |
c86edd1d Q |
36 | sqlconnected=1; |
37 | ||
38 | /* Set up the table */ | |
96464e2c P |
39 | pqcreatequery("CREATE TABLE openproxies (" |
40 | "ID int8 not null," | |
41 | "IP inet not null," | |
42 | "PM int4 not null," | |
43 | "TS int4 not null," | |
44 | "RH varchar not null," | |
0a85c6ba | 45 | "PRIMARY KEY (ID))"); |
c86edd1d | 46 | |
96464e2c P |
47 | pqcreatequery("CREATE INDEX openproxies_id_index ON openproxies (ID)"); |
48 | ||
49 | pqasyncquery(proxyscan_get_last_id, NULL, | |
50 | "SELECT ID FROM openproxies ORDER BY id DESC LIMIT 1"); | |
c86edd1d | 51 | |
c86edd1d Q |
52 | return 0; |
53 | } | |
54 | ||
96464e2c P |
55 | void proxyscan_get_last_id(PGconn *dbconn, void *arg) { |
56 | PGresult *pgres = PQgetResult(dbconn); | |
57 | unsigned int numrows; | |
58 | ||
59 | if(PQresultStatus(pgres) != PGRES_TUPLES_OK) { | |
60 | Error("proxyscan", ERR_ERROR, "Error loading last id."); | |
61 | } | |
62 | ||
63 | numrows = PQntuples(pgres); | |
64 | if ( numrows ) | |
65 | lastid = atoi(PQgetvalue(pgres, 0, 0)); | |
66 | else | |
67 | lastid = 0; | |
68 | ||
69 | PQclear(pgres); | |
70 | Error("proxyscan",ERR_INFO,"Retrieved lastid %d from database.",lastid); | |
71 | } | |
c86edd1d Q |
72 | /* |
73 | * scantostr: | |
74 | * Given a scan number, returns the string associated. | |
75 | */ | |
76 | ||
77 | const char *scantostr(int type) { | |
78 | char *reason="UNKNOWN"; | |
79 | ||
80 | switch (type) { | |
81 | case STYPE_SOCKS4: | |
82 | reason="socks4"; | |
83 | break; | |
84 | ||
85 | case STYPE_SOCKS5: | |
86 | reason="socks5"; | |
87 | break; | |
88 | ||
89 | case STYPE_HTTP: | |
90 | reason="http"; | |
91 | break; | |
92 | ||
93 | case STYPE_WINGATE: | |
94 | reason="wingate"; | |
95 | break; | |
96 | ||
97 | case STYPE_CISCO: | |
98 | reason="router"; | |
99 | break; | |
905c2ba2 | 100 | |
101 | case STYPE_DIRECT: | |
102 | reason="forward"; | |
103 | break; | |
c86edd1d Q |
104 | } |
105 | ||
106 | return reason; | |
107 | } | |
108 | ||
109 | /* | |
110 | * scantobm: | |
111 | * Given a scan number, returns the bitmask associated (as used in the | |
112 | * previous version of P) | |
113 | */ | |
114 | ||
115 | int scantodm(int scannum) { | |
116 | return (1<<scannum); | |
117 | } | |
118 | ||
119 | /* | |
120 | * loggline: | |
121 | * This function takes the given scanhost (which is assumed to have | |
122 | * at least one "OPEN" scan) and logs it to the database. It returns | |
123 | * the unique ID assigned to this gline (for the gline message itself). | |
124 | */ | |
125 | ||
126 | void loggline(cachehost *chp) { | |
127 | char reasonlist[100]; | |
96464e2c | 128 | char reasonesc[200 + 1]; /* reasonlist*2+1 */ |
c86edd1d Q |
129 | int reasonmask=0; |
130 | int reasonpos=0; | |
131 | foundproxy *fpp; | |
132 | ||
133 | if (brokendb) { | |
134 | chp->glineid=1; | |
135 | return; | |
136 | } | |
137 | ||
138 | reasonlist[0]='\0'; | |
139 | reasonmask=0; | |
140 | for (fpp=chp->proxies;fpp;fpp=fpp->next) { | |
141 | reasonpos += sprintf(reasonlist+reasonpos, "%s:%d ",scantostr(fpp->type), fpp->port); | |
142 | } | |
143 | ||
144 | if (chp->glineid==0) { | |
145 | chp->glineid=++lastid; | |
146 | ||
96464e2c P |
147 | PQescapeString(reasonesc,reasonlist,strlen(reasonlist)); |
148 | pqquery("INSERT INTO openproxies VALUES(%u,'%s',%d,%ld,'%s')",chp->glineid, | |
149 | IPlongtostr(chp->IP),reasonmask,getnettime(),reasonesc); | |
c86edd1d | 150 | } else { |
96464e2c P |
151 | PQescapeString(reasonesc,reasonlist,strlen(reasonlist)); |
152 | pqquery("UPDATE openproxies SET PM=%d,RH='%s' where ID=%u", | |
c86edd1d | 153 | reasonmask,reasonesc,chp->glineid); |
c86edd1d Q |
154 | } |
155 | } | |
156 | ||
157 | /* | |
158 | * proxyscandbclose: | |
159 | * Closes the db socket when proxyscan is unloaded | |
160 | */ | |
161 | ||
162 | void proxyscandbclose() { | |
c86edd1d Q |
163 | } |
164 | ||
165 | /* | |
166 | * proxyscandolistopen: | |
167 | * Lists all the open proxies found since <since> to user usernick. | |
168 | */ | |
169 | ||
96464e2c P |
170 | void proxyscandolistopen_real(PGconn *dbconn, void *arg) { |
171 | nick *np=getnickbynumeric((unsigned int)arg); | |
172 | PGresult *pgres; | |
173 | int i, num; | |
c86edd1d | 174 | |
96464e2c P |
175 | pgres=PQgetResult(dbconn); |
176 | if (PQresultStatus(pgres) != PGRES_TUPLES_OK) { | |
177 | Error("proxyscan", ERR_ERROR, "Error loading data."); | |
c86edd1d Q |
178 | return; |
179 | } | |
96464e2c P |
180 | |
181 | if (PQnfields(pgres) != 3) { | |
182 | Error("proxyscan", ERR_ERROR, "data format error."); | |
183 | } | |
c86edd1d | 184 | |
96464e2c P |
185 | num=PQntuples(pgres); |
186 | ||
187 | if (!np) { | |
188 | PQclear(pgres); | |
c86edd1d Q |
189 | return; |
190 | } | |
191 | ||
96464e2c P |
192 | sendnoticetouser(proxyscannick,np,"%-20s %-22s %s","IP","Found at","What was open"); |
193 | for (i=0; i<num; i++) { | |
194 | sendnoticetouser(proxyscannick,np, "%-20s %-22s %s",PQgetvalue(pgres, i, 0), | |
195 | PQgetvalue(pgres, i, 1), | |
196 | PQgetvalue(pgres, i, 2)); | |
c86edd1d | 197 | } |
96464e2c P |
198 | sendnoticetouser(proxyscannick,np,"--- End of list ---"); |
199 | } | |
200 | ||
201 | void proxyscandolistopen(nick *mynick, nick *usernick, time_t snce) { | |
202 | ||
203 | pqasyncquery(proxyscandolistopen_real,(void *)usernick->numeric, | |
204 | "SELECT IP,TS,RH FROM openproxies WHERE TS>'%lu' ORDER BY TS",snce); | |
c86edd1d | 205 | } |
7d228b1d D |
206 | |
207 | /* | |
208 | * proxyscanspewip | |
209 | * Check db for open proxies matching the given IP, send to user usernick. | |
210 | */ | |
211 | ||
96464e2c P |
212 | void proxyscanspewip_real(PGconn *dbconn, void *arg) { |
213 | nick *np=getnickbynumeric((unsigned int)arg); | |
214 | PGresult *pgres; | |
215 | int i, num; | |
7d228b1d | 216 | |
96464e2c P |
217 | pgres=PQgetResult(dbconn); |
218 | if (PQresultStatus(pgres) != PGRES_TUPLES_OK) { | |
219 | Error("proxyscan", ERR_ERROR, "Error loading data."); | |
7d228b1d D |
220 | return; |
221 | } | |
222 | ||
96464e2c P |
223 | if (PQnfields(pgres) != 4) { |
224 | Error("proxyscan", ERR_ERROR, "data format error."); | |
225 | } | |
226 | ||
227 | num=PQntuples(pgres); | |
228 | ||
229 | if (!np) { | |
230 | PQclear(pgres); | |
7d228b1d D |
231 | return; |
232 | } | |
233 | ||
96464e2c P |
234 | sendnoticetouser(proxyscannick,np,"%-5s %-20s %-22s %s","ID","IP","Found at","What was open"); |
235 | for (i=0; i<num; i++) { | |
236 | sendnoticetouser(proxyscannick,np, "%-5s %-20s %-22s %s",PQgetvalue(pgres, i, 0), | |
237 | PQgetvalue(pgres, i, 1), | |
238 | PQgetvalue(pgres, i, 2), | |
239 | PQgetvalue(pgres, i, 3)); | |
7d228b1d | 240 | } |
96464e2c P |
241 | sendnoticetouser(proxyscannick,np,"--- End of list ---"); |
242 | } | |
243 | ||
244 | void proxyscanspewip(nick *mynick, nick *usernick, unsigned long a, unsigned long b, unsigned long c, unsigned long d) { | |
245 | pqasyncquery(proxyscanspewip_real,(void *)usernick->numeric, | |
246 | "SELECT ID,IP,TS,RH FROM openproxies WHERE IP='%lu.%lu.%lu.%lu' ORDER BY TS DESC LIMIT 10",a,b,c,d); | |
247 | ||
7d228b1d D |
248 | } |
249 | ||
250 | /* | |
251 | * proxyscanshowkill | |
252 | * Check db for open proxies matching the given kill/gline ID, send to user usernick. | |
253 | */ | |
254 | ||
96464e2c P |
255 | void proxyscanshowkill_real(PGconn *dbconn, void *arg) { |
256 | nick *np=getnickbynumeric((unsigned int)arg); | |
257 | PGresult *pgres; | |
258 | int i, num; | |
7d228b1d | 259 | |
96464e2c P |
260 | pgres=PQgetResult(dbconn); |
261 | if (PQresultStatus(pgres) != PGRES_TUPLES_OK) { | |
262 | Error("proxyscan", ERR_ERROR, "Error loading data."); | |
7d228b1d D |
263 | return; |
264 | } | |
265 | ||
96464e2c P |
266 | if (PQnfields(pgres) != 4) { |
267 | Error("proxyscan", ERR_ERROR, "data format error."); | |
268 | } | |
269 | ||
270 | num=PQntuples(pgres); | |
271 | ||
272 | if (!np) { | |
273 | PQclear(pgres); | |
7d228b1d D |
274 | return; |
275 | } | |
276 | ||
96464e2c P |
277 | sendnoticetouser(proxyscannick,np,"%-5s %-20s %-22s %s","ID","IP","Found at","What was open"); |
278 | for (i=0; i<num; i++) { | |
279 | sendnoticetouser(proxyscannick,np, "%-5s %-20s %-22s %s",PQgetvalue(pgres, i, 0), | |
280 | PQgetvalue(pgres, i, 1), | |
281 | PQgetvalue(pgres, i, 2), | |
282 | PQgetvalue(pgres, i, 3)); | |
7d228b1d | 283 | } |
96464e2c P |
284 | sendnoticetouser(proxyscannick,np,"--- End of list ---"); |
285 | } | |
286 | ||
287 | ||
288 | void proxyscanshowkill(nick *mynick, nick *usernick, unsigned long a) { | |
289 | pqasyncquery(proxyscanspewip_real,(void *)usernick->numeric, | |
290 | "SELECT ID,IP,TS,RH FROM openproxies WHERE ID='%lu'",a); | |
7d228b1d | 291 | } |