/[svn]/vendor/pxys2-2.1.0/pxtarget/pxtarget.c
ViewVC logotype

Contents of /vendor/pxys2-2.1.0/pxtarget/pxtarget.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3253 - (show annotations)
Wed Apr 2 20:46:18 2014 UTC (6 years, 11 months ago) by michael
File MIME type: text/x-chdr
File size: 8084 byte(s)
- Imported pxys2-2.1.0

1 /* Copyright (C) 2006 Pascal Gloor
2 *
3 * This file is part of pxtarget (from pxys)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <unistd.h>
25 #include <inttypes.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include <sys/time.h>
29 #include <sys/wait.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <errno.h>
35 #include <time.h>
36 #include <errno.h>
37
38 #include "sha256.h"
39
40 #define RCSID "$Id: pxtarget.c,v 1.15 2006/09/10 22:24:06 spale Exp $"
41
42
43 #define HTTP_RESPONSE "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n"
44 #define COMMON_RESPONSE "*** PXSCAN STRING: "
45 #define DEFAULT_IP "0.0.0.0"
46 #define DEFAULT_PORT 9000
47 #define DEFAULT_MAX_CLI 20
48 #define ABS_MAX_CLI 1000
49
50 /* globas variables */
51 char *logfile = NULL;
52 int debug = 0;
53
54
55 /* functions */
56 char *build_sha256(char *secret);
57 void mylog(char *fmt, ...);
58 void daemonise(void);
59 void usage(char *prg);
60 void run_client(int cli, struct sockaddr_in *sockcli, char *secret);
61 int run_core(uint32_t ip, uint16_t port, char *str, unsigned int max_cli);
62
63 /* print usage */
64 void usage(char *prg) {
65 fprintf(stderr,"PX Target\n");
66 fprintf(stderr,"usage: %s [-h] [-d] [-m num] [-i ip] [-p port] <-s string> [-l logfile]\n",prg);
67 fprintf(stderr,"-h : This page.\n");
68 fprintf(stderr,"-d : Debug and stay in foreground\n");
69 fprintf(stderr,"-s : Shared secret (default: NONE)\n");
70 fprintf(stderr,"-i : Local IP Address (default: %s)\n",DEFAULT_IP);
71 fprintf(stderr,"-p : Local Port (default: %i)\n",DEFAULT_PORT);
72 fprintf(stderr,"-m : Max clients (default: %i min:1 max:%i)\n",DEFAULT_MAX_CLI, ABS_MAX_CLI);
73 fprintf(stderr,"-l : Logfile (default: NONE)\n");
74 exit(EXIT_FAILURE);
75 }
76
77 /* main */
78 int main(int argc, char *argv[]) {
79 char *prg = *argv;
80 uint32_t listen_ip = inet_addr(DEFAULT_IP);
81 uint16_t listen_port = htons(DEFAULT_PORT);
82 char *secret = NULL;
83 unsigned int max_cli = DEFAULT_MAX_CLI;
84
85 argc--;
86 argv++;
87
88 if ( !argc ) usage(prg);
89
90 /* command line arguments parsing */
91 while(argc) {
92 if ( strcmp(*argv,"-d") == 0 ) {
93 debug = 1;
94 }
95 else if ( strcmp(*argv,"-i") == 0 ) {
96 argc--;
97 argv++;
98 if ( !argc ) usage(prg);
99
100 listen_ip = inet_addr(*argv);
101 if ( listen_ip == INADDR_NONE ) {
102 fprintf(stderr,"-i invalid value.\n");
103 usage(prg);
104 }
105 }
106 else if ( strcmp(*argv,"-l") == 0 ) {
107 argc--;
108 argv++;
109 if ( !argc ) usage(prg);
110
111 logfile = *argv;
112 }
113 else if ( strcmp(*argv,"-p") == 0 ) {
114 argc--;
115 argv++;
116 if ( !argc ) usage(prg);
117
118 listen_port = htons(strtoul(*argv, NULL, 0));
119 if ( listen_port < 1 ) {
120 fprintf(stderr,"-p invalid value.\n");
121 usage(prg);
122 }
123 }
124 else if ( strcmp(*argv,"-m") == 0 ) {
125 argc--;
126 argv++;
127 if ( !argc ) usage(prg);
128
129 max_cli = strtoul(*argv, NULL, 0);
130
131 if ( max_cli < 1 || max_cli > ABS_MAX_CLI ) {
132 fprintf(stderr,"-m invalid value.\n");
133 usage(prg);
134 }
135 }
136 else if ( strcmp(*argv,"-s") == 0 ) {
137 argc--;
138 argv++;
139 if ( !argc ) usage(prg);
140
141 secret = *argv;
142 }
143 else if ( strcmp(*argv,"-h") == 0 )
144 usage(prg);
145 else
146 usage(prg);
147
148 argc--;
149 argv++;
150 }
151
152 if ( argc ) usage(prg);
153
154 if ( secret == NULL ) {
155 fprintf(stderr,"missing shared secret (-s)\n");
156 usage(prg);
157 }
158
159 if ( debug ) mylog("debug mode enabled.");
160
161 run_core(listen_ip,listen_port,secret,max_cli);
162
163 return 0;
164 }
165
166 int run_core(uint32_t ip, uint16_t port, char *secret, unsigned int max_cli) {
167 int s;
168 unsigned int run_cli = 0;
169 struct sockaddr_in sockin;
170
171 sockin.sin_family = AF_INET;
172 sockin.sin_port = port;
173 sockin.sin_addr.s_addr = ip;
174
175 if ( ( s = socket(PF_INET, SOCK_STREAM, 0) ) == -1 ) {
176 perror("socket");
177 exit(EXIT_FAILURE);
178 }
179
180 if ( fcntl(s, F_SETFL, O_NONBLOCK) == -1 ) {
181 perror("fcntl");
182 exit(EXIT_FAILURE);
183 }
184
185 if ( bind(s, (struct sockaddr*)&sockin, sizeof(struct sockaddr_in) ) == -1 ) {
186 perror("bind");
187 exit(EXIT_FAILURE);
188 }
189
190 if ( listen(s,10) == -1 ) {
191 perror("listen");
192 exit(EXIT_FAILURE);
193 }
194
195 if ( !debug )
196 daemonise();
197
198 while(1) {
199 struct sockaddr_in sockcli;
200 socklen_t socklen = sizeof(struct sockaddr_in);
201 int cli;
202
203 if((cli=accept(s, (struct sockaddr*)&sockcli, &socklen))>0) {
204 if ( run_cli >= max_cli ) {
205 mylog("ip=%s port=%i status=\"max clients\"",
206 inet_ntoa(sockcli.sin_addr),
207 ntohs(sockcli.sin_port));
208 close(cli);
209 continue;
210 }
211
212 switch(fork()) {
213 case -1:
214 mylog("ip=%s port=%i status=\"fork '%s'\"",
215 inet_ntoa(sockcli.sin_addr),
216 ntohs(sockcli.sin_port),
217 strerror(errno));
218 break;
219 case 0:
220 run_client(cli, &sockcli, secret);
221 exit(EXIT_SUCCESS);
222 default:
223 run_cli++;
224 break;
225 }
226 close(cli);
227 }
228 else
229 usleep(100000);
230
231 if ( run_cli > 0 ) {
232 int status;
233 if ( waitpid(-1, &status, WNOHANG) > 0 )
234 run_cli--;
235 }
236 }
237
238 close(s);
239
240 return 0;
241 }
242
243 void run_client(int s, struct sockaddr_in *sockin, char *secret) {
244 fd_set fdset;
245 struct timeval to;
246 char buf[8192];
247 char *string = NULL;
248 char *cli_type = "undefined";
249 char *cli_status = "undefined";
250 int is_http = 0;
251
252 FD_ZERO(&fdset);
253 FD_SET(s,&fdset);
254
255 to.tv_sec = 1;
256 to.tv_usec = 0;
257
258 if ( fcntl(s, F_SETFL, O_NONBLOCK) == -1 ) {
259 cli_status = "setsockopt_error";
260 goto client_end;
261 }
262
263
264 if ( select(s+1, &fdset, NULL, NULL, &to) == 1 ) {
265 ssize_t len;
266 char sbuf[1024];
267 if ( ( len = recv(s, sbuf, sizeof(sbuf)-1, 0 ) ) > 0 ) {
268 sbuf[len] = '\0';
269
270 if ( memcmp(sbuf,"GET ", sizeof("GET ")-1) == 0 ) {
271 cli_type = "http_get";
272 is_http = 1;
273 }
274 else if ( memcmp(sbuf,"POST ", sizeof("POST ")-1) == 0 ) {
275 cli_type = "http_post";
276 is_http = 1;
277 }
278 else {
279 cli_type = "undefined";
280 }
281 }
282 else {
283 cli_type = "no_cli_data";
284 }
285 }
286 else
287 cli_type = "no_cli_data";
288
289 buf[0] = '\0';
290
291 if ( is_http ) strcpy(buf,HTTP_RESPONSE);
292
293 strcpy(buf + strlen(buf), COMMON_RESPONSE);
294
295 string = build_sha256(secret);
296
297 strcpy(buf + strlen(buf), string);
298
299 if ( send(s,buf, strlen(buf), 0) != strlen(buf) ) {
300 cli_status = "write_error";
301 goto client_end;
302 }
303
304 cli_status = "ok";
305
306 sleep(1);
307
308
309 client_end:
310
311 mylog("ip=%s port=%u type=%s status=%s",
312 inet_ntoa(sockin->sin_addr),
313 ntohs(sockin->sin_port),
314 cli_type, cli_status );
315
316 close(s);
317 }
318
319 void mylog(char *fmt, ...) {
320 FILE *out = NULL;
321 va_list ap;
322 time_t ts = time(NULL);
323 char *tstr = ctime(&ts);
324
325 if ( tstr != NULL )
326 tstr[strlen(tstr)-1] = '\0';
327
328 if ( logfile != NULL )
329 out = fopen(logfile,"a+");
330
331 if ( out == NULL )
332 out = stdout;
333
334 va_start(ap, fmt);
335 fprintf(out,"[%s] ",tstr);
336 vfprintf(out,fmt,ap);
337 fprintf(out,"\n");
338 va_end(ap);
339
340 if ( out != stdout )
341 fclose(out);
342 }
343
344 void daemonise(void) {
345
346 switch(fork()) {
347 case -1:
348 perror("fork");
349 exit(EXIT_FAILURE);
350 case 0:
351 break;
352 default:
353 exit(EXIT_SUCCESS);
354 }
355
356 setsid();
357 freopen("/dev/null", "r+", stdin);
358 freopen("/dev/null", "r+", stdout);
359 freopen("/dev/null", "r+", stderr);
360 }
361
362 char *build_sha256(char *secret) {
363 static char buf[1024];
364 unsigned char hash[32];
365 sha256_context ctx;
366 time_t ts = time(NULL);
367 int i;
368
369 sprintf(buf,"%li",(long int)ts - ( ts % 3600 ));
370
371 sha256_starts(&ctx);
372 sha256_update(&ctx, (uint8_t*)secret, strlen(secret));
373 sha256_update(&ctx, (uint8_t*)buf, strlen(buf));
374 sha256_finish(&ctx, hash);
375
376 for(i=0; i<32; i++)
377 sprintf(buf + (i*2),"%02X",hash[i]);
378
379 strcpy(buf + 64,"\r\n");
380
381 return buf;
382 }

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28