/** * A simple 'SSH protocol version exchange' implemetation based on * RFC (http://www.openssh.com/txt/draft-ietf-secsh-transport-14.txt) * * @author Igor Homyakov, <*****@*****.**> * * @file */ int check_ssh(Socket_T s) { char buf[STRLEN]; ASSERT(s); if(!socket_readln(s, buf, sizeof(buf))) { LogError("SSH: error receiving identification string -- %s\n", STRERROR); return FALSE; } if(! Util_startsWith(buf, "SSH-")) { LogError("SSH: protocol error %s\n", buf); return FALSE; } /* send identification string back to server */ if(socket_write(s, buf, strlen(buf)) <= 0) { LogError("SSH: error sending identification string -- %s\n", STRERROR); return FALSE; } /* Read one extra line to prevent the "Read from socket failed" warning */ socket_readln(s, buf, sizeof(buf)); return TRUE; }
/** * Check the server for greeting code 220 and then send a QUIT and * check for code 221. If alive return TRUE, else, return FALSE. * * @file */ int check_ftp(Socket_T socket) { int status; char buf[STRLEN]; ASSERT(socket); do { if (! socket_readln(socket, buf, STRLEN)) { socket_setError(socket, "FTP: error receiving data -- %s", STRERROR); return FALSE; } Str_chomp(buf); } while(buf[3] == '-'); // Discard multi-line response if (sscanf(buf, "%d", &status) != 1 || status != 220) { socket_setError(socket, "FTP greeting error: %s", buf); return FALSE; } if (socket_print(socket, "QUIT\r\n") < 0) { socket_setError(socket, "FTP: error sending data -- %s", STRERROR); return FALSE; } if (! socket_readln(socket, buf, STRLEN)) { socket_setError(socket, "FTP: error receiving data -- %s", STRERROR); return FALSE; } Str_chomp(buf); if (sscanf(buf, "%d", &status) != 1 || status != 221) { socket_setError(socket, "FTP quit error: %s", buf); return FALSE; } return TRUE; }
/** * Check the server for greeting code '* OK' and then send LOGOUT and * check for code '* BYE'. If alive return TRUE, else, return FALSE. * * @file */ int check_imap(Socket_T socket) { char buf[STRLEN]; const char *ok = "* OK"; const char *bye = "* BYE"; ASSERT(socket); // Read and check IMAP greeting if (! socket_readln(socket, buf, sizeof(buf))) { socket_setError(socket, "IMAP: greeting read error -- %s", STRERROR); return FALSE; } Str_chomp(buf); if (strncasecmp(buf, ok, strlen(ok)) != 0) { socket_setError(socket, "IMAP: invalid greeting -- %s", buf); return FALSE; } // Logout and check response if (socket_print(socket, "001 LOGOUT\r\n") < 0) { socket_setError(socket, "IMAP: logout command error -- %s", STRERROR); return FALSE; } if (! socket_readln(socket, buf, sizeof(buf))) { socket_setError(socket, "IMAP: logout response read error -- %s", STRERROR); return FALSE; } Str_chomp(buf); if (strncasecmp(buf, bye, strlen(bye)) != 0) { socket_setError(socket, "IMAP: invalid logout response: %s", buf); return FALSE; } return TRUE; }
/** * Check the server for greeting "@RSYNCD: XX, then send this greeting back * to server, send command '#list' to get a listing of modules. * * @author Igor Homyakov <*****@*****.**> * * @file */ int check_rsync(Socket_T s) { char buf[64]; char header[10]; int rc, version_major, version_minor; char *rsyncd = "@RSYNCD:"; char *rsyncd_exit = "@RSYNCD: EXIT"; ASSERT(s); /* Read and check the greeting */ if (!socket_readln(s, buf, sizeof(buf))) { LogError("RSYNC: did not see server greeting -- %s\n", STRERROR); return FALSE; } Util_chomp(buf); rc = sscanf(buf, "%10s %d.%d", header, &version_major, &version_minor); if ((rc == EOF) || (rc != 3)) { LogError("RSYNC: server greeting parse error %s\n", buf); return FALSE; } if (strncasecmp(header, rsyncd, strlen(rsyncd)) != 0) { LogError("RSYNC: server sent unexpected greeting -- %s\n", buf); return FALSE; } /* Send back the greeting */ if (socket_print(s, "%s\n", buf) <= 0) { LogError("RSYNC: identification string send failed -- %s\n", STRERROR); return FALSE; } /* Send #list command */ if (socket_print(s, "#list\n") < 0) { LogError("RSYNC: #list command failed -- %s\n", STRERROR); return FALSE; } /* Read response: discard list output and check that we've received successful exit */ do { if (! socket_readln(s, buf, sizeof(buf))) { LogError("RSYNC: error receiving data -- %s\n", STRERROR); return FALSE; } Util_chomp(buf); } while (strncasecmp(buf, rsyncd, strlen(rsyncd))); if (strncasecmp(buf, rsyncd_exit, strlen(rsyncd_exit)) != 0) { LogError("RSYNC: server sent unexpected response -- %s\n", buf); return FALSE; } return TRUE; }
/** * Check the server for greeting code 220 and then send a QUIT and * check for code 221. If alive return TRUE, else, return FALSE. * * @author Jan-Henrik Haukeland, <*****@*****.**> * @author Michael Amster, <*****@*****.**> * * @version \$Id: ftp.c,v 1.15 2004/02/18 22:31:42 chopp Exp $ * * @file */ int check_ftp(Socket_T s) { int status; char buf[STRLEN]; char msg[STRLEN]; ASSERT(s); if(! socket_readln(s, buf, STRLEN)) { log("FTP: error receiving data -- %s\n", STRERROR); return FALSE; } chomp(buf, STRLEN); /* RATS: ignore */ /* chomp does zero termination */ sscanf(buf, "%d %s", &status, msg); if(status != 220) { log("FTP error: %s\n", buf); return FALSE; } /* Read past banners */ while(NULL != socket_readln(s, buf, STRLEN)) { if(starts_with(buf, "220")) continue; } if(socket_print(s, "QUIT\r\n") < 0) { log("FTP: error sending data -- %s\n", STRERROR); return FALSE; } if(socket_read(s, buf, STRLEN) <= 0) { log("FTP: error receiving data -- %s\n", STRERROR); return FALSE; } chomp(buf, STRLEN); /* RATS: ignore */ /* chomp does zero termination */ sscanf(buf, "%d %s", &status, msg); if(status != 221) { log("FTP error: %s\n", buf); return FALSE; } return TRUE; }
/** * A simple Postfix SMTP access policy delegation protocol test * * To not affect real traffic, we send the following request with * fixed virtual triplet values to the server: * request=smtpd_access_policy * protocol_state=RCPT * protocol_name=SMTP * [email protected] * [email protected] * client_address=1.2.3.4 * client_name=mx.foo.tld * and check that the server replies with some action. * * @file */ int check_postfix_policy(Socket_T socket) { char buf[STRLEN]; ASSERT(socket); if(socket_print(socket, "request=smtpd_access_policy\n" "protocol_state=RCPT\n" "protocol_name=SMTP\n" "[email protected]\n" "[email protected]\n" "client_address=1.2.3.4\n" "client_name=mx.foo.tld\n" "\n") < 0) { socket_setError(socket, "POSTFIX-POLICY: error sending data -- %s", STRERROR); return FALSE; } if(! socket_readln(socket, buf, sizeof(buf))) { socket_setError(socket, "POSTFIX-POLICY: error receiving data -- %s", STRERROR); return FALSE; } Str_chomp(buf); if( (strlen(buf) <= 7) || strncasecmp(buf, "action=", 7) ) { socket_setError(socket, "POSTFIX-POLICY error: %s", *buf?buf:"no action returned"); return FALSE; } return TRUE; }
/** * A simple DWP (database wire protocol) test. * * We send the following request to the server: * 'HEAD / HTTP/1.1' * and check the server's status code. * * If the status code is >= 400, an error has occurred. * Return TRUE if the status code is 200, otherwise FALSE. * * @file */ int check_dwp(Socket_T socket) { #define REQ_LENGTH 1024 int n; int status; char buf[STRLEN]; char proto[STRLEN]; ASSERT(socket); if(socket_print(socket, "HEAD / HTTP/1.1\r\n" "Connection: close\r\n\r\n") < 0) { socket_setError(socket, "DWP: error sending data -- %s\n", STRERROR); return FALSE; } if(! socket_readln(socket, buf, sizeof(buf))) { socket_setError(socket, "DWP: error receiving data -- %s\n", STRERROR); return FALSE; } Str_chomp(buf); n= sscanf(buf, "%255s %d", proto, &status); if(n!=2 || (status >= 400)) { socket_setError(socket, "DWP error: %s\n", buf); return FALSE; } return TRUE; }
/** * Returns a new HttpRequest object wrapping the client request */ static HttpRequest create_HttpRequest(Socket_T S) { HttpRequest req= NULL; char url[REQ_STRLEN]; char line[REQ_STRLEN]; char protocol[STRLEN]; char method[REQ_STRLEN]; if(socket_readln(S, line, REQ_STRLEN) == NULL) { internal_error(S, SC_BAD_REQUEST, "No request found"); return NULL; } Str_chomp(line); if(sscanf(line, "%1023s %1023s HTTP/%3[1.0]", method, url, protocol) != 3) { internal_error(S, SC_BAD_REQUEST, "Cannot parse request"); return NULL; } if(strlen(url) >= MAX_URL_LENGTH) { internal_error(S, SC_BAD_REQUEST, "[error] URL too long"); return NULL; } NEW(req); req->S= S; Util_urlDecode(url); req->url= Str_dup(url); req->method= Str_dup(method); req->protocol= Str_dup(protocol); create_headers(req); if(!create_parameters(req)) { destroy_HttpRequest(req); internal_error(S, SC_BAD_REQUEST, "Cannot parse Request parameters"); return NULL; } return req; }
/** * Create HTTP headers for the given request */ static void create_headers(HttpRequest req) { Socket_T S; char *value; HttpHeader header= NULL; char line[REQ_STRLEN]; S= req->S; while(1) { if(! socket_readln(S, line, sizeof(line))) break; if(!strcasecmp(line, "\r\n") || !strcasecmp(line, "\n")) break; if(NULL != (value= strchr(line, ':'))) { NEW(header); *value++= 0; Str_trim(line); Str_trim(value); Str_chomp(value); header->name= Str_dup(line); header->value= Str_dup(value); header->next= req->headers; req->headers= header; } } }
/** * Send PING and check for PONG. * If alive return TRUE, else, return FALSE. * * @author Debrard Sébastien <*****@*****.**> * * @file */ int check_clamav(Socket_T s) { char buf[STRLEN]; const char *ok= "PONG"; ASSERT(s); if(socket_print(s, "PING\r\n") < 0) { LogError("CLAMAV: error sending data -- %s\n", STRERROR); return FALSE; } if(!socket_readln(s, buf, sizeof(buf))) { LogError("CLAMAV: error receiving data -- %s\n", STRERROR); return FALSE; } Util_chomp(buf); if(strncasecmp(buf, ok, strlen(ok)) != 0) { LogError("CLAMAV error: %s\n", buf); return FALSE; } return TRUE; }
/** * Check the server for greeting code '* OK' and then send LOGOUT and * check for code '* BYE'. If alive return TRUE, else, return FALSE. * * @author Jan-Henrik Haukeland, <*****@*****.**> * * @file */ int check_imap(Socket_T s) { char buf[STRLEN]; const char *ok= "* OK"; const char *bye= "* BYE"; ASSERT(s); if(!socket_readln(s, buf, sizeof(buf))) { LogError("IMAP: error receiving data -- %s\n", STRERROR); return FALSE; } Util_chomp(buf); if(strncasecmp(buf, ok, strlen(ok)) != 0) { LogError("IMAP error: %s\n", buf); return FALSE; } if(socket_print(s, "001 LOGOUT\r\n") < 0) { LogError("IMAP: error sending data -- %s\n", STRERROR); return FALSE; } if(!socket_readln(s, buf, sizeof(buf))) { LogError("IMAP: error receiving data -- %s\n", STRERROR); return FALSE; } Util_chomp(buf); if(strncasecmp(buf, bye, strlen(bye)) != 0) { LogError("IMAP error: %s\n", buf); return FALSE; } return TRUE; }
static void do_status(SendMail_T *S) { int status = 0; StringBuffer_clear(S->status_message); char buf[STRLEN]; do { if (! socket_readln(S->socket, buf, sizeof(buf))) THROW(IOException, "Error receiving data from the mailserver '%s' -- %s", S->server, STRERROR); StringBuffer_append(S->status_message, "%s", buf); } while (buf[3] == '-'); // multi-line response Str_chomp(buf); if (sscanf(buf, "%d", &status) != 1 || status < 200 || status >= 400) THROW(IOException, "%s", buf); }
/** * Check that the server returns a valid HTTP response as well as checksum * or content regex if required * @param s A socket * @return TRUE if the response is valid otherwise FALSE */ static int check_request(Socket_T socket, Port_T P) { int status, content_length = -1; char buf[LINE_SIZE]; if (! socket_readln(socket, buf, LINE_SIZE)) { socket_setError(socket, "HTTP: Error receiving data -- %s\n", STRERROR); return FALSE; } Str_chomp(buf); if (! sscanf(buf, "%*s %d", &status)) { socket_setError(socket, "HTTP error: Cannot parse HTTP status in response: %s\n", buf); return FALSE; } if (status >= 400) { socket_setError(socket, "HTTP error: Server returned status %d\n", status); return FALSE; } /* Get Content-Length header value */ while (socket_readln(socket, buf, LINE_SIZE)) { if ((buf[0] == '\r' && buf[1] == '\n') || (buf[0] == '\n')) break; Str_chomp(buf); if (Str_startsWith(buf, "Content-Length")) { if (! sscanf(buf, "%*s%*[: ]%d", &content_length)) { socket_setError(socket, "HTTP error: Parsing Content-Length response header '%s'\n", buf); return FALSE; } if (content_length < 0) { socket_setError(socket, "HTTP error: Illegal Content-Length response header '%s'\n", buf); return FALSE; } } } if (P->url_request && P->url_request->regex && ! do_regex(socket, content_length, P->url_request)) return FALSE; if (P->request_checksum) return check_request_checksum(socket, content_length, P->request_checksum, P->request_hashtype); return TRUE; }
/** * Check that the server returns a valid HTTP response * @param C An mmonit object * @return TRUE if the response is valid otherwise FALSE */ static int data_check(Socket_T socket, Mmonit_T C) { int status; char buf[STRLEN]; if (! socket_readln(socket, buf, sizeof(buf))) { LogError("M/Monit: error receiving data from %s -- %s\n", C->url->url, STRERROR); return FALSE; } Str_chomp(buf); int n = sscanf(buf, "%*s %d", &status); if (n != 1 || (status >= 400)) { LogError("M/Monit: message sending failed to %s -- %s\n", C->url->url, buf); return FALSE; } return TRUE; }
static int expect(Socket_T socket, int expect) { int status; char buf[STRLEN]; do { if (! socket_readln(socket, buf, STRLEN)) { socket_setError(socket, "LMTP: error receiving data -- %s", STRERROR); return FALSE; } Str_chomp(buf); } while (buf[3] == '-'); // Discard multi-line response if (sscanf(buf, "%d", &status) != 1 || status != expect) { socket_setError(socket, "LMTP error: %s", buf); return FALSE; } return TRUE; }
static void do_status(SendMail_T *S) { int status; char buf[STRLEN]; if(!socket_readln(S->socket, buf, sizeof(buf))) { LogError("Sendmail: error receiving data from the mailserver '%s' -- %s\n", S->server, STRERROR); siglongjmp(S->error, TRUE); } Str_chomp(buf); sscanf(buf, "%d", &status); if(status >= 400) { LogError("Sendmail error: %s\n", buf); siglongjmp(S->error, TRUE); } }
static int expect(Socket_T socket, int expect, int log) { int status; char buf[STRLEN]; if(!socket_readln(socket, buf, STRLEN)) { socket_setError(socket, "LMTP: error receiving data -- %s\n", STRERROR); return FALSE; } Str_chomp(buf); sscanf(buf, "%d%*s", &status); if(status != expect) { if(log) socket_setError(socket, "LMTP error: %s\n", buf); return FALSE; } return TRUE; }
int check_apache_status(Socket_T socket) { ASSERT(socket); char host[STRLEN]; if (socket_print(socket, "GET /server-status?auto HTTP/1.1\r\n" "Host: %s\r\n" "Accept: */*\r\n" "User-Agent: Monit/%s\r\n" "Connection: close\r\n\r\n", Util_getHTTPHostHeader(socket, host, STRLEN), VERSION) < 0) { socket_setError(socket, "HTTP: error sending data -- %s", STRERROR); return FALSE; } char buffer[4096] = {0}; while (socket_readln(socket, buffer, sizeof(buffer))) { if (Str_startsWith(buffer, "Scoreboard: ")) { char *scoreboard = buffer + 12; // skip header return parse_scoreboard(socket, scoreboard); } } socket_setError(socket, "APACHE-STATUS: error -- no scoreboard found"); return FALSE; }
/** * Pass on to methods in http/cervlet.c to start/stop services * @param S A service name as stated in the config file * @param action A string describing the action to execute * @param attempts Number of attemps (in case of "already action already in progres...") * @return a string starting with "ERR" in for error, otherwise return "OK" */ char *control_service_daemon_message(const char *S, const char *action, int attempts, int check_exit_status /* ignored */) { char *rv = NULL; int status, content_length = 0; Socket_T s; char *auth; char buf[STRLEN]; ASSERT(S); ASSERT(action); if (Util_getAction(action) == ACTION_IGNORE) { return xstrdup("ERR1: invalid action"); } auth = Util_getBasicAuthHeaderMonit(); retry: /* Try with the socket first */ if (Run.bind_path) { s = socket_new(Run.bind_path, 0, SOCKET_TCP, Run.httpdssl, NET_TIMEOUT); } /* Try network connection */ if (!s) { if(!(s = socket_new(Run.bind_addr ? Run.bind_addr : "localhost", Run.httpdport, SOCKET_TCP, Run.httpdssl, NET_TIMEOUT))) { FREE(auth); return xstrdup("ERR2: cannot connect to the monit daemon"); } } /* Send request */ if (socket_print(s, "POST /%s HTTP/1.0\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: %d\r\n" "%s" "\r\n" "action=%s", S, strlen("action=") + strlen(action), auth ? auth : "", action) < 0) { return xstrdup("ERR3: cannot send the command"); goto err1; } /* Process response */ if (! socket_readln(s, buf, STRLEN)) { rv = xstrdup("ERR4: error receiving data"); goto err1; } Util_chomp(buf); if (! sscanf(buf, "%*s %d", &status)) { rv = xstrdup("ERR5: cannot parse status in response"); goto err1; } if (status >= 300) { /* Skip headers */ while (socket_readln(s, buf, STRLEN)) { if (! strncmp(buf, "\r\n", sizeof(buf))) break; if(Util_startsWith(buf, "Content-Length") && ! sscanf(buf, "%*s%*[: ]%d", &content_length)) { rv = xstrdup("ERR6: error parsing headers"); goto err1; } } if (content_length > 0 && content_length < 1024 && socket_readln(s, buf, STRLEN)) { char token[] = "</h2>"; char *p = strstr(buf, token); if (strlen(p) <= strlen(token)) { rv = xstrdup("ERR7: error parsing body"); goto err1; } p += strlen(token); rv = xcalloc(sizeof(unsigned char), content_length + 1 + 6); snprintf(rv, content_length + 1 + 6, "ERR8: %s", p); p = strstr(rv, "<p>"); if (p) *p = 0; attempts--; if ((attempts > 0) && (strstr(rv, "please try again later") != NULL)) { socket_free(&s); /*LogInfo("%s: retrying %s %s (%s)\n", prog, action, S, rv);*/ LogInfo("%s: retrying %s %s\n", prog, action, S); FREE(rv); sleep(1); goto retry; } } } else rv = xstrdup("OK"); err1: FREE(auth); socket_free(&s); return rv; }
/** * Simple MySQL test. * * In the case that the anonymous login is possible, * we will perform MySQL ping. If authentication failed * we suppose the anonymous login is denied and we will * return success, because the server at least performed * authentication => it seems it works. * * @file */ int check_mysql(Socket_T socket) { unsigned char buf[STRLEN]; unsigned char requestLogin[39] = { 0x23, 0x00, 0x00, // packet_length, 3 bytes 0x01, // packet_number, 1 byte 0x00, 0xa2, 0x00, 0x00, // client_flags, 4 bytes (do+auth 4.1, transact) 0x00, 0x00, 0x00, 0x40, // max_packet_size, 4 bytes 0x08, // charset_number (latin1), 1 byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // filler, 23 bytes 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // username 0x00, // password 0x00 }; unsigned char requestPing[5] = { 0x01, 0x00, 0x00, // packet_length, 3 bytes 0x00, // packet_number, 1 byte 0x0e // command ping (14), 1 byte }; unsigned char responsePing[5] = { 0x07, 0x00, 0x00, // packet_length, 3 bytes 0x01, // packet_number, 1 byte 0x00 // affected_rows, 1 byte // remaining 4 bytes ignored }; unsigned char requestQuit[5] = { 0x01, 0x00, 0x00, // packet_length, 3 bytes 0x00, // packet_number, 1 byte 0x01 // command quit (1), 1 byte }; ASSERT(socket); if(!socket_readln(socket, (char *)buf, sizeof(buf))) { socket_setError(socket, "MYSQL: error receiving greeting -- %s", STRERROR); return FALSE; } if(socket_write(socket, requestLogin, sizeof(requestLogin)) < 0) { socket_setError(socket, "MYSQL: error sending login -- %s", STRERROR); return FALSE; } /* read just first few bytes which contains enough information */ errno = 0; if(socket_read(socket, buf, 7) <= 6) { socket_setError(socket, "MYSQL: error receiving login response"); return FALSE; } /* Compare Packet Number: */ if(buf[3] != 0x02) { socket_setError(socket, "MYSQL: invalid response packet number"); return FALSE; } /* Compare Response Code: */ if(buf[4] == 0x00) { /* If OK, we are loged in and will perform MySQL ping */ if(socket_write(socket, (unsigned char *)requestPing, sizeof(requestPing)) < 0) { socket_setError(socket, "MYSQL: error sending ping -- %s", STRERROR); return FALSE; } if(socket_read(socket, buf, sizeof(responsePing)) <= 0) { socket_setError(socket, "MYSQL: error receiving ping response -- %s", STRERROR); return FALSE; } if(memcmp((unsigned char *)buf, (unsigned char *)responsePing, sizeof(responsePing))) { socket_setError(socket, "MYSQL: ping failed"); return FALSE; } if(socket_write(socket, (unsigned char *)requestQuit, sizeof(requestQuit)) < 0) { socket_setError(socket, "MYSQL: error sending quit -- %s", STRERROR); return FALSE; } return TRUE; } else if((buf[4] == 0xFF) && ((buf[5] == 0x15 && buf[6] == 0x04) || (buf[5] == 0xE3 && buf[6] == 0x04) || (buf[5] == 0x13 && buf[6] == 0x04))) { /* If access denied (1045) or server requires newer authentication protocol (1251) or bad handshake (1043) return success immediately */ return TRUE; } socket_setError(socket, "MYSQL: login failed (error code %d)", buf[6] * 256 + buf[5]); return FALSE; }
/** * Simple MySQL test. * * In the case that the anonymous login is possible, * we will perform MySQL ping. If authentication failed * we suppose the anonymous login is denied and we will * return success, because the server at least performed * authentication => it seems it works. * * @author Martin Pala, <*****@*****.**> * * @file */ int check_mysql(Socket_T s) { unsigned char buf[STRLEN]; unsigned char requestLogin[10] = { 0x06, /** Packet Length */ 0x00, 0x00, 0x01, /** Packet Number */ 0x00, /** Flags */ 0x00, /** Max Packet */ 0x00, 0x00, 0x00, /** Username*/ 0x00 /** Password*/ }; unsigned char requestPing[5] = { 0x01, /** Packet Length */ 0x00, 0x00, 0x00, /** Packet Number */ 0x0E /** Command Ping */ }; unsigned char responsePing[5] = { 0x03, /** Packet Length */ 0x00, 0x00, 0x01, /** Packet Number */ 0x00 /** Response Code OK */ /** Padding Ignored */ }; unsigned char requestQuit[5] = { 0x01, /** Packet Length */ 0x00, 0x00, 0x00, /** Packet Number */ 0x01 /** Command Quit */ }; ASSERT(s); if(!socket_readln(s, (char *)buf, sizeof(buf))) { LogError("MYSQL: error receiving greeting -- %s\n", STRERROR); return FALSE; } if(socket_write(s, requestLogin, sizeof(requestLogin)) < 0) { LogError("MYSQL: error sending login -- %s\n", STRERROR); return FALSE; } /* read just first few bytes which contains enough information */ errno = 0; if(socket_read(s, buf, 7) <= 6) { LogError("MYSQL: error receiving login response\n"); return FALSE; } /* Compare Packet Number: */ if(buf[3] != 0x02) { LogError("MYSQL: invalid response packet number\n"); return FALSE; } /* Compare Response Code: */ if(buf[4] == 0x00) { /* If OK, we are loged in and will perform MySQL ping */ if(socket_write(s, (unsigned char *)requestPing, sizeof(requestPing)) < 0) { LogError("MYSQL: error sending ping -- %s\n", STRERROR); return FALSE; } if(socket_read(s, buf, sizeof(responsePing)) <= 0) { LogError("MYSQL: error receiving ping response -- %s\n", STRERROR); return FALSE; } if(memcmp((unsigned char *)buf, (unsigned char *)responsePing, sizeof(responsePing))) { LogError("MYSQL: ping failed\n"); return FALSE; } if(socket_write(s, (unsigned char *)requestQuit, sizeof(requestQuit)) < 0) { LogError("MYSQL: error sending quit -- %s\n", STRERROR); return FALSE; } return TRUE; } else if((buf[4] == 0xFF) && ((buf[5] == 0x15 && buf[6] == 0x04) || (buf[5] == 0xE3 && buf[6] == 0x04))) { /* If access denied (1045) or server requires newer authentication protocol (1251), return success immediately */ return TRUE; } LogError("MYSQL: login failed (error code 0x%x%x)\n", buf[5], buf[6]); return FALSE; }
int check_sip(Socket_T socket) { int status; char buf[STRLEN]; int port; char *transport; Port_T P; const char *request; const char *myip; char *rport= ""; char *proto; ASSERT(socket); P= socket_get_Port(socket); ASSERT(P); request= P->request?P->request:"*****@*****.**"; port = socket_get_local_port(socket); proto = socket_is_secure(socket) ? "sips" : "sip"; switch(socket_get_type(socket)) { case SOCK_DGRAM: { transport="UDP"; rport=";rport"; break; } case SOCK_STREAM: { transport="TCP"; break; } default: { socket_setError(socket, "Unsupported socket type, only TCP and UDP are supported\n"); return TRUE; } } myip= socket_get_local_host(socket); if(socket_print(socket, "OPTIONS %s:%s SIP/2.0\r\n" "Via: SIP/2.0/%s %s:%d;branch=z9hG4bKh%u%s\r\n" "Max-Forwards: %d\r\n" "To: <%s:%s>\r\n" "From: monit <%s:monit@%s>;tag=%d\r\n" "Call-ID: %u\r\n" "CSeq: 63104 OPTIONS\r\n" "Contact: <%s:%s:%d>\r\n" "Accept: application/sdp\r\n" "Content-Length: 0\r\n" "User-Agent: %s/%s\r\n\r\n", proto, // protocol request, // to transport, // via transport udp|tcp myip, // who its from port, // our port random(), // branch rport, // rport option P->maxforward, // maximum forwards proto, // protocol request, // to proto, // protocol myip, // from host random(), // tag random(), // call id proto, // protocol myip, // contact host port, // contact port prog, VERSION // user agent ) < 0) { socket_setError(socket, "SIP: error sending data -- %s\n", STRERROR); return FALSE; } if(! socket_readln(socket, buf, sizeof(buf))) { socket_setError(socket, "SIP: error receiving data -- %s\n", STRERROR); return FALSE; } Str_chomp(buf); DEBUG("Response from SIP server: %s\n", buf); if(! sscanf(buf, "%*s %d", &status)) { socket_setError(socket, "SIP error: cannot parse SIP status in response: %s\n", buf); return FALSE; } if(status >= 400) { socket_setError(socket, "SIP error: Server returned status %d\n", status); return FALSE; } if(status >= 300 && status < 400) { socket_setError(socket, "SIP info: Server redirection. Returned status %d\n", status); return FALSE; } if(status > 100 && status < 200) { socket_setError(socket, "SIP error: Provisional response . Returned status %d\n", status); return FALSE; } return TRUE; }
/** * Extract the Scoreboard line from the mod_status response. * Count the active apache child processes, and those which are * in other states. If each percentage exceeds the corresponding * limit, then return FALSE. * @param s A socket * @param limit The maximum percentage of logging processes * @return TRUE if logging is OK otherwise FALSE */ static int check_apache_stat(Socket_T socket) { int scored = 0; int errors = 0; char line[READ_SIZE]; char search_string[READ_SIZE + 1]; int loglimit= 0; int closelimit= 0; int dnslimit= 0; int keepalivelimit= 0; int replylimit= 0; int requestlimit= 0; int startlimit= 0; int waitlimit= 0; int gracefullimit= 0; int cleanuplimit= 0; int no_logging = 0; int no_close = 0; int no_dns = 0; int no_keepalive = 0; int no_reply = 0; int no_request = 0; int no_start = 0; int no_wait = 0; int no_graceful = 0; int no_cleanup = 0; int active_servers = 0; char *p; Port_T myPort= (Port_T)socket_get_Port(socket); ASSERT(myPort); loglimit= myPort->ApacheStatus.loglimit; closelimit= myPort->ApacheStatus.closelimit; dnslimit= myPort->ApacheStatus.dnslimit; keepalivelimit= myPort->ApacheStatus.keepalivelimit; replylimit= myPort->ApacheStatus.replylimit; requestlimit= myPort->ApacheStatus.requestlimit; startlimit= myPort->ApacheStatus.startlimit; waitlimit= myPort->ApacheStatus.waitlimit; gracefullimit= myPort->ApacheStatus.gracefullimit; cleanuplimit= myPort->ApacheStatus.cleanuplimit; while(NULL != socket_readln(socket, line, READ_SIZE)) { if(Str_startsWith(line, "Scoreboard")) { if(1 != sscanf(line, "%*s%*[: ]%1024s", search_string)) { Str_chomp(line); socket_setError(socket, "APACHE-STATUS error: parsing Apache status response '%s'\n", line); return FALSE; } else { scored = 1; } } } DEBUG("Scoreboard: %s\n", search_string); /* Check that some scoreboard line was found, if not return an error */ if(!scored){ socket_setError(socket, "APACHE-STATUS error: no scoreboard line returned by Apache\n"); return FALSE; } /* Total each of the status messages in the scoreboard */ for(p = search_string ; *p ; p++){ active_servers++; switch(*p){ case 'S': no_start++; break; case 'R': no_request++; break; case 'W': no_reply++; break; case 'K': no_keepalive++; break; case 'D': no_dns++; break; case 'C': no_close++; break; case 'L': no_logging++; break; case 'G': no_graceful++; break; case 'I': no_cleanup++; break; case '_': no_wait++; break; case '.': active_servers--; break; } } if(active_servers <= 0){ socket_setError(socket, "APACHE-STATUS warning: No idle server or threads found\n"); /* This is not really an error, only a very bussy server */ return TRUE; } /* * Conditions are only tested if the limit parameter is greater than zero. */ if(loglimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.loglimitOP, (100 * no_logging / active_servers), loglimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are logging\n", loglimit); errors++; } } if(startlimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.startlimitOP, (100 * no_start / active_servers), startlimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are starting\n", startlimit); errors++; } } if(requestlimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.requestlimitOP, (100 * no_request / active_servers), requestlimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are reading requests\n", requestlimit); errors++; } } if(replylimit > 0 ){ if(Util_evalQExpression(myPort->ApacheStatus.replylimitOP, (100 * no_reply / active_servers), replylimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are sending a reply\n", replylimit); errors++; } } if(keepalivelimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.keepalivelimitOP, (100 * no_keepalive / active_servers), keepalivelimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are in keepalive\n", keepalivelimit); errors++; } } if(dnslimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.dnslimitOP, (100 * no_dns / active_servers), dnslimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are waiting for DNS\n", dnslimit); errors++; } } if(closelimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.closelimitOP, (100 * no_close / active_servers), closelimit)){ socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are closing connections\n", closelimit); errors++; } } if(gracefullimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.gracefullimitOP, (100 * no_graceful / active_servers), gracefullimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are finishing gracefully\n", gracefullimit); errors++; } } if(cleanuplimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.cleanuplimitOP, (100 * no_cleanup / active_servers), cleanuplimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are in idle cleanup\n", cleanuplimit); errors++; } } if(waitlimit > 0){ if(Util_evalQExpression(myPort->ApacheStatus.waitlimitOP, (100 * no_wait / active_servers), waitlimit)) { socket_setError(socket, "APACHE-STATUS error:" " %i percent of Apache processes are waiting for a connection\n", waitlimit); errors++; } } return (errors==0); }
/** * Pass on to methods in http/cervlet.c to start/stop services * @param S A service name as stated in the config file * @param action A string describing the action to execute * @return FALSE for error, otherwise TRUE */ int control_service_daemon(const char *S, const char *action) { int rv = FALSE; int status, content_length = 0; Socket_T s; char *auth; char buf[STRLEN]; ASSERT(S); ASSERT(action); if (Util_getAction(action) == ACTION_IGNORE) { LogError("%s: Cannot %s service '%s' -- invalid action %s\n", prog, action, S, action); return FALSE; } s = socket_new(Run.bind_addr ? Run.bind_addr : "localhost", Run.httpdport, SOCKET_TCP, Run.httpdssl, NET_TIMEOUT); if (!s) { LogError("%s: Cannot connect to the monit daemon. Did you start it with http support?\n", prog); return FALSE; } /* Send request */ auth = Util_getBasicAuthHeaderMonit(); if (socket_print(s, "POST /%s HTTP/1.0\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: %d\r\n" "%s" "\r\n" "action=%s", S, strlen("action=") + strlen(action), auth ? auth : "", action) < 0) { LogError("%s: Cannot send the command '%s' to the monit daemon -- %s", prog, action ? action : "null", STRERROR); goto err1; } /* Process response */ if (! socket_readln(s, buf, STRLEN)) { LogError("%s: error receiving data -- %s\n", prog, STRERROR); goto err1; } Util_chomp(buf); if (! sscanf(buf, "%*s %d", &status)) { LogError("%s: cannot parse status in response: %s\n", prog, buf); goto err1; } if (status >= 300) { char *message = NULL; /* Skip headers */ while (socket_readln(s, buf, STRLEN)) { if (! strncmp(buf, "\r\n", sizeof(buf))) break; if(Util_startsWith(buf, "Content-Length") && ! sscanf(buf, "%*s%*[: ]%d", &content_length)) goto err1; } if (content_length > 0 && content_length < 1024 && socket_readln(s, buf, STRLEN)) { char token[] = "</h2>"; char *p = strstr(buf, token); if (strlen(p) <= strlen(token)) goto err2; p += strlen(token); message = xcalloc(sizeof(unsigned char), content_length + 1); snprintf(message, content_length + 1, "%s", p); p = strstr(message, "<p>"); if (p) *p = 0; } err2: LogError("%s: action failed -- %s\n", prog, message ? message : "unable to parse response"); FREE(message); } else rv = TRUE; err1: FREE(auth); socket_free(&s); return rv; }