summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_curl.c78
1 files changed, 39 insertions, 39 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 0f065731..82324d36 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -452,7 +452,7 @@ check_http (void)
452 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CAINFO, ca_cert), "CURLOPT_CAINFO"); 452 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CAINFO, ca_cert), "CURLOPT_CAINFO");
453 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1), "CURLOPT_SSL_VERIFYPEER"); 453 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1), "CURLOPT_SSL_VERIFYPEER");
454 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2), "CURLOPT_SSL_VERIFYHOST"); 454 handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2), "CURLOPT_SSL_VERIFYHOST");
455 } else { 455 } else {
456 /* backward-compatible behaviour, be tolerant in checks 456 /* backward-compatible behaviour, be tolerant in checks
457 * TODO: depending on more options have aspects we want 457 * TODO: depending on more options have aspects we want
458 * to be less tolerant about ssl verfications 458 * to be less tolerant about ssl verfications
@@ -460,7 +460,7 @@ check_http (void)
460 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0), "CURLOPT_SSL_VERIFYPEER"); 460 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0), "CURLOPT_SSL_VERIFYPEER");
461 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0), "CURLOPT_SSL_VERIFYHOST"); 461 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0), "CURLOPT_SSL_VERIFYHOST");
462 } 462 }
463 463
464 /* detect SSL library used by libcurl */ 464 /* detect SSL library used by libcurl */
465 ssl_library = curlhelp_get_ssl_library (curl); 465 ssl_library = curlhelp_get_ssl_library (curl);
466 466
@@ -481,7 +481,7 @@ check_http (void)
481#endif /* USE_OPENSSL */ 481#endif /* USE_OPENSSL */
482 /* libcurl is built with OpenSSL, monitoring plugins, so falling 482 /* libcurl is built with OpenSSL, monitoring plugins, so falling
483 * back to manually extracting certificate information */ 483 * back to manually extracting certificate information */
484 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); 484 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO");
485 break; 485 break;
486 486
487 case CURLHELP_SSL_LIBRARY_NSS: 487 case CURLHELP_SSL_LIBRARY_NSS:
@@ -492,7 +492,7 @@ check_http (void)
492 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", curlhelp_get_ssl_library_string (ssl_library)); 492 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", curlhelp_get_ssl_library_string (ssl_library));
493#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ 493#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */
494 break; 494 break;
495 495
496 case CURLHELP_SSL_LIBRARY_GNUTLS: 496 case CURLHELP_SSL_LIBRARY_GNUTLS:
497#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) 497#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0)
498 /* GnuTLS: support for CERTINFO is implemented since 7.42.0 */ 498 /* GnuTLS: support for CERTINFO is implemented since 7.42.0 */
@@ -501,7 +501,7 @@ check_http (void)
501 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", curlhelp_get_ssl_library_string (ssl_library)); 501 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", curlhelp_get_ssl_library_string (ssl_library));
502#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */ 502#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */
503 break; 503 break;
504 504
505 case CURLHELP_SSL_LIBRARY_UNKNOWN: 505 case CURLHELP_SSL_LIBRARY_UNKNOWN:
506 default: 506 default:
507 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (unknown SSL library '%s', must implement first)\n", curlhelp_get_ssl_library_string (ssl_library)); 507 die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (unknown SSL library '%s', must implement first)\n", curlhelp_get_ssl_library_string (ssl_library));
@@ -543,12 +543,12 @@ check_http (void)
543 if (onredirect == STATE_DEPENDENT) { 543 if (onredirect == STATE_DEPENDENT) {
544 if( followmethod == FOLLOW_LIBCURL ) { 544 if( followmethod == FOLLOW_LIBCURL ) {
545 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1), "CURLOPT_FOLLOWLOCATION"); 545 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1), "CURLOPT_FOLLOWLOCATION");
546 546
547 /* default -1 is infinite, not good, could lead to zombie plugins! 547 /* default -1 is infinite, not good, could lead to zombie plugins!
548 Setting it to one bigger than maximal limit to handle errors nicely below 548 Setting it to one bigger than maximal limit to handle errors nicely below
549 */ 549 */
550 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS"); 550 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_MAXREDIRS, max_depth+1), "CURLOPT_MAXREDIRS");
551 551
552 /* for now allow only http and https (we are a http(s) check plugin in the end) */ 552 /* for now allow only http and https (we are a http(s) check plugin in the end) */
553#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) 553#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4)
554 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS"); 554 handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), "CURLOPT_REDIRECT_PROTOCOLS");
@@ -640,7 +640,7 @@ check_http (void)
640 cert_ptr.to_info = NULL; 640 cert_ptr.to_info = NULL;
641 res = curl_easy_getinfo (curl, CURLINFO_CERTINFO, &cert_ptr.to_info); 641 res = curl_easy_getinfo (curl, CURLINFO_CERTINFO, &cert_ptr.to_info);
642 if (!res && cert_ptr.to_info) { 642 if (!res && cert_ptr.to_info) {
643#ifdef USE_OPENSSL 643#ifdef USE_OPENSSL
644 /* We have no OpenSSL in libcurl, but we can use OpenSSL for X509 cert parsing 644 /* We have no OpenSSL in libcurl, but we can use OpenSSL for X509 cert parsing
645 * We only check the first certificate and assume it's the one of the server 645 * We only check the first certificate and assume it's the one of the server
646 */ 646 */
@@ -669,7 +669,7 @@ GOT_FIRST_CERT:
669 } 669 }
670 BIO_free (cert_BIO); 670 BIO_free (cert_BIO);
671 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); 671 result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
672 return result; 672 return result;
673#else /* USE_OPENSSL */ 673#else /* USE_OPENSSL */
674 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, 674 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal,
675 * so we use the libcurl CURLINFO data 675 * so we use the libcurl CURLINFO data
@@ -859,12 +859,12 @@ GOT_FIRST_CERT:
859 /* make sure the page is of an appropriate size 859 /* make sure the page is of an appropriate size
860 * TODO: as far I can tell check_http gets the full size of header and 860 * TODO: as far I can tell check_http gets the full size of header and
861 * if -N is not given header+body. Does this make sense? 861 * if -N is not given header+body. Does this make sense?
862 * 862 *
863 * TODO: check_http.c had a get_length function, the question is really 863 * TODO: check_http.c had a get_length function, the question is really
864 * here what to use? the raw data size of the header_buf, the value of 864 * here what to use? the raw data size of the header_buf, the value of
865 * Content-Length, both and warn if they differ? Should the length be 865 * Content-Length, both and warn if they differ? Should the length be
866 * header+body or only body? 866 * header+body or only body?
867 * 867 *
868 * One possible policy: 868 * One possible policy:
869 * - use header_buf.buflen (warning, if it mismatches to the Content-Length value 869 * - use header_buf.buflen (warning, if it mismatches to the Content-Length value
870 * - if -N (nobody) is given, use Content-Length only and hope the server set 870 * - if -N (nobody) is given, use Content-Length only and hope the server set
@@ -903,7 +903,7 @@ GOT_FIRST_CERT:
903 curl_global_cleanup (); 903 curl_global_cleanup ();
904 curlhelp_freewritebuffer (&body_buf); 904 curlhelp_freewritebuffer (&body_buf);
905 curlhelp_freewritebuffer (&header_buf); 905 curlhelp_freewritebuffer (&header_buf);
906 if (!strcmp (http_method, "PUT")) { 906 if (!strcmp (http_method, "PUT")) {
907 curlhelp_freereadbuffer (&put_buf); 907 curlhelp_freereadbuffer (&put_buf);
908 } 908 }
909 909
@@ -941,11 +941,11 @@ redir (curlhelp_write_curlbuf* header_buf)
941 int new_port; 941 int new_port;
942 char *new_host; 942 char *new_host;
943 char *new_url; 943 char *new_url;
944 944
945 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 945 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
946 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 946 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
947 headers, &nof_headers, 0); 947 headers, &nof_headers, 0);
948 948
949 location = get_header_value (headers, nof_headers, "location"); 949 location = get_header_value (headers, nof_headers, "location");
950 950
951 if (verbose >= 2) 951 if (verbose >= 2)
@@ -955,7 +955,7 @@ redir (curlhelp_write_curlbuf* header_buf)
955 die (STATE_WARNING, 955 die (STATE_WARNING,
956 _("HTTP WARNING - maximum redirection depth %d exceeded - %s%s\n"), 956 _("HTTP WARNING - maximum redirection depth %d exceeded - %s%s\n"),
957 max_depth, location, (display_html ? "</A>" : "")); 957 max_depth, location, (display_html ? "</A>" : ""));
958 958
959 UriParserStateA state; 959 UriParserStateA state;
960 UriUriA uri; 960 UriUriA uri;
961 state.uri = &uri; 961 state.uri = &uri;
@@ -968,7 +968,7 @@ redir (curlhelp_write_curlbuf* header_buf)
968 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); 968 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n"));
969 } 969 }
970 } 970 }
971 971
972 if (verbose >= 2) { 972 if (verbose >= 2) {
973 printf (_("** scheme: %s\n"), 973 printf (_("** scheme: %s\n"),
974 uri_string (uri.scheme, buf, DEFAULT_BUFFER_SIZE)); 974 uri_string (uri.scheme, buf, DEFAULT_BUFFER_SIZE));
@@ -1003,7 +1003,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1003 } 1003 }
1004 1004
1005 use_ssl = !uri_strcmp (uri.scheme, "https"); 1005 use_ssl = !uri_strcmp (uri.scheme, "https");
1006 1006
1007 /* we do a sloppy test here only, because uriparser would have failed 1007 /* we do a sloppy test here only, because uriparser would have failed
1008 * above, if the port would be invalid, we just check for MAX_PORT 1008 * above, if the port would be invalid, we just check for MAX_PORT
1009 */ 1009 */
@@ -1018,7 +1018,7 @@ redir (curlhelp_write_curlbuf* header_buf)
1018 die (STATE_UNKNOWN, 1018 die (STATE_UNKNOWN,
1019 _("HTTP UNKNOWN - Redirection to port above %d - %s%s\n"), 1019 _("HTTP UNKNOWN - Redirection to port above %d - %s%s\n"),
1020 MAX_PORT, location, display_html ? "</A>" : ""); 1020 MAX_PORT, location, display_html ? "</A>" : "");
1021 1021
1022 /* by RFC 7231 relative URLs in Location should be taken relative to 1022 /* by RFC 7231 relative URLs in Location should be taken relative to
1023 * the original URL, so wy try to form a new absolute URL here 1023 * the original URL, so wy try to form a new absolute URL here
1024 */ 1024 */
@@ -1070,11 +1070,11 @@ redir (curlhelp_write_curlbuf* header_buf)
1070 server_url = new_url; 1070 server_url = new_url;
1071 1071
1072 uriFreeUriMembersA (&uri); 1072 uriFreeUriMembersA (&uri);
1073 1073
1074 if (verbose) 1074 if (verbose)
1075 printf (_("Redirection to %s://%s:%d%s\n"), use_ssl ? "https" : "http", 1075 printf (_("Redirection to %s://%s:%d%s\n"), use_ssl ? "https" : "http",
1076 host_name ? host_name : server_address, server_port, server_url); 1076 host_name ? host_name : server_address, server_port, server_url);
1077 1077
1078 /* TODO: the hash component MUST be taken from the original URL and 1078 /* TODO: the hash component MUST be taken from the original URL and
1079 * attached to the URL in Location 1079 * attached to the URL in Location
1080 */ 1080 */
@@ -1320,7 +1320,7 @@ process_arguments (int argc, char **argv)
1320 got_plus = 1; 1320 got_plus = 1;
1321 *plus_ptr = '\0'; 1321 *plus_ptr = '\0';
1322 } 1322 }
1323 1323
1324 if (optarg[0] == '2') 1324 if (optarg[0] == '2')
1325 ssl_version = CURL_SSLVERSION_SSLv2; 1325 ssl_version = CURL_SSLVERSION_SSLv2;
1326 else if (optarg[0] == '3') 1326 else if (optarg[0] == '3')
@@ -1380,7 +1380,7 @@ process_arguments (int argc, char **argv)
1380 break; 1380 break;
1381 } 1381 }
1382 } 1382 }
1383#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ 1383#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */
1384 if (verbose >= 2) 1384 if (verbose >= 2)
1385 printf(_("* Set SSL/TLS version to %d\n"), ssl_version); 1385 printf(_("* Set SSL/TLS version to %d\n"), ssl_version);
1386 if (server_port == HTTP_PORT) 1386 if (server_port == HTTP_PORT)
@@ -1778,13 +1778,13 @@ int
1778curlhelp_buffer_read_callback (void *buffer, size_t size, size_t nmemb, void *stream) 1778curlhelp_buffer_read_callback (void *buffer, size_t size, size_t nmemb, void *stream)
1779{ 1779{
1780 curlhelp_read_curlbuf *buf = (curlhelp_read_curlbuf *)stream; 1780 curlhelp_read_curlbuf *buf = (curlhelp_read_curlbuf *)stream;
1781 1781
1782 size_t n = min (nmemb * size, buf->buflen - buf->pos); 1782 size_t n = min (nmemb * size, buf->buflen - buf->pos);
1783 1783
1784 memcpy (buffer, buf->buf + buf->pos, n); 1784 memcpy (buffer, buf->buf + buf->pos, n);
1785 buf->pos += n; 1785 buf->pos += n;
1786 1786
1787 return (int)n; 1787 return (int)n;
1788} 1788}
1789 1789
1790void 1790void
@@ -1953,7 +1953,7 @@ get_header_value (const struct phr_header* headers, const size_t nof_headers, co
1953 return NULL; 1953 return NULL;
1954} 1954}
1955 1955
1956int 1956int
1957check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFAULT_BUFFER_SIZE]) 1957check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFAULT_BUFFER_SIZE])
1958{ 1958{
1959 char *server_date = NULL; 1959 char *server_date = NULL;
@@ -1963,11 +1963,11 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA
1963 struct phr_header headers[255]; 1963 struct phr_header headers[255];
1964 size_t nof_headers = 255; 1964 size_t nof_headers = 255;
1965 size_t msglen; 1965 size_t msglen;
1966 1966
1967 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 1967 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
1968 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 1968 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
1969 headers, &nof_headers, 0); 1969 headers, &nof_headers, 0);
1970 1970
1971 server_date = get_header_value (headers, nof_headers, "date"); 1971 server_date = get_header_value (headers, nof_headers, "date");
1972 document_date = get_header_value (headers, nof_headers, "last-modified"); 1972 document_date = get_header_value (headers, nof_headers, "last-modified");
1973 1973
@@ -2002,7 +2002,7 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA
2002 } 2002 }
2003 } 2003 }
2004 } 2004 }
2005 2005
2006 if (server_date) free (server_date); 2006 if (server_date) free (server_date);
2007 if (document_date) free (document_date); 2007 if (document_date) free (document_date);
2008 2008
@@ -2025,7 +2025,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri
2025 int res = phr_parse_response (header_buf->buf, header_buf->buflen, 2025 int res = phr_parse_response (header_buf->buf, header_buf->buflen,
2026 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, 2026 &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
2027 headers, &nof_headers, 0); 2027 headers, &nof_headers, 0);
2028 2028
2029 content_length_s = get_header_value (headers, nof_headers, "content-length"); 2029 content_length_s = get_header_value (headers, nof_headers, "content-length");
2030 if (!content_length_s) { 2030 if (!content_length_s) {
2031 return header_buf->buflen + body_buf->buflen; 2031 return header_buf->buflen + body_buf->buflen;
@@ -2055,10 +2055,10 @@ curlhelp_get_ssl_library (CURL* curl)
2055 2055
2056 ssl_version = strdup (version_data->ssl_version); 2056 ssl_version = strdup (version_data->ssl_version);
2057 if (ssl_version == NULL ) return CURLHELP_SSL_LIBRARY_UNKNOWN; 2057 if (ssl_version == NULL ) return CURLHELP_SSL_LIBRARY_UNKNOWN;
2058 2058
2059 library = strtok (ssl_version, "/"); 2059 library = strtok (ssl_version, "/");
2060 if (library == NULL) return CURLHELP_SSL_LIBRARY_UNKNOWN; 2060 if (library == NULL) return CURLHELP_SSL_LIBRARY_UNKNOWN;
2061 2061
2062 if (strcmp (library, "OpenSSL") == 0) 2062 if (strcmp (library, "OpenSSL") == 0)
2063 ssl_library = CURLHELP_SSL_LIBRARY_OPENSSL; 2063 ssl_library = CURLHELP_SSL_LIBRARY_OPENSSL;
2064 else if (strcmp (library, "LibreSSL") == 0) 2064 else if (strcmp (library, "LibreSSL") == 0)
@@ -2070,9 +2070,9 @@ curlhelp_get_ssl_library (CURL* curl)
2070 2070
2071 if (verbose >= 2) 2071 if (verbose >= 2)
2072 printf ("* SSL library string is : %s %s (%d)\n", version_data->ssl_version, library, ssl_library); 2072 printf ("* SSL library string is : %s %s (%d)\n", version_data->ssl_version, library, ssl_library);
2073 2073
2074 free (ssl_version); 2074 free (ssl_version);
2075 2075
2076 return ssl_library; 2076 return ssl_library;
2077} 2077}
2078 2078
@@ -2101,12 +2101,12 @@ parse_cert_date (const char *s)
2101{ 2101{
2102 struct tm tm; 2102 struct tm tm;
2103 time_t date; 2103 time_t date;
2104 2104
2105 if (!s) return -1; 2105 if (!s) return -1;
2106 2106
2107 strptime (s, "%Y-%m-%d %H:%M:%S GMT", &tm); 2107 strptime (s, "%Y-%m-%d %H:%M:%S GMT", &tm);
2108 date = mktime (&tm); 2108 date = mktime (&tm);
2109 2109
2110 return date; 2110 return date;
2111} 2111}
2112 2112
@@ -2127,7 +2127,7 @@ net_noopenssl_check_certificate (cert_ptr_union* cert_ptr, int days_till_exp_war
2127 float time_left; 2127 float time_left;
2128 int days_left; 2128 int days_left;
2129 int time_remaining; 2129 int time_remaining;
2130 char timestamp[50] = ""; 2130 char timestamp[50] = "";
2131 int status = STATE_UNKNOWN; 2131 int status = STATE_UNKNOWN;
2132 2132
2133 if (verbose >= 2) 2133 if (verbose >= 2)
@@ -2160,7 +2160,7 @@ HAVE_FIRST_CERT:
2160 2160
2161 if (verbose >= 2) 2161 if (verbose >= 2)
2162 printf ("**** REQUEST CERTIFICATES ****\n"); 2162 printf ("**** REQUEST CERTIFICATES ****\n");
2163 2163
2164 if (!cname_found) { 2164 if (!cname_found) {
2165 printf("%s\n",_("CRITICAL - Cannot retrieve certificate subject.")); 2165 printf("%s\n",_("CRITICAL - Cannot retrieve certificate subject."));
2166 return STATE_CRITICAL; 2166 return STATE_CRITICAL;