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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 michael 3253 /* 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