Exemple #1
0
/**
 *  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;
  
}
Exemple #2
0
/**
 *  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;
}
Exemple #3
0
/**
 *  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;
}
Exemple #4
0
/**
 *  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;

}
Exemple #5
0
/**
 *  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;
  
}
Exemple #6
0
/**
 *  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;

}
Exemple #7
0
/**
 *  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;
    }
  }
}
Exemple #10
0
/**
 *  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;
  
}
Exemple #11
0
/**
 *  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;
  
}
Exemple #12
0
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);
}
Exemple #13
0
/**
 * 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;
}
Exemple #14
0
/**
 * 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;
}
Exemple #15
0
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);
  }
  
}
Exemple #17
0
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;

}
Exemple #18
0
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;
}
Exemple #19
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
 * @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;
}
Exemple #20
0
/**
 *  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;
}
Exemple #21
0
/**
 *  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;
}
Exemple #22
0
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;

}
Exemple #23
0
/**
 * 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);

}
Exemple #24
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;
}