Back to index

nagios-plugins  1.4.16
Classes | Defines | Functions | Variables
check_http-with-client-certificate.c File Reference
#include "config.h"
#include "common.h"
#include "netutils.h"
#include "utils.h"

Go to the source code of this file.

Classes

struct  pageref

Defines

#define REVISION   "$Revision: 1117 $"
#define CVSREVISION   "1.24"
#define COPYRIGHT   "2003"
#define AUTHORS   "Fabian Pehla"
#define EMAIL   "fabian@pehla.de"
#define HELP_TXT_SUMMARY   "\This plugin tests the HTTP service on the specified host. It can test\n\normal (http) and secure (https) servers, follow redirects, search for\n\strings and regular expressions, check connection times, and report on\n\certificate expiration times.\n"
#define HELP_TXT_OPTIONS   "\-H <virtual host> -I <ip address> [-p <port>] [-u <uri>]\n\ [-w <warn time>] [-c <critical time>] [-t <timeout>]\n\ [-S] [-C <days>] [-a <basic auth>] [-A <certificate file>]\n\ [-Z <ca certificate file>] [-e <expect>] [-E <expect only>]\n\ [-s <string>] [-r <regex>] [-R <regex case insensitive>]\n\ [-f (ok|warn|critical|follow)] [-g (ok|warn|critical)]\n"
#define HELP_TXT_LONGOPTIONS   "\ -H, --hostname=<virtual host>\n\ FQDN host name argument for use in HTTP Host:-Header (virtual host)\n\ If used together wich the -S option, the server certificate will\n\ be checked against this hostname\n\ -I, --ip-address=<address>\n\ IP address or hostname for TCP connect (use IP to avoid DNS lookup)\n\ -p, --port=<port>\n\ Port number (default: %d)\n\ -u, --url-path=<uri>\n\ URL to request from host (default: %s)\n\ -S, --ssl\n\ Use SSL (default port: %d)\n\ -C, --server-certificate-days=<days>\n\ Minimum number of days a server certificate must be valid\n\ No other check can be combined with this option\n\ -a, --basic-auth=<username:password>\n\ Colon separated username and password for basic authentication\n\ -A, --client-certificate=<certificate file>\n\ File containing X509 client certificate and key\n\ -K, --passphrase=<passphrase>\n\ Passphrase for the client certificate key\n\ This option can only be used in combination with the -A option\n\ -Z, --ca-certificate=<certificate file>\n\ File containing certificates of trusted CAs\n\ The server certificate will be checked against these CAs\n\ -e, --http-expect=<expect string>\n\ String to expect in HTTP response line (Default: %s)\n\ -E, --http-expect-only=<expect only string>\n\ String to expect in HTTP response line\n\ No other checks are made, this either matches the response\n\ or exits immediately\n\ -s, --content-string=<string>\n\ String to expect in content\n\ -r, --content-ereg=<regex>\n\ Regular expression to expect in content\n\ -R, --content-eregi=<regex case insensitive>\n\ Case insensitive regular expression to expect in content\n\ -f, --onredirect=(ok|warning|critical|follow)\n\ Follow a redirect (3xx) or return with a user defined state\n\ Default: OK\n\ -g, --onerror=(ok|warning|critical)\n\ Status to return on a client error (4xx)\n\ -m, --min=INTEGER\n\ Minimum page size required (bytes)\n\ -t, --timeout=<timeout>\n\ Seconds before connection times out (default: %d)\n\ -c, --critical=<critical time>\n\ Response time to result in critical status (seconds)\n\ -w, --warning=<warn time>\n\ Response time to result in warning status (seconds)\n\ -V, --version\n\ Print version information\n\ -v, --verbose\n\ Show details for command-line debugging (do not use with nagios server)\n\ -h, --help\n\ Print detailed help screen\n"
#define HTTP_PORT   80
#define DEFAULT_HTTP_URL_PATH   "/"
#define DEFAULT_HTTP_EXPECT   "HTTP/1."
#define DEFAULT_HTTP_METHOD   "GET"
#define DEFAULT_HTTP_REDIRECT_STATE   STATE_OK
#define DEFAULT_HTTP_CLIENT_ERROR_STATE   STATE_WARNING
#define HTTP_TEMPLATE_REQUEST   "%s%s %s HTTP/1.0\r\n"
#define HTTP_TEMPLATE_HEADER_USERAGENT   "%sUser-Agent: %s/%s (nagios-plugins %s)\r\n"
#define HTTP_TEMPLATE_HEADER_HOST   "%sHost: %s\r\n"
#define HTTP_TEMPLATE_HEADER_AUTH   "%sAuthorization: Basic %s\r\n"
#define RESULT_TEMPLATE_STATUS_RESPONSE_TIME   "%s %s: %s - %7.3f seconds response time|time=%7.3f\n"
#define RESULT_TEMPLATE_RESPONSE_TIME   "%s %s: %7.3f seconds response time|time=%7.3f\n"
#define chk_protocol(protocol)   ( strstr( protocol, "https" ) ? TRUE : FALSE );
#define protocol_std_port(use_ssl)   ( use_ssl ? HTTPS_PORT : HTTP_PORT );
#define protocol_text(use_ssl)   ( use_ssl ? "HTTPS" : "HTTP" )
#define MAX_IPV4_HOSTLENGTH   64
#define HTTP_HEADER_LOCATION_MATCH   "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: "
#define HTTP_HEADER_PROTOCOL_MATCH   "%[HTPShtps]://"
#define HTTP_HEADER_HOSTNAME_MATCH   "%[a-zA-Z0-9.-]"
#define HTTP_HEADER_PORT_MATCH   ":%[0-9]"
#define HTTP_HEADER_URL_PATH_MATCH   "%[/a-zA-Z0-9._-=@,]"
#define OPTCHARS   "Vvht:c:w:H:F:I:p:u:P:SC:a:A:K:Z:e:E:s:r:R:f:g:lm:"

Functions

void print_usage (void)
void print_help (void)
int process_arguments (int, char **)
int http_request (int sock, struct pageref *page)
int parse_http_response (struct pageref *page)
int check_http_response (struct pageref *page)
int check_http_content (struct pageref *page)
int prepare_follow_redirect (struct pageref *page)
static char * base64 (char *bin, int len)
int main (int argc, char **argv)

Variables

const char * progname = "check_http"
int verbose = FALSE
int use_warning_interval = FALSE
double warning_interval = 0
int use_critical_interval = FALSE
double critical_interval = 0
double elapsed_time = 0
int use_server_hostname = FALSE
char * server_hostname = ""
char * server_host = ""
int use_server_port = FALSE
int server_port = HTTP_PORT
int use_basic_auth = FALSE
char basic_auth [MAX_INPUT_BUFFER] = ""
int use_ssl = FALSE
char * http_method = DEFAULT_HTTP_METHOD
char * http_url_path = ""
int use_http_post_data = FALSE
char * http_post_data = ""
int use_min_content_length = FALSE
int min_content_length = 0
int use_http_expect_only = FALSE
char http_expect [MAX_INPUT_BUFFER] = DEFAULT_HTTP_EXPECT
int check_content_string = FALSE
char content_string [MAX_INPUT_BUFFER] = ""
int http_redirect_state = DEFAULT_HTTP_REDIRECT_STATE
int http_client_error_state = DEFAULT_HTTP_CLIENT_ERROR_STATE

Class Documentation

struct pageref

Definition at line 212 of file check_http-with-client-certificate.c.

Class Members
char * body
char * content
char * header
size_t size
char * status

Define Documentation

#define AUTHORS   "Fabian Pehla"

Definition at line 43 of file check_http-with-client-certificate.c.

#define chk_protocol (   protocol)    ( strstr( protocol, "https" ) ? TRUE : FALSE );

Definition at line 173 of file check_http-with-client-certificate.c.

#define COPYRIGHT   "2003"

Definition at line 42 of file check_http-with-client-certificate.c.

#define CVSREVISION   "1.24"

Definition at line 41 of file check_http-with-client-certificate.c.

Definition at line 131 of file check_http-with-client-certificate.c.

#define DEFAULT_HTTP_EXPECT   "HTTP/1."

Definition at line 128 of file check_http-with-client-certificate.c.

#define DEFAULT_HTTP_METHOD   "GET"

Definition at line 129 of file check_http-with-client-certificate.c.

Definition at line 130 of file check_http-with-client-certificate.c.

#define DEFAULT_HTTP_URL_PATH   "/"

Definition at line 127 of file check_http-with-client-certificate.c.

#define EMAIL   "fabian@pehla.de"

Definition at line 44 of file check_http-with-client-certificate.c.

#define HELP_TXT_LONGOPTIONS   "\ -H, --hostname=<virtual host>\n\ FQDN host name argument for use in HTTP Host:-Header (virtual host)\n\ If used together wich the -S option, the server certificate will\n\ be checked against this hostname\n\ -I, --ip-address=<address>\n\ IP address or hostname for TCP connect (use IP to avoid DNS lookup)\n\ -p, --port=<port>\n\ Port number (default: %d)\n\ -u, --url-path=<uri>\n\ URL to request from host (default: %s)\n\ -S, --ssl\n\ Use SSL (default port: %d)\n\ -C, --server-certificate-days=<days>\n\ Minimum number of days a server certificate must be valid\n\ No other check can be combined with this option\n\ -a, --basic-auth=<username:password>\n\ Colon separated username and password for basic authentication\n\ -A, --client-certificate=<certificate file>\n\ File containing X509 client certificate and key\n\ -K, --passphrase=<passphrase>\n\ Passphrase for the client certificate key\n\ This option can only be used in combination with the -A option\n\ -Z, --ca-certificate=<certificate file>\n\ File containing certificates of trusted CAs\n\ The server certificate will be checked against these CAs\n\ -e, --http-expect=<expect string>\n\ String to expect in HTTP response line (Default: %s)\n\ -E, --http-expect-only=<expect only string>\n\ String to expect in HTTP response line\n\ No other checks are made, this either matches the response\n\ or exits immediately\n\ -s, --content-string=<string>\n\ String to expect in content\n\ -r, --content-ereg=<regex>\n\ Regular expression to expect in content\n\ -R, --content-eregi=<regex case insensitive>\n\ Case insensitive regular expression to expect in content\n\ -f, --onredirect=(ok|warning|critical|follow)\n\ Follow a redirect (3xx) or return with a user defined state\n\ Default: OK\n\ -g, --onerror=(ok|warning|critical)\n\ Status to return on a client error (4xx)\n\ -m, --min=INTEGER\n\ Minimum page size required (bytes)\n\ -t, --timeout=<timeout>\n\ Seconds before connection times out (default: %d)\n\ -c, --critical=<critical time>\n\ Response time to result in critical status (seconds)\n\ -w, --warning=<warn time>\n\ Response time to result in warning status (seconds)\n\ -V, --version\n\ Print version information\n\ -v, --verbose\n\ Show details for command-line debugging (do not use with nagios server)\n\ -h, --help\n\ Print detailed help screen\n"

Definition at line 66 of file check_http-with-client-certificate.c.

#define HELP_TXT_OPTIONS   "\-H <virtual host> -I <ip address> [-p <port>] [-u <uri>]\n\ [-w <warn time>] [-c <critical time>] [-t <timeout>]\n\ [-S] [-C <days>] [-a <basic auth>] [-A <certificate file>]\n\ [-Z <ca certificate file>] [-e <expect>] [-E <expect only>]\n\ [-s <string>] [-r <regex>] [-R <regex case insensitive>]\n\ [-f (ok|warn|critical|follow)] [-g (ok|warn|critical)]\n"

Definition at line 58 of file check_http-with-client-certificate.c.

#define HELP_TXT_SUMMARY   "\This plugin tests the HTTP service on the specified host. It can test\n\normal (http) and secure (https) servers, follow redirects, search for\n\strings and regular expressions, check connection times, and report on\n\certificate expiration times.\n"

Definition at line 52 of file check_http-with-client-certificate.c.

#define HTTP_HEADER_HOSTNAME_MATCH   "%[a-zA-Z0-9.-]"

Definition at line 180 of file check_http-with-client-certificate.c.

#define HTTP_HEADER_LOCATION_MATCH   "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: "

Definition at line 178 of file check_http-with-client-certificate.c.

#define HTTP_HEADER_PORT_MATCH   ":%[0-9]"

Definition at line 181 of file check_http-with-client-certificate.c.

#define HTTP_HEADER_PROTOCOL_MATCH   "%[HTPShtps]://"

Definition at line 179 of file check_http-with-client-certificate.c.

#define HTTP_HEADER_URL_PATH_MATCH   "%[/a-zA-Z0-9._-=@,]"

Definition at line 182 of file check_http-with-client-certificate.c.

#define HTTP_PORT   80

Definition at line 126 of file check_http-with-client-certificate.c.

#define HTTP_TEMPLATE_HEADER_AUTH   "%sAuthorization: Basic %s\r\n"

Definition at line 136 of file check_http-with-client-certificate.c.

#define HTTP_TEMPLATE_HEADER_HOST   "%sHost: %s\r\n"

Definition at line 135 of file check_http-with-client-certificate.c.

#define HTTP_TEMPLATE_HEADER_USERAGENT   "%sUser-Agent: %s/%s (nagios-plugins %s)\r\n"

Definition at line 134 of file check_http-with-client-certificate.c.

#define HTTP_TEMPLATE_REQUEST   "%s%s %s HTTP/1.0\r\n"

Definition at line 133 of file check_http-with-client-certificate.c.

#define MAX_IPV4_HOSTLENGTH   64

Definition at line 177 of file check_http-with-client-certificate.c.

#define OPTCHARS   "Vvht:c:w:H:F:I:p:u:P:SC:a:A:K:Z:e:E:s:r:R:f:g:lm:"
#define protocol_std_port (   use_ssl)    ( use_ssl ? HTTPS_PORT : HTTP_PORT );

Definition at line 174 of file check_http-with-client-certificate.c.

#define protocol_text (   use_ssl)    ( use_ssl ? "HTTPS" : "HTTP" )

Definition at line 175 of file check_http-with-client-certificate.c.

#define RESULT_TEMPLATE_RESPONSE_TIME   "%s %s: %7.3f seconds response time|time=%7.3f\n"

Definition at line 140 of file check_http-with-client-certificate.c.

#define RESULT_TEMPLATE_STATUS_RESPONSE_TIME   "%s %s: %s - %7.3f seconds response time|time=%7.3f\n"

Definition at line 139 of file check_http-with-client-certificate.c.

#define REVISION   "$Revision: 1117 $"

Definition at line 40 of file check_http-with-client-certificate.c.


Function Documentation

static char * base64 ( char *  bin,
int  len 
) [static]

Definition at line 1530 of file check_http-with-client-certificate.c.

{

        char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1);
        int i = 0, j = 0;

        char BASE64_END = '=';
        char base64_table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        while (j < len - 2) {
                buf[i++] = base64_table[bin[j] >> 2];
                buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)];
                buf[i++] = base64_table[((bin[j + 1] & 15) << 2) | (bin[j + 2] >> 6)];
                buf[i++] = base64_table[bin[j + 2] & 63];
                j += 3;
        }

        switch (len - j) {
        case 1:
                buf[i++] = base64_table[bin[j] >> 2];
                buf[i++] = base64_table[(bin[j] & 3) << 4];
                buf[i++] = BASE64_END;
                buf[i++] = BASE64_END;
                break;
        case 2:
                buf[i++] = base64_table[bin[j] >> 2];
                buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)];
                buf[i++] = base64_table[(bin[j + 1] & 15) << 2];
                buf[i++] = BASE64_END;
                break;
        case 0:
                break;
        }

        buf[i] = '\0';
        return buf;
}

Here is the caller graph for this function:

int check_http_content ( struct pageref page)

Definition at line 1083 of file check_http-with-client-certificate.c.

{
        char *msg = "";

        /* check for string in content */
        if ( check_content_string ) {
                if ( strstr( page->content, content_string ) ) {
                        asprintf( &msg, RESULT_TEMPLATE_STATUS_RESPONSE_TIME,
                                        protocol_text( use_ssl ),
                                        state_text( STATE_OK ),
                                        page->status,
                                        elapsed_time,
                                        elapsed_time );
                        terminate( STATE_OK, msg );
                } else {
                        asprintf( &msg, RESULT_TEMPLATE_STATUS_RESPONSE_TIME,
                                        protocol_text( use_ssl ),
                                        state_text( STATE_CRITICAL ),
                                        page->status,
                                        elapsed_time,
                                        elapsed_time );
                        terminate( STATE_CRITICAL, msg );
                }
        }

#ifdef HAVE_REGEX_H
        /* check for regex in content */
        if ( check_content_regex ) {
                regex_error = regexec( &regex_preg, page->content, REGEX_REGS, regex_pmatch, 0);
                if ( regex_error == 0 ) {
                        asprintf( &msg, RESULT_TEMPLATE_STATUS_RESPONSE_TIME,
                                        protocol_text( use_ssl ),
                                        state_text( STATE_OK ),
                                        page->status,
                                        elapsed_time,
                                        elapsed_time );
                        terminate( STATE_OK, msg );
                } else {
                        if ( regex_error == REG_NOMATCH ) {
                                asprintf( &msg, "%s, %s: regex pattern not found\n",
                                                protocol_text( use_ssl) ,
                                                state_text( STATE_CRITICAL ) );
                                terminate( STATE_CRITICAL, msg );
                        } else {
                                regerror( regex_error, &regex_preg, regex_error_buffer, MAX_INPUT_BUFFER);
                                asprintf( &msg, "%s %s: Regex execute Error: %s\n",
                                                protocol_text( use_ssl) ,
                                                state_text( STATE_CRITICAL ),
                                                regex_error_buffer );
                                terminate( STATE_CRITICAL, msg );
                        }
                }
        }
#endif

        return STATE_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int check_http_response ( struct pageref page)

Definition at line 959 of file check_http-with-client-certificate.c.

{
        char *msg = "";

        /* check response time befor anything else */
        if ( use_critical_interval && ( elapsed_time > critical_interval ) ) {
                asprintf( &msg, RESULT_TEMPLATE_RESPONSE_TIME, 
                                protocol_text( use_ssl ),
                                state_text( STATE_CRITICAL ),
                                elapsed_time,
                                elapsed_time ); 
                terminate( STATE_CRITICAL, msg );
        }
        if ( use_warning_interval  && ( elapsed_time > warning_interval ) ) {
                asprintf( &msg, RESULT_TEMPLATE_RESPONSE_TIME, 
                                protocol_text( use_ssl ),
                                state_text( STATE_WARNING ),
                                elapsed_time,
                                elapsed_time );
                terminate( STATE_WARNING, msg );
        }


        /* make sure the status line matches the response we are looking for */
        if ( strstr( page->status, http_expect ) ) {
                /* The result is only checked against the expected HTTP status line,
                   so exit immediately after this check */
                if ( use_http_expect_only ) {
                        if ( ( server_port == HTTP_PORT ) 
#ifdef HAVE_SSL
                             || ( server_port == HTTPS_PORT ) )
#else
                           )
#endif 
                                asprintf( &msg, "Expected HTTP response received from host\n" );
                        else
                                asprintf( &msg, "Expected HTTP response received from host on port %d\n", server_port );
                        terminate( STATE_OK, msg );
                }
        } else {
                if ( ( server_port == HTTP_PORT )
#ifdef HAVE_SSL
                     || ( server_port == HTTPS_PORT ) )
#else
                   )
#endif
                        asprintf( &msg, "Invalid HTTP response received from host\n" );
                else
                        asprintf( &msg, "Invalid HTTP response received from host on port %d\n", server_port );
                terminate( STATE_CRITICAL, msg );
        }

        /* check the return code */
        /* server errors result in a critical state */
        if ( strstr( page->status, "500" ) ||
             strstr( page->status, "501" ) ||
             strstr( page->status, "502" ) ||
             strstr( page->status, "503" ) ||
             strstr( page->status, "504" ) ||
             strstr( page->status, "505" )) {
                asprintf( &msg, RESULT_TEMPLATE_STATUS_RESPONSE_TIME,
                                protocol_text( use_ssl ),
                                state_text( http_client_error_state ),
                                page->status,
                                elapsed_time,
                                elapsed_time );
                terminate( STATE_CRITICAL, msg );
        }

        /* client errors result in a warning state */
        if ( strstr( page->status, "400" ) ||
             strstr( page->status, "401" ) ||
             strstr( page->status, "402" ) ||
             strstr( page->status, "403" ) ||
             strstr( page->status, "404" ) ||
             strstr( page->status, "405" ) ||
             strstr( page->status, "406" ) ||
             strstr( page->status, "407" ) ||
             strstr( page->status, "408" ) ||
             strstr( page->status, "409" ) ||
             strstr( page->status, "410" ) ||
             strstr( page->status, "411" ) ||
             strstr( page->status, "412" ) ||
             strstr( page->status, "413" ) ||
             strstr( page->status, "414" ) ||
             strstr( page->status, "415" ) ||
             strstr( page->status, "416" ) ||
             strstr( page->status, "417" ) ) {
                asprintf( &msg, RESULT_TEMPLATE_STATUS_RESPONSE_TIME,
                                protocol_text( use_ssl ),
                                state_text( http_client_error_state ),
                                page->status,
                                elapsed_time,
                                elapsed_time );
                terminate( http_client_error_state, msg );
        }

        /* check redirected page if specified */
        if (strstr( page->status, "300" ) ||
            strstr( page->status, "301" ) ||
            strstr( page->status, "302" ) ||
            strstr( page->status, "303" ) ||
            strstr( page->status, "304" ) ||
            strstr( page->status, "305" ) ||
            strstr( page->status, "306" ) ||
            strstr( page->status, "307" ) ) {
                if ( http_redirect_state == STATE_DEPENDENT ) {
                                /* returning STATE_DEPENDENT means follow redirect */
                                return STATE_DEPENDENT;
                } else {
                        asprintf( &msg, RESULT_TEMPLATE_STATUS_RESPONSE_TIME,
                                        protocol_text( use_ssl ),
                                        state_text( http_redirect_state ),
                                        page->status,
                                        elapsed_time,
                                        elapsed_time );
                        terminate( http_redirect_state, msg );
                }
        }

        return STATE_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int http_request ( int  sock,
struct pageref page 
)

Definition at line 820 of file check_http-with-client-certificate.c.

{
        char *buffer = "";
        char recvbuff[MAX_INPUT_BUFFER] = ""; 
        int buffer_len = 0;
        int content_len = 0;
        size_t sendsize = 0;
        size_t recvsize = 0;
        char *content = ""; 
        size_t size = 0;
        char *basic_auth_encoded = NULL;

        asprintf( &buffer, HTTP_TEMPLATE_REQUEST, buffer, http_method, http_url_path );

        asprintf( &buffer, HTTP_TEMPLATE_HEADER_USERAGENT, buffer, progname, REVISION, PACKAGE_VERSION );

        if ( use_server_hostname ) {
                asprintf( &buffer, HTTP_TEMPLATE_HEADER_HOST, buffer, server_hostname );
        }

        if ( use_basic_auth ) {
                basic_auth_encoded = base64( basic_auth, strlen( basic_auth ) );
                asprintf( &buffer, HTTP_TEMPLATE_HEADER_AUTH, buffer, basic_auth_encoded );
        }

        /* either send http POST data */
        if ( use_http_post_data ) {
        /* based on code written by Chris Henesy <lurker@shadowtech.org> */
                asprintf( &buffer, "Content-Type: application/x-www-form-urlencoded\r\n" );
                asprintf( &buffer, "Content-Length: %i\r\n\r\n", buffer, content_len );
                asprintf( &buffer, "%s%s%s", buffer, http_post_data, "\r\n" );
                sendsize = send( sock, buffer, strlen( buffer ), 0 );
                if ( sendsize < strlen( buffer ) ) {
                        printf( "ERROR: Incomplete write\n" );
                        return STATE_CRITICAL;
                }
        /* or just a newline */
        } else {
               asprintf( &buffer, "%s%s", buffer, "\r\n" );
                     sendsize = send( sock, buffer, strlen( buffer ) , 0 );
                     if ( sendsize < strlen( buffer ) ) {
                      printf( "ERROR: Incomplete write\n" );
                       return STATE_CRITICAL;
               }
       }


        /* read server's response */

        do {
                recvsize = recv( sock, recvbuff, MAX_INPUT_BUFFER - 1, 0 );
                if ( recvsize > (size_t) 0 ) {
                        recvbuff[recvsize] = '\0';
                        asprintf( &content, "%s%s", content, recvbuff );
                        size += recvsize;
                }
        } while ( recvsize > (size_t) 0 );

        asprintf( &page->content, "%s", content );
        page->size = size;

        /* return a CRITICAL status if we couldn't read any data */
        if ( size == (size_t) 0)
                ssl_terminate( STATE_CRITICAL, "No data received" );

        return STATE_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 332 of file check_http-with-client-certificate.c.

{
        int result = STATE_UNKNOWN;
        int sock;
        struct pageref page;
#ifdef HAVE_SSL
        SSL_CTX *ctx;
        SSL *ssl;
        BIO *sbio;
#endif

        if ( process_arguments(argc, argv) == ERROR )
                usage( "check_http: could not parse arguments\n" );

#ifdef HAVE_SSL
        /* build SSL context if required:
         * a) either we use ssl from the beginning OR
         * b) or we follor redirects wich may lead os to a ssl page 
         */
        if ( use_ssl || ( http_redirect_state == STATE_DEPENDENT ) )
                ctx=initialize_ssl_ctx();
#endif

        /* Loop around 3xx onredirect=follow */
        do {

                /*
                 * initialize alarm signal handling, set socket timeout, start timer
                 * socket_timeout and socket_timeout_alarm_handler are defined in
                 * netutils.c
                 */
                (void) signal( SIGALRM, socket_timeout_alarm_handler );
                (void) alarm( socket_timeout );
                gettimeofday( &start_tv, NULL );
        
                /* make a tcp connection */
                result = my_tcp_connect( server_host, server_port, &sock );
        
                /* result of tcp connect */
                if ( result == STATE_OK )
                {
#ifdef HAVE_SSL
                        /* make a ssl connection */
                        if ( use_ssl ) {
                                ssl=SSL_new( ctx );
                                sbio=BIO_new_socket( sock, BIO_NOCLOSE );
                                SSL_set_bio( ssl, sbio, sbio);
                                if ( SSL_connect( ssl ) <= 0 )
                                        ssl_terminate( STATE_CRITICAL, "check_http: SSL connect error" );

                                /* fetch server certificate */
                                result = fetch_server_certificate( ssl );

                                /* verify server certificate against CAs */
                                if ( ( result == STATE_OK ) && use_ca_certificate ) {
                                        result = check_server_certificate_chain( ssl );
                                }

                                /* check if certificate matches hostname */
                                if ( ( result == STATE_OK ) && use_server_hostname ) {
                                        result = check_server_certificate_hostname();
                                }

                                if ( result == STATE_OK ) {
                                        /* check server certificate expire date */
                                        if ( check_server_certificate ) {
                                                result = check_server_certificate_expires();
                                        /* OR: perform http request */
                                        } else {
                                                result = https_request( ctx, ssl, (struct pageref *) &page );
                                        }
                                }
                                SSL_shutdown( ssl );
                                SSL_free( ssl );
                        } else {
#endif
                        /* HTTP implementation */
                        result = http_request( sock, (struct pageref *) &page );
#ifdef HAVE_SSL
                        }
#endif
                        /* stop timer and calculate elapsed_time */
                        elapsed_time = delta_time( start_tv );

                        /* close the tcp connection */
                        close( sock );

                        /* reset the alarm */
                        alarm( 0 );

                        /* analyze http page */
                        /* TO DO */
                        if ( result == STATE_OK )
                                result = parse_http_response( (struct pageref *) &page );

                        if ( result == STATE_OK )
                                result = check_http_response( (struct pageref *) &page );

                        switch ( result ) {
                                case STATE_OK:
                                        /* weiter geht's */
                                        result = check_http_content( (struct pageref *) &page );
                                        break;
                                case STATE_DEPENDENT:
                                        /* try to determine redirect parameters */
                                        result = prepare_follow_redirect( (struct pageref *) &page );
                                        break;
                        }

                } else {
                        /* some error occured while trying to make a tcp connect */
                        exit( result );
                }

        } while ( result == STATE_DEPENDENT ); // end of onredirect loop

        /* destroy SSL context */
#ifdef HAVE_SSL
        if ( use_ssl || ( http_redirect_state == STATE_DEPENDENT ) )
                destroy_ssl_ctx( ctx );
#endif

        /* if we ever get to this point, everything went fine */
        printf( RESULT_TEMPLATE_STATUS_RESPONSE_TIME, 
                protocol_text( use_ssl ),
                state_text( result ),
                page.status,
                elapsed_time,
                elapsed_time );

        return result;
}

Here is the call graph for this function:

int parse_http_response ( struct pageref page)

Definition at line 890 of file check_http-with-client-certificate.c.

{
       char *content = "";     //local copy of struct member
        char *status = "";      //local copy of struct member
        char *header = "";      //local copy of struct member
        size_t len = 0;         //temporary used
        char *pos = "";         //temporary used

        asprintf( &content, "%s", page->content );

        /* find status line and null-terminate it */
        // copy content to status
        status = content;
        
        // find end of status line and copy pointer to pos
        content += (size_t) strcspn( content, "\r\n" );
        pos = content;

        // advance content pointer behind the newline of status line
        content += (size_t) strspn( content, "\r\n" );

        // null-terminate status line at pos
        status[strcspn( status, "\r\n")] = 0;
        strip( status );

        // copy final status to struct member
        page->status = status;


        /* find header and null-terminate it */
        // copy remaining content to header
        header = content;

        // loop until line containing only newline is found (end of header)
        while ( strcspn( content, "\r\n" ) > 0 ) {
                //find end of line and copy pointer to pos
                content += (size_t) strcspn( content, "\r\n" );
                pos = content;

                if ( ( strspn( content, "\r" ) == 1 && strspn( content, "\r\n" ) >= 2 ) ||
                     ( strspn( content, "\n" ) == 1 && strspn( content, "\r\n" ) >= 2 ) )
                        content += (size_t) 2;
                else
                        content += (size_t) 1;
        }
        // advance content pointer behind the newline
        content += (size_t) strspn( content, "\r\n" );

        // null-terminate header at pos
        header[pos - header] = 0;

        // copy final header to struct member
        page->header = header;


        // copy remaining content to body
        page->body = content;

        if ( verbose ) {
                printf( "STATUS: %s\n", page->status );
                printf( "HEADER: \n%s\n", page->header );
                printf( "BODY: \n%s\n", page->body );
        }

        return STATE_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int prepare_follow_redirect ( struct pageref page)

Definition at line 1143 of file check_http-with-client-certificate.c.

{
        char *header = NULL;
        char *msg = "";
        char protocol[6];
        char hostname[MAX_IPV4_HOSTLENGTH];
        char port[6];
        char *url_path = NULL;
        char *orig_url_path = NULL;
        char *orig_url_dirname = NULL;
        size_t len = 0;

        asprintf( &header, "%s", page->header );


        /* restore some default values */
        use_http_post_data = FALSE;
        asprintf( &http_method, "%s", DEFAULT_HTTP_METHOD );

        /* copy url of original request, maybe we need it to compose 
           absolute url from relative Location: header */
        asprintf( &orig_url_path, "%s", http_url_path );

        while ( strcspn( header, "\r\n" ) > (size_t) 0 ) {
                url_path = realloc( url_path, (size_t) strcspn( header, "\r\n" ) );
                if ( url_path == NULL )
                        terminate( STATE_UNKNOWN, "HTTP UNKNOWN: could not reallocate url_path" );


                /* Try to find a Location header combination of METHOD HOSTNAME PORT and PATH */
                /* 1. scan for Location: http[s]://hostname:port/path */
                if ( sscanf ( header, HTTP_HEADER_LOCATION_MATCH HTTP_HEADER_PROTOCOL_MATCH HTTP_HEADER_HOSTNAME_MATCH HTTP_HEADER_PORT_MATCH HTTP_HEADER_URL_PATH_MATCH, &protocol, &hostname, &port, url_path ) == 4 ) {
                        asprintf( &server_hostname, "%s", hostname );
                        asprintf( &server_host, "%s", hostname );
                        use_ssl = chk_protocol(protocol);
                        server_port = atoi( port );
                        asprintf( &http_url_path, "%s", url_path );
                        return STATE_DEPENDENT;
                } 
                else if ( sscanf ( header, HTTP_HEADER_LOCATION_MATCH HTTP_HEADER_PROTOCOL_MATCH HTTP_HEADER_HOSTNAME_MATCH HTTP_HEADER_URL_PATH_MATCH, &protocol, &hostname, url_path ) == 3) {
                        asprintf( &server_hostname, "%s", hostname );
                        asprintf( &server_host, "%s", hostname );
                        use_ssl = chk_protocol(protocol);
                        server_port = protocol_std_port(use_ssl);
                        asprintf( &http_url_path, "%s", url_path );
                        return STATE_DEPENDENT;
                }
                else if ( sscanf ( header, HTTP_HEADER_LOCATION_MATCH HTTP_HEADER_PROTOCOL_MATCH HTTP_HEADER_HOSTNAME_MATCH HTTP_HEADER_PORT_MATCH, &protocol, &hostname, &port ) == 3) {
                        asprintf( &server_hostname, "%s", hostname );
                        asprintf( &server_host, "%s", hostname );
                        use_ssl = chk_protocol(protocol);
                        server_port = atoi( port );
                        asprintf( &http_url_path, "%s", DEFAULT_HTTP_URL_PATH );
                        return STATE_DEPENDENT;
                }
                else if ( sscanf ( header, HTTP_HEADER_LOCATION_MATCH HTTP_HEADER_PROTOCOL_MATCH HTTP_HEADER_HOSTNAME_MATCH, protocol, hostname ) == 2 ) {
                        asprintf( &server_hostname, "%s", hostname );
                        asprintf( &server_host, "%s", hostname );
                        use_ssl = chk_protocol(protocol);
                        server_port = protocol_std_port(use_ssl);
                        asprintf( &http_url_path, "%s", DEFAULT_HTTP_URL_PATH );
                }
                else if ( sscanf ( header, HTTP_HEADER_LOCATION_MATCH HTTP_HEADER_URL_PATH_MATCH, url_path ) == 1 ) {
                        /* check for relative url and prepend path if necessary */
                        if ( ( url_path[0] != '/' ) && ( orig_url_dirname = strrchr( orig_url_path, '/' ) ) ) {
                                *orig_url_dirname = '\0';
                                asprintf( &http_url_path, "%s%s", orig_url_path, url_path );
                        } else {
                                asprintf( &http_url_path, "%s", url_path );
                        }
                        return STATE_DEPENDENT;
                }
                header += (size_t) strcspn( header, "\r\n" );
                header += (size_t) strspn( header, "\r\n" );
        } /* end while (header) */
        

        /* default return value is STATE_DEPENDENT to continue looping in main() */
        asprintf( &msg, "% %: % - Could not find redirect Location",
                        protocol_text( use_ssl ),
                        state_text( STATE_UNKNOWN ),
                        page->status );
        terminate( STATE_UNKNOWN, msg );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void print_help ( void  )

Definition at line 467 of file check_http-with-client-certificate.c.

{
        print_revision( progname, REVISION );
        printf
                ( "Copyright (c) %s %s <%s>\n\n%s\n",
                 COPYRIGHT, AUTHORS, EMAIL, HELP_TXT_SUMMARY );
        print_usage();
        printf( "NOTE: One or both of -H and -I must be specified\n" );
        printf( "\nOptions:\n" HELP_TXT_LONGOPTIONS "\n",
                HTTP_PORT, DEFAULT_HTTP_URL_PATH, HTTPS_PORT,
                DEFAULT_HTTP_EXPECT, DEFAULT_SOCKET_TIMEOUT );
#ifdef HAVE_SSL
        //printf( SSLDESCRIPTION );
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void print_usage ( void  )

Definition at line 389 of file check_cpqarray.c.

{
  printf("cpqarrayd [options]\n");
  printf("   -h         prints this text\n");
  printf("   -d         enables debugging\n");
}
int process_arguments ( int  argc,
char **  argv 
)

Variable Documentation

Definition at line 209 of file check_http-with-client-certificate.c.

Definition at line 246 of file check_http-with-client-certificate.c.

Definition at line 247 of file check_http-with-client-certificate.c.

double critical_interval = 0

Definition at line 197 of file check_http-with-client-certificate.c.

double elapsed_time = 0

Definition at line 198 of file check_http-with-client-certificate.c.

Definition at line 249 of file check_http-with-client-certificate.c.

Definition at line 245 of file check_http-with-client-certificate.c.

Definition at line 238 of file check_http-with-client-certificate.c.

char* http_post_data = ""

Definition at line 241 of file check_http-with-client-certificate.c.

Definition at line 248 of file check_http-with-client-certificate.c.

char* http_url_path = ""

Definition at line 239 of file check_http-with-client-certificate.c.

Definition at line 243 of file check_http-with-client-certificate.c.

const char* progname = "check_http"

Definition at line 39 of file check_http-with-client-certificate.c.

char* server_host = ""

Definition at line 204 of file check_http-with-client-certificate.c.

char* server_hostname = ""

Definition at line 203 of file check_http-with-client-certificate.c.

Definition at line 206 of file check_http-with-client-certificate.c.

Definition at line 208 of file check_http-with-client-certificate.c.

Definition at line 196 of file check_http-with-client-certificate.c.

Definition at line 244 of file check_http-with-client-certificate.c.

Definition at line 240 of file check_http-with-client-certificate.c.

Definition at line 242 of file check_http-with-client-certificate.c.

Definition at line 202 of file check_http-with-client-certificate.c.

Definition at line 205 of file check_http-with-client-certificate.c.

int use_ssl = FALSE

Definition at line 221 of file check_http-with-client-certificate.c.

Definition at line 194 of file check_http-with-client-certificate.c.

int verbose = FALSE

Definition at line 191 of file check_http-with-client-certificate.c.

double warning_interval = 0

Definition at line 195 of file check_http-with-client-certificate.c.