/[monit]/monit/http/engine.c
ViewVC logotype

Diff of /monit/http/engine.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.44 by hauk, Thu Sep 18 14:01:33 2003 UTC revision 1.45 by hauk, Fri Sep 19 03:44:17 2003 UTC
# Line 79  Line 79 
79  #endif  #endif
80    
81  #include "http_utils.h"  #include "http_utils.h"
82  #include "engine.h"  #include "engine.h"
83    #include "socket.h"
84    
 #define  HOST      1  
 #define  WRAPPER   2  
 #define  INETADDR  3  
   
 /* Private variables */  
 static int myServerSocket= 0;  
 ssl_server_connection * mySSLServerConnection= NULL;  
 static volatile int stopped= FALSE;  
 static HostsAllow hostlist= NULL;  
 static pthread_mutex_t hostlist_mutex= PTHREAD_MUTEX_INITIALIZER;  
   
 /* Private prototypes */  
 static void initialize_service();  
 static void check_Impl();  
 static int  authenticate(RequestWrapper);  
 static int  is_host_allow(char *);  
 static RequestWrapper socket_producer(int);  
 static RequestWrapper create_wrapper(struct in_addr, int);  
 static void destroy_host_allow(HostsAllow);  
85    
86  /**  /**
87   *  A naive http 1.0 server. The server delegates handling of a HTTP   *  A naive http 1.0 server. The server delegates handling of a HTTP
# Line 128  static void destroy_host_allow(HostsAllo Line 110  static void destroy_host_allow(HostsAllo
110   */   */
111    
112    
113    /* ------------------------------------------------------------- Definitions */
114    
115    
116    static int myServerSocket= 0;
117    static HostsAllow hostlist= NULL;
118    static volatile int stopped= FALSE;
119    ssl_server_connection *mySSLServerConnection= NULL;
120    static pthread_mutex_t hostlist_mutex= PTHREAD_MUTEX_INITIALIZER;
121    
122    
123    /* -------------------------------------------------------------- Prototypes */
124    
125    
126    static void check_Impl();
127    static void initialize_service();
128    static int  authenticate(Socket_T);
129    static int  is_host_allow(const char *);
130    static void destroy_host_allow(HostsAllow);
131    static Socket_T socket_producer(int, int, void*);
132    
133    
134  /* ------------------------------------------------------------------ Public */  /* ------------------------------------------------------------------ Public */
135    
136    
# Line 139  static void destroy_host_allow(HostsAllo Line 142  static void destroy_host_allow(HostsAllo
142   */   */
143  void start_httpd(int port, int backlog, char *bindAddr) {  void start_httpd(int port, int backlog, char *bindAddr) {
144    
145    RequestWrapper W;    Socket_T S;
146    
147    stopped= Run.stopped;    stopped= Run.stopped;
148    
149    if ( (myServerSocket= create_server_socket(port, backlog, bindAddr)) < 0 ) {    if((myServerSocket= create_server_socket(port, backlog, bindAddr)) < 0) {
150            
151      log("http server: Could not create a server socket at port %d -- %s\n",      log("http server: Could not create a server socket at port %d -- %s\n",
152            port, STRERROR);          port, STRERROR);
153            
154      log("monit HTTP server not available\n");      log("monit HTTP server not available\n");
155        
156      if ( Run.init ) {      if(Run.init) {
157          
158        sleep(1);        sleep(1);
159        kill_daemon(SIGTERM);        kill_daemon(SIGTERM);
160          
161      }      }
162            
163    } else {    } else {
164          
165      initialize_service();      initialize_service();
166        
167      if ( Run.httpdssl ) {      if(Run.httpdssl) {
168          
169        mySSLServerConnection= init_ssl_server( Run.httpsslpem,        mySSLServerConnection= init_ssl_server( Run.httpsslpem,
170                                                Run.httpsslclientpem );                                                Run.httpsslclientpem);
171          
172        if ( mySSLServerConnection == NULL ) {        if(mySSLServerConnection == NULL) {
173            
174          log("http server: Could not initilize SSL engine\n");          log("http server: Could not initilize SSL engine\n");
175                
176          log("monit HTTP server not available\n");          log("monit HTTP server not available\n");
177            
178          return;          return;
179        }        }
180          
181  #ifdef HAVE_OPENSSL  #ifdef HAVE_OPENSSL
182        mySSLServerConnection->server_socket= myServerSocket;        mySSLServerConnection->server_socket= myServerSocket;
183  #endif  #endif
184      }      }
185        
186      while( !stopped ) {      while(! stopped) {
187                
188        if ( NULL == (W= socket_producer(myServerSocket)) ) {        if(!(S= socket_producer(myServerSocket, port, mySSLServerConnection))) {
           
189          continue;          continue;
   
       }  
         
       if ( Run.httpdssl ) {  
   
         if ( NULL == (W->ssl=  
                       insert_accepted_ssl_socket(mySSLServerConnection) )) {  
             
           log("http server: Cannot create SSL connection -- %s\n",  
                 STRERROR);  
           destroy_wrapper(W);  
   
           continue;  
   
         }  
   
         if (! embed_accepted_ssl_socket(W->ssl, W->socket)) {  
   
           log("http server: Cannot establish SSL connection\n");  
           destroy_wrapper(W);  
   
           continue;  
   
         }  
           
190        }        }
191    
192        if ( (!W->status) || (!authenticate(W)) ) {        if(! authenticate(S)) {
193                    socket_free(&S);
         destroy_wrapper(W);  
           
194          continue;          continue;
           
       }  
         
       if ( !Run.httpdssl ) {  
           
         if ( !check_socket(W->socket) ) {  
             
           log("http server: Client socket not ready -- %s\n", STRERROR);  
           destroy_wrapper(W);  
             
           continue;  
             
         }  
   
195        }        }
196    
197        http_processor(W);        http_processor(S);
198                
199      }      }
200    
201      close_socket(myServerSocket);      if(S) {
202          socket_free(&S);
203        }
204      delete_ssl_server_socket(mySSLServerConnection);        delete_ssl_server_socket(mySSLServerConnection);  
205    
     pthread_exit(NULL);  
   
206    }    }
207    
208  }  }
# Line 261  void stop_httpd() { Line 222  void stop_httpd() {
222    
223    
224  /**  /**
225   * Add hosts allowed to connect to this server.   * Add hosts allowed to connect to this server.
226   * @param name A hostname (A-Record) or IP address to be added to the hosts allow list   * @param name A hostname (A-Record) or IP address to be added to the
227     * hosts allow list
228   * @return FALSE if the given host does not resolve, otherwise TRUE   * @return FALSE if the given host does not resolve, otherwise TRUE
229   */   */
230  int add_host_allow(char *name) {  int add_host_allow(char *name) {
231    
232    struct hostent *hp;    struct hostent *hp;
233    
234    if ( ! (hp= gethostbyname(name)) ) {    if(! (hp= gethostbyname(name))) {
235            
236      return FALSE;      return FALSE;
237            
# Line 281  int add_host_allow(char *name) { Line 243  int add_host_allow(char *name) {
243            
244      while(*hp->h_addr_list) {      while(*hp->h_addr_list) {
245    
246        h->name= xstrdup( inet_ntoa( *(struct in_addr *) *hp->h_addr_list++) );        h->name= xstrdup( inet_ntoa( *(struct in_addr *) *hp->h_addr_list++));
247            
248        LOCK(hostlist_mutex)        LOCK(hostlist_mutex)
249                    
250        if ( hostlist ) {        if(hostlist) {
251                
252          HostsAllow p, n;          HostsAllow p, n;
253                
254          for ( n= p= hostlist; p; n= p, p= p->next) {          for(n= p= hostlist; p; n= p, p= p->next) {
255                    
256            if ( !strcasecmp(p->name, name) ) {            if(!strcasecmp(p->name, name)) {
257                        
258              destroy_host_allow(h);              destroy_host_allow(h);
259              goto done;              goto done;
# Line 329  int has_hosts_allow() { Line 291  int has_hosts_allow() {
291    int rv;    int rv;
292    
293    LOCK(hostlist_mutex)    LOCK(hostlist_mutex)
294        rv= (hostlist != NULL );        rv= (hostlist != NULL);
295    END_LOCK;    END_LOCK;
296    
297    return rv;    return rv;
# Line 342  int has_hosts_allow() { Line 304  int has_hosts_allow() {
304   */   */
305  void destroy_hosts_allow() {  void destroy_hosts_allow() {
306    
307    if ( has_hosts_allow() ) {    if(has_hosts_allow()) {
308            
309      LOCK(hostlist_mutex)      LOCK(hostlist_mutex)
310          destroy_host_allow(hostlist);          destroy_host_allow(hostlist);
# Line 376  static void initialize_service() { Line 338  static void initialize_service() {
338   */   */
339  static void check_Impl() {  static void check_Impl() {
340    
341    if ( (Impl.doGet == 0) || (Impl.doPost == 0) ) {    if((Impl.doGet == 0) || (Impl.doPost == 0)) {
342            
343      log("http server: Service Methods not implemented\n");      log("http server: Service Methods not implemented\n");
344      _exit(1);      _exit(1);
# Line 387  static void check_Impl() { Line 349  static void check_Impl() {
349    
350    
351  /**  /**
352   * Returns TRUE if remote host is allowed to connect, if not shutdown   * Returns TRUE if remote host is allowed to connect, otherwise return
353   * the socket and return FALSE. If allow Basic Authentication is   * FALSE. If allow Basic Authentication is defined in the Run.Auth
354   * defined in the Run.Auth object, authentication is delegated to the   * object, authentication is delegated to the processor module.
  * processor module.  
355   */   */
356  static int authenticate(RequestWrapper w) {  static int authenticate(Socket_T S) {
357    
358    if ( is_host_allow(w->inetaddr->remote_host) ) {    if(is_host_allow(socket_get_remote_host(S))) {
359            
360      return TRUE;      return TRUE;
361            
362    }    }
363    
364    if ( ! has_hosts_allow() && Run.Auth.defined ) {    if(! has_hosts_allow() && Run.Auth.defined) {
365    
366      return TRUE;      return TRUE;
367    
# Line 411  static int authenticate(RequestWrapper w Line 372  static int authenticate(RequestWrapper w
372  }  }
373    
374    
   
375  /**  /**
376   * Returns TRUE if host is allowed to connect to   * Returns TRUE if host is allowed to connect to
377   * this server   * this server
378   */   */
379  static int is_host_allow(char *name) {  static int is_host_allow(const char *name) {
380    
381    HostsAllow p;    HostsAllow p;
382    int rv= FALSE;    int rv= FALSE;
383    
384    LOCK(hostlist_mutex)    LOCK(hostlist_mutex)
385        
386    for ( p= hostlist; p; p= p->next) {    for(p= hostlist; p; p= p->next) {
387    
388      if ( !strncasecmp(p->name, name, STRLEN) ) {      if(!strncasecmp(p->name, name, STRLEN)) {
389                
390        rv= TRUE;        rv= TRUE;
391        break;        break;
# Line 448  static int is_host_allow(char *name) { Line 408  static int is_host_allow(char *name) {
408   * Accept connections from Clients and create a RequestWraper object   * Accept connections from Clients and create a RequestWraper object
409   * for each successful accept. If accept fails, return a NULL object   * for each successful accept. If accept fails, return a NULL object
410   */   */
411  static RequestWrapper socket_producer(int server) {  static Socket_T socket_producer(int server, int port, void *sslserver) {
412      
413    int client;    int client;
414    struct sockaddr_in in;    struct sockaddr_in in;
415    int len= sizeof(struct sockaddr_in);    int len= sizeof(struct sockaddr_in);
# Line 470  static RequestWrapper socket_producer(in Line 430  static RequestWrapper socket_producer(in
430    
431    } else {    } else {
432    
433      /* in the case that timeout or error occured, return NULL to allow      /* If timeout or error occured, return NULL to allow the caller to
434       * the caller handle various states (such as stopped) which can       * handle various states (such as stopped) which can occure in the
435       * occure in the meantime */       * meantime */
436      return NULL;      return NULL;
437    
438    }    }
439    
440    if(set_noblock(client) < 0) {    if(set_noblock(client) < 0) {
441      close_socket(client);      goto error;
     return NULL;  
442    }    }
443        
444    return create_wrapper(in.sin_addr, client);    if(!check_socket(client)) {
445        goto error;
 }  
   
   
 /**  
  * Create a RequestWrapper. This function will always return a  
  * RequestWraper. If the build is successful the status variable in  
  * the Wrapper is set to TRUE otherwise it is set to FALSE. If the  
  * build fails, the client socket is also shutdown. The build fails  
  * if the connecting client does not have a valid domain name.  
  */  
 static RequestWrapper create_wrapper(struct in_addr iaddr, int client) {  
   
   InetAddress i;  
   RequestWrapper w;  
   char localhost[STRLEN];  
   
   if(gethostname(localhost, sizeof(localhost)) < 0) {  
     snprintf(localhost, STRLEN, "localhost");  
446    }    }
447      
448      
449      return socket_create_a(client, inet_ntoa(in.sin_addr), port, sslserver);
450    
451    NEW(i);    error:
452    NEW(w);    close_socket(client);
453    w->inetaddr= i;    
454    w->status= TRUE;    return NULL;
   w->socket= client;  
   i->local_host= xstrdup(localhost);  
   i->remote_host= xstrdup(inet_ntoa(iaddr));  
       
   return (w);  
455    
456  }  }
457    

Legend:
Removed from v.1.44  
changed lines
  Added in v.1.45

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26