00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <errno.h>
00025
00026 #ifdef HAVE_SYS_TYPES_H
00027 #include <sys/types.h>
00028 #endif
00029
00030 #include <sys/socket.h>
00031 #include <time.h>
00032
00033 #ifdef HAVE_NETDB_H
00034 #include <netdb.h>
00035 #endif
00036
00037 #ifdef HAVE_UNISTD_H
00038 #include <unistd.h>
00039 #endif
00040
00041 #ifdef HAVE_STRING_H
00042 #include <string.h>
00043 #endif
00044
00045 #ifdef HAVE_NETINET_IN_H
00046 #include <netinet/in.h>
00047 #endif
00048
00049 #ifdef HAVE_ARPA_INET_H
00050 #include <arpa/inet.h>
00051 #endif
00052
00053 #include "http_utils.h"
00054 #include "engine.h"
00055
00056 #define HOST 1
00057 #define WRAPPER 2
00058 #define INETADDR 3
00059
00060
00061 static int myServerSocket= 0;
00062 static volatile int stopped= FALSE;
00063 static HostsAllow hostlist= NULL;
00064 static pthread_mutex_t hostlist_mutex= PTHREAD_MUTEX_INITIALIZER;
00065
00066
00067
00068 static void initialize_service();
00069 static void check_Impl();
00070 static int authenticate(RequestWrapper);
00071 static int is_host_allow(char *);
00072 static RequestWrapper socket_producer(int);
00073 static RequestWrapper create_wrapper(struct in_addr, int);
00074 static void destroy_host_allow(HostsAllow);
00075
00101
00102
00103
00110 void start_httpd(int port, int backlog, char *bindAddr) {
00111
00112 RequestWrapper W;
00113
00114 stopped= FALSE;
00115
00116
00117 if ( (myServerSocket= create_server_socket(port, backlog, bindAddr)) < 0 ) {
00118
00119 error("http server: Could not create a server socket at port %d -- %s\n",
00120 port, STRERROR);
00121
00122 error("monit HTTP server not available\n");
00123
00124 } else {
00125
00126 initialize_service();
00127
00128 while( !stopped ) {
00129
00130 if ( NULL == (W= socket_producer(myServerSocket)) ) {
00131
00132 continue;
00133
00134 }
00135
00136 if ( (!W->status) || (!authenticate(W)) ) {
00137
00138 destroy_wrapper(W);
00139
00140 continue;
00141
00142 }
00143
00144 if ( !check_socket(W->socket) ) {
00145
00146 error("http server: Client socket not ready -- %s\n", STRERROR);
00147 destroy_wrapper(W);
00148
00149 continue;
00150
00151 }
00152
00153 http_processor(W);
00154
00155 }
00156
00157 }
00158
00159 }
00160
00161
00165 void stop_httpd() {
00166
00167 stopped= TRUE;
00168 close_socket(myServerSocket);
00169
00170 }
00171
00172
00173
00174
00175
00181 int add_host_allow(char *name) {
00182
00183 struct hostent *hp;
00184
00185 if ( ! (hp= gethostbyname(name)) ) {
00186
00187 return FALSE;
00188
00189 } else {
00190
00191 HostsAllow h= NEW(h);
00192
00193 while(*hp->h_addr_list) {
00194
00195 h->name= xstrdup( inet_ntoa( *(struct in_addr *) *hp->h_addr_list++) );
00196
00197 LOCK(hostlist_mutex)
00198
00199 if ( hostlist ) {
00200
00201 HostsAllow p, n;
00202
00203 for ( n= p= hostlist; p; n= p, p= p->next) {
00204
00205 if ( !strcasecmp(p->name, name) ) {
00206
00207 destroy_host_allow(h);
00208 goto done;
00209
00210 }
00211
00212 }
00213
00214 n->next= h;
00215
00216 } else {
00217
00218 hostlist= h;
00219
00220 }
00221
00222 done:
00223 END_LOCK;
00224
00225 }
00226
00227 }
00228
00229 return TRUE;
00230
00231 }
00232
00233
00238 int has_hosts_allow() {
00239
00240 int rv;
00241
00242 LOCK(hostlist_mutex)
00243 rv= (hostlist != NULL );
00244 END_LOCK;
00245
00246 return rv;
00247
00248 }
00249
00250
00254 void destroy_hosts_allow() {
00255
00256 if ( has_hosts_allow() ) {
00257
00258 LOCK(hostlist_mutex)
00259 destroy_host_allow(hostlist);
00260 hostlist= NULL;
00261 END_LOCK;
00262
00263 }
00264
00265 }
00266
00267
00268
00269
00270
00277 static void initialize_service() {
00278
00279 init_service();
00280 check_Impl();
00281
00282 }
00283
00284
00288 static void check_Impl() {
00289
00290 if ( (Impl.doGet == 0) || (Impl.doPost == 0) ) {
00291
00292 error("http server: Service Methods not implemented\n");
00293 _exit(1);
00294
00295 }
00296
00297 }
00298
00299
00306 static int authenticate(RequestWrapper w) {
00307
00308 if ( is_host_allow(w->inetaddr->remote_host) ) {
00309
00310 return TRUE;
00311
00312 }
00313
00314 if ( ! has_hosts_allow() && Run.Auth.defined ) {
00315
00316 return TRUE;
00317
00318 }
00319
00320 return FALSE;
00321
00322 }
00323
00324
00325
00330 static int is_host_allow(char *name) {
00331
00332 HostsAllow p;
00333 int rv= FALSE;
00334
00335 LOCK(hostlist_mutex)
00336
00337 for ( p= hostlist; p; p= p->next) {
00338
00339 if ( !strncasecmp(p->name, name, STRLEN) ) {
00340
00341 rv= TRUE;
00342 break;
00343
00344 }
00345
00346 }
00347
00348 END_LOCK;
00349
00350 return rv;
00351
00352 }
00353
00354
00355
00356
00357
00363 static RequestWrapper socket_producer(int server) {
00364
00365 int client;
00366 int len= sizeof(struct sockaddr_in);
00367 struct sockaddr_in in;
00368
00369 again:
00370 errno= 0;
00371 if ( (client= accept(server, (struct sockaddr*)&in, &len)) < 0) {
00372
00373 if ( stopped ) {
00374
00375 log("http server: service stopped\n");
00376
00377 } else if ( errno == EINTR ) {
00378
00379 goto again;
00380
00381 } else {
00382
00383 error("http server: cannot accept connection -- %s\n", STRERROR);
00384
00385 }
00386
00387 return NULL;
00388
00389 }
00390
00391 return create_wrapper(in.sin_addr, client);
00392
00393 }
00394
00395
00403 static RequestWrapper create_wrapper(struct in_addr iaddr, int client) {
00404
00405 RequestWrapper w= NEW(w);
00406 InetAddress i= NEW(i);
00407
00408 i->remote_host= xstrdup( inet_ntoa(iaddr) );
00409 i->local_host= get_localhostname();
00410 w->inetaddr= i;
00411 w->socket= client;
00412 w->status= TRUE;
00413
00414 return (w);
00415
00416 }
00417
00418
00419
00420
00421
00425 static void destroy_host_allow(HostsAllow p) {
00426
00427 HostsAllow a= p;
00428
00429 if ( a->next ) {
00430
00431 destroy_host_allow(a->next);
00432
00433 }
00434
00435 free(a->name);
00436 free(a);
00437
00438 }
00439