示例#1
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;

}
示例#2
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;
  
}
示例#3
0
/**
 *  Send PING and check for PONG.
 *  If alive return TRUE, else, return FALSE.
 *
 *  @file
 */
int check_clamav(Socket_T socket) {

  char buf[STRLEN];
  const char *ok = "PONG";

  ASSERT(socket);

  if(socket_print(socket, "PING\r\n") < 0) {
    socket_setError(socket, "CLAMAV: error sending data -- %s", STRERROR);
    return FALSE;
  }

  if(!socket_readln(socket, buf, sizeof(buf))) {
    socket_setError(socket, "CLAMAV: error receiving data -- %s", STRERROR);
    return FALSE;
  }

  Str_chomp(buf);

  if(strncasecmp(buf, ok, strlen(ok)) != 0) {
    socket_setError(socket, "CLAMAV error: %s", buf);
    return FALSE;
  }

  return TRUE;

}
示例#4
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;
}
示例#5
0
文件: ftp.c 项目: AsydSolutions/monit
/**
 *  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;
}
示例#6
0
文件: http.c 项目: ezotrank/monit-src
static int check_request_checksum(Socket_T socket, int content_length, char *checksum, int hashtype) {
        int n, keylength = 0;
        MD_T result, hash;
        md5_context_t ctx_md5;
        sha1_context_t ctx_sha1;
        char buf[READ_SIZE];

        if (content_length <= 0) {
                DEBUG("HTTP warning: Response does not contain a valid Content-Length -- cannot compute checksum\n");
                return TRUE;
        }

        switch (hashtype) {
                case HASH_MD5:
                        md5_init(&ctx_md5);
                        while (content_length > 0) {
                                if ((n = socket_read(socket, buf, content_length > sizeof(buf) ? sizeof(buf) : content_length)) < 0)
                                        break;
                                md5_append(&ctx_md5, (const md5_byte_t *)buf, n);
                                content_length -= n;
                        }
                        md5_finish(&ctx_md5, (md5_byte_t *)hash);
                        keylength = 16; /* Raw key bytes not string chars! */
                        break;
                case HASH_SHA1:
                        sha1_init(&ctx_sha1);
                        while (content_length > 0) {
                                if ((n = socket_read(socket, buf, content_length > sizeof(buf) ? sizeof(buf) : content_length)) < 0)
                                        break;
                                sha1_append(&ctx_sha1, (md5_byte_t *)buf, n);
                                content_length -= n;
                        }
                        sha1_finish(&ctx_sha1, (md5_byte_t *)hash);
                        keylength = 20; /* Raw key bytes not string chars! */
                        break;
                default:
                        socket_setError(socket, "HTTP checksum error: Unknown hash type\n");
                        return FALSE;
        }

        if (strncasecmp(Util_digest2Bytes((unsigned char *)hash, keylength, result), checksum, keylength * 2) != 0) {
                socket_setError(socket, "HTTP checksum error: Document checksum mismatch\n");
                return FALSE;
        } else {
                DEBUG("HTTP: Succeeded testing document checksum\n");
        }
        return TRUE;
}
示例#7
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;
}
示例#8
0
文件: http.c 项目: ezotrank/monit-src
int check_http(Socket_T socket) {
        Port_T P;
        char host[STRLEN];
        char auth[STRLEN]= {0};
        const char *request = NULL;
        const char *hostheader = NULL;

        ASSERT(socket);

        P = socket_get_Port(socket);

        ASSERT(P);

        request = P->request ? P->request : "/";

        Util_getHTTPHostHeader(socket, host, STRLEN);
        hostheader = P->request_hostheader ? P->request_hostheader : host;

        if (socket_print(socket,
                         "GET %s HTTP/1.1\r\n"
                         "Host: %s\r\n"
                         "Accept: */*\r\n"
                         "User-Agent: %s/%s\r\n"
                         "%s\r\n",
                         request, hostheader, prog, VERSION,
                         get_auth_header(P, auth, STRLEN)) < 0) {
                socket_setError(socket, "HTTP: error sending data -- %s\n", STRERROR);
                return FALSE;
        }

        return check_request(socket, P);
}
示例#9
0
static int say(Socket_T socket, char *msg) {
        if (socket_write(socket, msg, strlen(msg)) < 0) {
                socket_setError(socket, "LMTP: error sending data -- %s", STRERROR);
                return FALSE;
        }
        return TRUE;
}
示例#10
0
/**
 * Simple MySQL test. Connect to MySQL and read Server Handshake Packet.
 * If we can read the packet and it is not an error packet we assume the 
 * server is up and working.
 *
 *  @see http://dev.mysql.com/doc/internals/en/client-server-protocol.html
 */
int check_mysql(Socket_T socket) {
        ASSERT(socket);
        mysql_packet_t pkt;
        if (_response(socket, &pkt)) {
                short protocol_version = pkt.msg[0];
                unsigned char *server_version = pkt.msg + 1;
                // Protocol is 10 for MySQL 5.x
                if ((protocol_version > 12) || (protocol_version < 9))
                        socket_setError(socket, "Invalid protocol version %d", protocol_version);
                // Handshake packet should have sequence id 0
                else if (pkt.seq != 0)
                        socket_setError(socket, "Invalid packet sequence id %d", pkt.seq);
                else {
                        DEBUG("MySQL: Protocol: %d, Server Version: %s\n", protocol_version, server_version);
                        return TRUE;
                }
        }
        return FALSE;
}
示例#11
0
文件: lmtp.c 项目: ezotrank/monit-src
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;

}
示例#12
0
static int _response(Socket_T socket, mysql_packet_t *pkt) {
        memset(pkt, 0, sizeof *pkt);
        if (socket_read(socket, pkt->buf, 4) < 4) {
                socket_setError(socket, "Error receiving server response -- %s", STRERROR);
                return FALSE;
        }
        pkt->len = B3(pkt->buf);
        pkt->len = pkt->len > STRLEN ? STRLEN : pkt->len; // Adjust packet length for this buffer
        pkt->seq = pkt->buf[3];
        pkt->msg = pkt->buf + 4;
        if (socket_read(socket, pkt->msg, pkt->len) != pkt->len) {
                socket_setError(socket, "Error receiving server response -- %s", STRERROR);
                return FALSE;
        }
        if (*pkt->msg == MYSQL_ERROR) {
                unsigned short code = B2(pkt->msg + 1);
                unsigned char *err = pkt->msg + 9;
                socket_setError(socket, "Server returned error code %d -- %s", code, err);
                return FALSE;
        }
        return TRUE;
}
示例#13
0
文件: http.c 项目: ezotrank/monit-src
/**
 * 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;
}
示例#14
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;
}
示例#15
0
文件: http.c 项目: Happy-Ferret/Monit
int check_http(Socket_T socket) {
        Port_T P;
        char host[STRLEN];
        char auth[STRLEN] = {};
        const char *request = NULL;
        const char *hostheader = NULL;

        ASSERT(socket);

        P = socket_get_Port(socket);

        ASSERT(P);

        request = P->request ? P->request : "/";

        hostheader = _findHostHeaderIn(P->http_headers);
        hostheader = hostheader ? hostheader : P->request_hostheader
                                ? P->request_hostheader : Util_getHTTPHostHeader(socket, host, STRLEN); // Otherwise use deprecated request_hostheader or default host
        StringBuffer_T sb = StringBuffer_create(168);
        StringBuffer_append(sb,
                            "GET %s HTTP/1.1\r\n"
                            "Host: %s\r\n"
                            "Accept: */*\r\n"
                            "User-Agent: Monit/%s\r\n"
                            "%s",
                            request, hostheader, VERSION,
                            get_auth_header(P, auth, STRLEN));
        // Add headers if we have them
        if (P->http_headers) {
                for (list_t p = P->http_headers->head; p; p = p->next) {
                        if (Str_startsWith(p->e, "Host")) // Already set contrived above
                                continue;
                        StringBuffer_append(sb, "%s\r\n", p->e);
                }
        }
        StringBuffer_append(sb, "\r\n");
        int send_status = socket_write(socket, (void*)StringBuffer_toString(sb), StringBuffer_length(sb));
        StringBuffer_free(&sb);
        if (send_status < 0) {
                socket_setError(socket, "HTTP: error sending data -- %s", STRERROR);
                return FALSE;
        }

        return check_request(socket, P);
}
示例#16
0
/**
 * Check an Apache server to monitor its status.
 * Do this using the server-status report from mod_status, which
 * will only be available if the server is responding to
 * some extent.
 *
 * Currently based on the Scoreboard response, which is available
 * even with ExtendedStatus Off on Apache config file.
 *
 * @file
 */
int check_apache_status(Socket_T socket) {

  char host[STRLEN];
  const char *request= "/server-status?auto";

  ASSERT(socket);

  if(socket_print(socket, "GET %s HTTP/1.1\r\n"
                  "Host: %s\r\n"
                  "Accept: */*\r\n"
                  "User-Agent: %s/%s\r\n"
                  "Connection: close\r\n\r\n",
                  request, Util_getHTTPHostHeader(socket, host, STRLEN),
                  prog, VERSION) < 0) {
    socket_setError(socket, "HTTP: error sending data -- %s\n", STRERROR);
    return FALSE;
  }

  return check_apache_stat(socket);

}
示例#17
0
文件: http.c 项目: ezotrank/monit-src
static int do_regex(Socket_T socket, int content_length, Request_T R) {
        int n, size = 0, length = 0, rv = FALSE, regex_return;
        char *buf = NULL;

        if (content_length == 0) {
                socket_setError(socket, "HTTP error: No content returned from server\n");
                return FALSE;
        } else if (content_length < 0) { /* Not defined in response */
                content_length = HTTP_CONTENT_MAX;
        } else if (content_length > HTTP_CONTENT_MAX) {
                content_length = HTTP_CONTENT_MAX;
        }

        length = content_length;
        buf = ALLOC(content_length + 1);

        do {
                n = socket_read(socket, &buf[size], length);
                if (n <= 0)
                        break;
                size += n;
                length -= n;
        } while (length > 0);

        if (size == 0) {
                socket_setError(socket, "HTTP error: receiving data -- %s\n", STRERROR);
                goto error;
        }
        buf[size] = 0;

#ifdef HAVE_REGEX_H
        regex_return = regexec(R->regex, buf, 0, NULL, 0);
#else
        regex_return = strstr(buf, R->regex) ? 0 : 1;
#endif
        switch (R->operator) {
                case Operator_Equal:
                        if (regex_return == 0) {
                                rv = TRUE;
                                DEBUG("HTTP: Regular expression matches\n");
                        } else {
#ifdef HAVE_REGEX_H
                                char errbuf[STRLEN];
                                regerror(regex_return, NULL, errbuf, sizeof(errbuf));
                                socket_setError(socket, "HTTP error: Regular expression doesn't match: %s\n", errbuf);
#else
                                socket_setError(socket, "HTTP error: Regular expression doesn't match\n");
#endif
                        }
                        break;
                case Operator_NotEqual:
                        if (regex_return == 0) {
                                socket_setError(socket, "HTTP error: Regular expression matches\n");
                        } else {
                                rv = TRUE;
                                DEBUG("HTTP: Regular expression doesn't match\n");
                        }
                        break;
                default:
                        socket_setError(socket, "HTTP error: Invalid content operator\n");
        }

error:
        FREE(buf);
        return rv;
}
示例#18
0
/**
 *  PostgreSQL test.
 *
 *  @file
 */
int check_pgsql(Socket_T socket) {

  unsigned char buf[STRLEN];

  unsigned char requestLogin[33] = {
    0x00,                              /** Length */
    0x00,
    0x00,
    0x21,

    0x00,                              /** ProtoVer 3.0 */
    0x03,
    0x00,
    0x00,

    0x75, 0x73, 0x65, 0x72, 0x00,      /** user */
    0x72, 0x6f, 0x6f, 0x74, 0x00,      /** root */

    0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x00,  /** database */
    0x72, 0x6f, 0x6f, 0x74, 0x00,                          /** root */

    0x00
  };

  /** Doing this is too suspicious maybe.
   * Type Q, Length 19 and QUERY select 1 as a; */
  /**
  unsigned char requestQuery[20] = {
    0x51,

    0x00,
    0x00,
    0x00,
    0x13,

    0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20,
    0x31, 0x20, 0x61, 0x73, 0x20, 0x61, 0x3b,

    0x00
  };
  */

  unsigned char requestTerm[5] = {
    0x58,                              /** Type X */

    0x00,                              /** Length */
    0x00,
    0x00,
    0x04
  };

  unsigned char responseAuthOk[9] = {
    0x52,                              /** Type R */

    0x00,                              /** Length */
    0x00,
    0x00,
    0x08,

    0x00,                              /** OK code 0 */
    0x00,
    0x00,
    0x00
  };

  ASSERT(socket);

  if(socket_write(socket, (unsigned char *)requestLogin, sizeof(requestLogin)) <= 0) {
    socket_setError(socket, "PGSQL: error sending data -- %s", STRERROR);
    return FALSE;
  }

  /** Nine-byte is enough to hold Auth-Ok */
  if(socket_read(socket, buf, 9) <= 0) {
    socket_setError(socket, "PGSQL: error receiving data -- %s", STRERROR);
    return FALSE;
  }

  /** If server insists on auth error it is working anyway */
  if(*buf=='E') {
    return TRUE;
  }

  /** Successful connection */
  if(!memcmp((unsigned char *)buf, (unsigned char *)responseAuthOk, 9)) {
    /** This is where suspicious people can do SELECT query that I dont */
    socket_write(socket, (unsigned char *)requestTerm, sizeof(requestTerm));
    return TRUE;
  }

  /** The last possibility must be that server is demanding password */
  if(*buf=='R') {
    return TRUE;
  }

  socket_setError(socket, "PGSQL: unknown error");

  return FALSE;
}
示例#19
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);

}
示例#20
0
int check_ntp3(Socket_T socket) 
{
  int  br;
  char ntpRequest[NTPLEN];
  char ntpResponse[NTPLEN];

  ASSERT(socket);

  memset(ntpRequest, 0, NTPLEN);
  memset(ntpResponse, 0, NTPLEN);

  /*
    Prepare NTP request. The first octet consists of:
       bits 0-1 ... Leap Indicator
       bits 2-4 ... Version Number
       bits 5-7 ... Mode
   */
  ntpRequest[0]=
    (NTP_LEAP_NOTSYNC << 6)
    |
    (NTP_VERSION << 3)
    |
    (NTP_MODE_CLIENT);

  /* Send request to NTP server */
  if(socket_write(socket, ntpRequest, NTPLEN) <= 0 ) {
    socket_setError(socket, "NTP: error sending NTP request -- %s\n", STRERROR);
    return FALSE;
  }

  /* Receive and validate response */
  if( (br= socket_read(socket, ntpResponse, NTPLEN)) <= 0) {
    socket_setError(socket, "NTP: did not receive answer from server -- %s\n", STRERROR);
    return FALSE;
  }

  if( br != NTPLEN ) {
    socket_setError(socket, "NTP: Received %d bytes from server, expected %d bytes\n",
      br, NTPLEN);
    return FALSE;
  }

  /*
    Compare NTP response. The first octet consists of:
       bits 0-1 ... Leap Indicator
       bits 2-4 ... Version Number
       bits 5-7 ... Mode
   */
  if( (ntpResponse[0] & 0x07) != NTP_MODE_SERVER )
  {
    socket_setError(socket, "NTP: Server mode error\n");
    return FALSE;
  }
  if( (ntpResponse[0] & 0x38) != NTP_VERSION<<3 )
  {
    socket_setError(socket, "NTP: Server protocol version error\n");
    return FALSE;
  }
  if( (ntpResponse[0] & 0xc0) == NTP_LEAP_NOTSYNC<<6 )
  {
    socket_setError(socket, "NTP: Server not synchronized\n");
    return FALSE;
  }

  return TRUE;
}
示例#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.
 *
 *  @file
 */
int check_mysql(Socket_T socket) {

  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(socket);

  if(!socket_readln(socket, (char *)buf, sizeof(buf))) {
    socket_setError(socket, "MYSQL: error receiving greeting -- %s\n", STRERROR);
    return FALSE;
  }

  if(socket_write(socket, requestLogin, sizeof(requestLogin)) < 0) {
    socket_setError(socket, "MYSQL: error sending login -- %s\n", 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\n");
    return FALSE;
  }

  /* Compare Packet Number: */
  if(buf[3] != 0x02) {
    socket_setError(socket, "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(socket, (unsigned char *)requestPing, sizeof(requestPing)) < 0) {
      socket_setError(socket, "MYSQL: error sending ping -- %s\n", STRERROR);
      return FALSE;
    }

    if(socket_read(socket, buf, sizeof(responsePing)) <= 0) {
      socket_setError(socket, "MYSQL: error receiving ping response -- %s\n", STRERROR);
      return FALSE;
    }

    if(memcmp((unsigned char *)buf,
  	      (unsigned char *)responsePing, sizeof(responsePing))) {
      socket_setError(socket, "MYSQL: ping failed\n");
      return FALSE;
    }

    if(socket_write(socket, (unsigned char *)requestQuit, sizeof(requestQuit)) < 0) {
      socket_setError(socket, "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) || (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)\n", buf[6] * 256 + buf[5]);

  return FALSE;
}
示例#22
0
static int parse_scoreboard(Socket_T socket, char *scoreboard) {
        int logging = 0, close = 0, dns = 0, keepalive = 0, reply = 0, request = 0, start = 0, wait = 0, graceful = 0, cleanup = 0, open = 0;
        for (char *state = scoreboard; *state; state++) {
                switch (*state) {
                        case 'S':
                                start++;
                                break;
                        case 'R':
                                request++;
                                break;
                        case 'W':
                                reply++;
                                break;
                        case 'K':
                                keepalive++;
                                break;
                        case 'D':
                                dns++;
                                break;
                        case 'C':
                                close++;
                                break;
                        case 'L':
                                logging++;
                                break;
                        case 'G':
                                graceful++;
                                break;
                        case 'I':
                                cleanup++;
                                break;
                        case '_':
                                wait++;
                                break;
                        case '.':
                                open++;
                                break;
                }
        }

        int total = logging + close + dns + keepalive + reply + request + start + wait + graceful + cleanup + open;
        if (! total)
                return TRUE; // Idle server

        int errors = 0;
        Port_T p = socket_get_Port(socket);
        ASSERT(p);

        //FIXME: socket_setError overrides previous => either stop on first error, or append errors and set error at the end (convert error buffer to stringbuffer?)
        if (p->ApacheStatus.loglimit > 0 && Util_evalQExpression(p->ApacheStatus.loglimitOP, (100 * logging / total), p->ApacheStatus.loglimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are logging", 100 * logging / total);
                errors++;
        }
        if (p->ApacheStatus.startlimit > 0 && Util_evalQExpression(p->ApacheStatus.startlimitOP, (100 * start / total), p->ApacheStatus.startlimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are starting", 100 * start / total);
                errors++;
        }
        if (p->ApacheStatus.requestlimit > 0 && Util_evalQExpression(p->ApacheStatus.requestlimitOP, (100 * request / total), p->ApacheStatus.requestlimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are reading requests", 100 * request / total);
                errors++;
        }
        if (p->ApacheStatus.replylimit > 0 && Util_evalQExpression(p->ApacheStatus.replylimitOP, (100 * reply / total), p->ApacheStatus.replylimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are sending a reply", 100 * reply / total);
                errors++;
        }
        if (p->ApacheStatus.keepalivelimit > 0 && Util_evalQExpression(p->ApacheStatus.keepalivelimitOP, (100 * keepalive / total), p->ApacheStatus.keepalivelimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are in keepalive", 100 * keepalive / total);
                errors++;
        }
        if (p->ApacheStatus.dnslimit > 0 && Util_evalQExpression(p->ApacheStatus.dnslimitOP, (100 * dns / total), p->ApacheStatus.dnslimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are waiting for DNS", 100 * dns / total);
                errors++;
        }
        if (p->ApacheStatus.closelimit > 0 && Util_evalQExpression(p->ApacheStatus.closelimitOP, (100 * close / total), p->ApacheStatus.closelimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are closing connections", 100 * close / total);
                errors++;
        }
        if (p->ApacheStatus.gracefullimit > 0 && Util_evalQExpression(p->ApacheStatus.gracefullimitOP, (100 * graceful / total), p->ApacheStatus.gracefullimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are finishing gracefully", 100 * graceful / total);
                errors++;
        }
        if (p->ApacheStatus.cleanuplimit > 0 && Util_evalQExpression(p->ApacheStatus.cleanuplimitOP, (100 * cleanup / total), p->ApacheStatus.cleanuplimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are in idle cleanup", 100 * cleanup / total);
                errors++;
        }
        if (p->ApacheStatus.waitlimit > 0 && Util_evalQExpression(p->ApacheStatus.waitlimitOP, (100 * wait / total), p->ApacheStatus.waitlimit)) {
                socket_setError(socket, "APACHE-STATUS: error -- %d percent of processes are waiting for a connection", 100 * wait / total);
                errors++;
        }

        return (errors == 0);
}
示例#23
0
/**
 *  Simple RADIUS test.
 *
 *  We send a Status-Server packet, and expect an Access-Accept or Accounting-Response packet.
 *
 *
 */
int check_radius(Socket_T socket) {
        int i, length, left;
        int secret_len;
        Port_T P;
        md5_context_t ctx;
        char *secret;
        unsigned char *attr;
        unsigned char  digest[16];
        unsigned char  response[STRLEN];
        unsigned char  request[38] = {
                /* Status-Server */
                0x0c,

                /* Code, we always use zero */
                0x00,

                /* Packet length */
                0x00,
                0x26,

                /* Request Authenticator */
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,

                /* Message-Authenticator */
                0x50,

                /* Length */
                0x12,

                /* Contents of Message-Authenticator */
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00,
                0x00
        };

        ASSERT(socket);

        if (socket_get_type(socket) != SOCK_DGRAM) {
                socket_setError(socket, "RADIUS: unsupported socket type -- protocol test skipped\n");
                return TRUE;
        }

        P = socket_get_Port(socket);
        ASSERT(P);
  
        secret = P->request ? P->request : "testing123";
        secret_len = (int)strlen(secret);

        /* get 16 bytes of random data */
        for (i = 0; i < 16; i++)
                request[i + 4] = ((unsigned int)random()) & 0xff;

        /* sign the packet */
        Util_hmacMD5(request, sizeof(request), (unsigned char *)secret, secret_len, request + 22);

        if (socket_write(socket, (unsigned char *)request, sizeof(request)) < 0) {
                socket_setError(socket, "RADIUS: error sending query -- %s\n", STRERROR);
                return FALSE;
        }

        /* the response should have at least 20 bytes */
        if ((length = socket_read(socket, (unsigned char *)response, sizeof(response))) < 20) {
                socket_setError(socket, "RADIUS: error receiving response -- %s\n", STRERROR);
                return FALSE;
        }

        /* compare the response code (should be Access-Accept or Accounting-Response) */
        if ((response[0] != 2) && (response[0] != 5)) {
                socket_setError(socket, "RADIUS: Invalid reply code -- error occured\n");
                return FALSE;
        }

        /* compare the packet ID (it should be the same as in our request) */
        if (response[1] != 0x00) {
                socket_setError(socket, "RADIUS: ID mismatch\n");
                return FALSE;
        }

        /* check the length */
        if (response[2] != 0) {
                socket_setError(socket, "RADIUS: message is too long\n");
                return FALSE;
        }

        /* check length against packet data */
        if (response[3] != length) {
                socket_setError(socket, "RADIUS: message has invalid length\n");
                return FALSE;
        }

        /* validate that it is a well-formed packet */
        attr = response + 20;
        left = length - 20;
        while (left > 0) {
                if (left < 2) {
                        socket_setError(socket, "RADIUS: message is malformed\n");
                        return FALSE;
                }

                if (attr[1] < 2) {
                        socket_setError(socket, "RADIUS: message has invalid attribute length\n");
                        return FALSE;
                }

                if (attr[1] > left) {
                        socket_setError(socket, "RADIUS: message has attribute that is too long\n");
                        return FALSE;
                }

                /* validate Message-Authenticator, if found */
                if (attr[0] == 0x50) {
                        /* FIXME: validate it */
                }
                left -= attr[1];
        }

        /* save the reply authenticator, and copy the request authenticator over */
        memcpy(digest, response + 4, 16);
        memcpy(response + 4, request + 4, 16);

        md5_init(&ctx);
        md5_append(&ctx, (const md5_byte_t *)response, length);
        md5_append(&ctx, (const md5_byte_t *)secret, secret_len);
        md5_finish(&ctx, response + 4);

        if (memcmp(digest, response + 4, 16) != 0)
                socket_setError(socket, "RADIUS: message fails authentication\n");

        return TRUE;
}
示例#24
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;
}
示例#25
0
文件: dns.c 项目: AsydSolutions/monit
/**
 *  Simple DNS test.
 *
 *  The nameserver is queried for NS record of DNS root.
 *
 *  @file
 */
int check_dns(Socket_T socket) {
  int            offset_request  = 0;
  int            offset_response = 0;
  int            rc;
  unsigned char  buf[STRLEN];
  unsigned char *response = NULL;
  unsigned char  request[19] = {
    0x00,          /** Request Length field for DNS via TCP */
    0x11,

    0x00,                                /** Transaction ID */
    0x01,

    0x01,                                         /** Flags */
    0x00,

    0x00,                                 /** Queries count */
    0x01,

    0x00,                 /** Answer resource records count */
    0x00,

    0x00,              /** Authority resource records count */
    0x00,

    0x00,             /** Additional resource records count */
    0x00,

                                                 /** Query: */

    0x00,                 /** Name: DNS root (empty string) */

    0x00,                                      /** Type: NS */
    0x02,

    0x00,                                     /** Class: IN */
    0x01
  };

  ASSERT(socket);

  switch (socket_get_type(socket)) {
    case SOCK_DGRAM:
      offset_request  = 2; /*  Skip Length field in request */
      offset_response = 0;
      break;
    case SOCK_STREAM:
      offset_request  = 0;
      offset_response = 2; /*  Skip Length field in response */
      break;
    default:
      socket_setError(socket, "DNS: unsupported socket type -- protocol test skipped");
      return TRUE;
  }

  if (socket_write(socket, (unsigned char *)request + offset_request, sizeof(request) - offset_request) < 0) {
    socket_setError(socket, "DNS: error sending query -- %s", STRERROR);
    return FALSE;
  }

  /* Response should have at least 14 bytes */
  if (socket_read(socket, (unsigned char *)buf, 15) <= 14) {
    socket_setError(socket, "DNS: error receiving response -- %s", STRERROR);
    return FALSE;
  }

  response = buf + offset_response;

  /* Compare transaction ID (it should be the same as in our request): */
  if (response[0] != 0x00 && response[1] != 0x01) {
    socket_setError(socket, "DNS: response transaction ID mismatch -- received 0x%x%x, expected 0x1", response[0], response[1]);
    return FALSE;
  }

  /* Compare flags: */

  /* Response type */
  if ((response[2] & 0x80) != 0x80) {
    socket_setError(socket, "DNS: invalid response type: 0x%x", response[2] & 0x80);
    return FALSE;
  }

  /* Response code: accept request refusal as correct response as the server may disallow NS root query but the negative response means, it reacts to requests */
  rc = response[3] & 0x0F;
  if (rc != 0x0 && rc != 0x5) {
    socket_setError(socket, "DNS: invalid response code: 0x%x", rc);
    return FALSE;
  }

  /* Compare queries count (it should be one as in our request): */
  if (response[4] != 0x00 && response[5] != 0x01) {
    socket_setError(socket, "DNS: invalid query count in response -- received 0x%x%x, expected 1", response[4], response[5]);
    return FALSE;
  }

  /* Compare answer and authority resource record counts (they shouldn't be both zero) */
  if (rc == 0 && response[6] == 0x00 && response[7] == 0x00 && response[8] == 0x00 && response[9] == 0x00) {
    socket_setError(socket, "DNS: no answer or authority records returned");
    return FALSE;
  }

  return TRUE;
}
示例#26
0
/**
 *  Generic service test.
 *
 *  @file
 */
int check_generic(Socket_T socket) {
  Generic_T g = NULL;
  char *buf;
#ifdef HAVE_REGEX_H
  int regex_return;
#endif

  ASSERT(socket);

  if(socket_get_Port(socket))
    g = ((Port_T)(socket_get_Port(socket)))->generic;

  buf = CALLOC(sizeof(char), Run.expectbuffer + 1);

  while (g != NULL) {

    if (g->send != NULL) {

      /* Unescape any \0x00 escaped chars in g's send string
      to allow sending a string containing \0 bytes also */
      char *X = Str_dup(g->send);
      int l = Util_handle0Escapes(X);

      if(socket_write(socket, X, l) < 0) {
        socket_setError(socket, "GENERIC: error sending data -- %s", STRERROR);
        FREE(X);
        FREE(buf);
        return FALSE;
      } else
        DEBUG("GENERIC: successfully sent: '%s'\n", g->send);

      FREE(X);

    } else if (g->expect != NULL) {
      int n;
      /* Need read, not readln here */
      if((n = socket_read(socket, buf, Run.expectbuffer)) < 0) {
        socket_setError(socket, "GENERIC: error receiving data -- %s", STRERROR);
        FREE(buf);
        return FALSE;
      }
      buf[n] = 0;
      if (n > 0)
              _escapeZeroInExpectBuffer(buf, n);
#ifdef HAVE_REGEX_H
      regex_return = regexec(g->expect, buf, 0, NULL, 0);
      if (regex_return != 0) {
        char e[STRLEN];
        regerror(regex_return, g->expect, e, STRLEN);
        socket_setError(socket, "GENERIC: receiving unexpected data [%s] -- %s", Str_trunc(buf, STRLEN - 4), e);
        FREE(buf);
        return FALSE;
      } else
        DEBUG("GENERIC: successfully received: '%s'\n", Str_trunc(buf, STRLEN - 4));

#else
      /* w/o regex support */

      if (strncmp(buf, g->expect, strlen(g->expect)) != 0) {
        socket_setError(socket, "GENERIC: receiving unexpected data [%s]", Str_trunc(buf, STRLEN - 4));
        FREE(buf);
        return FALSE;
      } else
        DEBUG("GENERIC: successfully received: '%s'\n", Str_trunc(buf, STRLEN - 4));

#endif

    } else {
      /* This should not happen */
      socket_setError(socket, "GENERIC: unexpected strangeness");
      FREE(buf);
      return FALSE;
    }
    g = g->next;
  }

  FREE(buf);
  return TRUE;

}
示例#27
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;

}