911106dfb16696472af8c1b7b4c554a829354fa8jm * CDDL HEADER START
911106dfb16696472af8c1b7b4c554a829354fa8jm * The contents of this file are subject to the terms of the
911106dfb16696472af8c1b7b4c554a829354fa8jm * Common Development and Distribution License (the "License").
911106dfb16696472af8c1b7b4c554a829354fa8jm * You may not use this file except in compliance with the License.
911106dfb16696472af8c1b7b4c554a829354fa8jm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911106dfb16696472af8c1b7b4c554a829354fa8jm * See the License for the specific language governing permissions
911106dfb16696472af8c1b7b4c554a829354fa8jm * and limitations under the License.
911106dfb16696472af8c1b7b4c554a829354fa8jm * When distributing Covered Code, include this CDDL HEADER in each
911106dfb16696472af8c1b7b4c554a829354fa8jm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
911106dfb16696472af8c1b7b4c554a829354fa8jm * If applicable, add the following below this CDDL HEADER, with the
911106dfb16696472af8c1b7b4c554a829354fa8jm * fields enclosed by brackets "[]" replaced with your own identifying
911106dfb16696472af8c1b7b4c554a829354fa8jm * information: Portions Copyright [yyyy] [name of copyright owner]
911106dfb16696472af8c1b7b4c554a829354fa8jm * CDDL HEADER END
db1a607eb6d6da9154ca7153026a4fba0ee309eajoyce mcintosh * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Use is subject to license terms.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Description: Module contains supporting functions used by functions
911106dfb16696472af8c1b7b4c554a829354fa8jm * defined in vs_svc.c. It also contains some internal(static) functions.
911106dfb16696472af8c1b7b4c554a829354fa8jm/* prototypes of local functions */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic char *vs_icap_find_ext(char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_send_respmod_hdr(vs_scan_ctx_t *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_create_respmod_hdr(vs_scan_ctx_t *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_uri_encode(char *, int, char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_uri_illegal_char(char);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_read_hdr(vs_scan_ctx_t *, vs_hdr_t *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_readline(vs_scan_ctx_t *, char *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_write(int, char *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_read(int, char *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jm/* process options and respmod headers */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vs_icap_parse_hdrs(char, char *, char **, char **);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_opt_value(vs_scan_ctx_t *, int, char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_resp_violations(vs_scan_ctx_t *, int, char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_resp_violation_rec(vs_scan_ctx_t *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_resp_infection(vs_scan_ctx_t *, int, char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_resp_virus_id(vs_scan_ctx_t *, int, char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_resp_encap(vs_scan_ctx_t *, int, char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_resp_istag(vs_scan_ctx_t *, int, char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vs_icap_istag_to_scanstamp(char *, vs_scanstamp_t);
911106dfb16696472af8c1b7b4c554a829354fa8jm/* Utility functions for handling OPTIONS data: vs_options_t */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vs_icap_copy_options(vs_options_t *, vs_options_t *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vs_icap_compare_se(int, char *, int);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic iovec_t *vs_icap_make_strvec(char *, const char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void vs_icap_trimspace(char *);
911106dfb16696472af8c1b7b4c554a829354fa8jm/* icap response message */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic char *vs_icap_resp_str(int);
911106dfb16696472af8c1b7b4c554a829354fa8jm * local variables
911106dfb16696472af8c1b7b4c554a829354fa8jm/* option headers - and handler functions */
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_OPT_XFER_PREVIEW, "Transfer-Preview", vs_icap_opt_ext},
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_OPT_XFER_COMPLETE, "Transfer-Complete", vs_icap_opt_ext},
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_OPT_MAX_CONNECTIONS, "Max-Connections", vs_icap_opt_value},
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_OPT_X_DEF_INFO, "X-Definition-Info", vs_icap_opt_value}
911106dfb16696472af8c1b7b4c554a829354fa8jm/* resp hdrs - and handler functions */
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_RESP_ENCAPSULATED, "Encapsulated", vs_icap_resp_encap},
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_RESP_X_VIRUS_ID, "X-Virus-ID", vs_icap_resp_virus_id},
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_RESP_X_INFECTION, "X-Infection-Found", vs_icap_resp_infection},
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_RESP_X_VIOLATIONS, "X-Violations-Found", vs_icap_resp_violations}
911106dfb16696472af8c1b7b4c554a829354fa8jm/* ICAP response code to string mappings */
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_RESP_SERV_UNAVAIL, "Service unavailable/overloaded"},
911106dfb16696472af8c1b7b4c554a829354fa8jm { VS_RESP_ICAP_VER_UNSUPP, "ICAP version not supported"},
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic pthread_mutex_t vs_opt_mutex = PTHREAD_MUTEX_INITIALIZER;
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_init
911106dfb16696472af8c1b7b4c554a829354fa8jm * initialization performed when daemon is loaded
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_fini
911106dfb16696472af8c1b7b4c554a829354fa8jm * cleanup performed when daemon is unloaded
911106dfb16696472af8c1b7b4c554a829354fa8jm for (i = 0; i < VS_SE_MAX; i++)
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_config
53c110294d8b1410cabc201a52f94b03ae2ef448jm * When a new VSCAN configuration is specified, this will be
911106dfb16696472af8c1b7b4c554a829354fa8jm * called per scan engine. If the scan engine host or port has
911106dfb16696472af8c1b7b4c554a829354fa8jm * changed delete the vs_options entry for that scan engine.
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_scan_file
911106dfb16696472af8c1b7b4c554a829354fa8jm * Create a context (vs_scan_ctx_t) for the scan operation and initialize
911106dfb16696472af8c1b7b4c554a829354fa8jm * its options info. If the scan engine connection's IP or port is different
911106dfb16696472af8c1b7b4c554a829354fa8jm * from that held in vs_options the vs_options info is old and should
911106dfb16696472af8c1b7b4c554a829354fa8jm * be deleted (vs_icap_free_options). Otherwise, copy the vs_options info
911106dfb16696472af8c1b7b4c554a829354fa8jm * into the context.
911106dfb16696472af8c1b7b4c554a829354fa8jm * file name, size and decsriptor are also copied into the context
911106dfb16696472af8c1b7b4c554a829354fa8jm * Handle the ICAP protocol communication with the external Scan Engine to
911106dfb16696472af8c1b7b4c554a829354fa8jm * perform the scan
911106dfb16696472af8c1b7b4c554a829354fa8jm * - send an OPTIONS request if necessary
911106dfb16696472af8c1b7b4c554a829354fa8jm * - send RESPMOD scan request
911106dfb16696472af8c1b7b4c554a829354fa8jm * - process the response and save any cleaned data to file
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: result->vsr_rc
bfc848c632c9eacb2a640246d96e198f1b185c03jmvs_icap_scan_file(vs_eng_ctx_t *eng, char *devname, char *fname,
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* retry once on ENOENT as /dev link may not be created yet */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* initialize context */
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) strlcpy(ctx.vsc_host, eng->vse_host, sizeof (ctx.vsc_host));
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Hooks for future saving of repaired data, not yet in use */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* take a copy of vs_options[idx] if they match the SE specified */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_icap_compare_se(ctx.vsc_idx, ctx.vsc_host, ctx.vsc_port) == 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm * default the result to scan engine error.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Any non scan-engine errors will reset it to VS_RESULT_ERROR
911106dfb16696472af8c1b7b4c554a829354fa8jm /* do the scan */
911106dfb16696472af8c1b7b4c554a829354fa8jm/* ********************************************************************* */
911106dfb16696472af8c1b7b4c554a829354fa8jm/* Local Function definitions */
911106dfb16696472af8c1b7b4c554a829354fa8jm/* ********************************************************************* */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_option_request
911106dfb16696472af8c1b7b4c554a829354fa8jm * Send ICAP options message and await/process the response.
911106dfb16696472af8c1b7b4c554a829354fa8jm * The ICAP options request needs to be sent when a connection
911106dfb16696472af8c1b7b4c554a829354fa8jm * is first made with the scan engine. Unless the scan engine
911106dfb16696472af8c1b7b4c554a829354fa8jm * determines that the options will never expire (which we save
911106dfb16696472af8c1b7b4c554a829354fa8jm * as optione_req_time == -1) the request should be resent after
911106dfb16696472af8c1b7b4c554a829354fa8jm * the expiry time specified by the icap server.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_send_option_req
911106dfb16696472af8c1b7b4c554a829354fa8jm * Send an OPTIONS request to the scan engine
911106dfb16696472af8c1b7b4c554a829354fa8jm * The Symantec ICAP server REQUIRES the resource name (VS_SERVICE_NAME)
911106dfb16696472af8c1b7b4c554a829354fa8jm * after the IP address, otherwise it closes the connection.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm if (gethostname(my_host_name, sizeof (my_host_name)) != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm /* non SE error */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = snprintf(bufp, bufsp, "OPTIONS icap://%s:%d/%s %s\r\n",
911106dfb16696472af8c1b7b4c554a829354fa8jm ctx->vsc_host, ctx->vsc_port, VS_SERVICE_NAME, VS_ICAP_VER);
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = snprintf(bufp, bufsp, "Host: %s\r\n\r\n", my_host_name);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_icap_write(ctx->vsc_sockfd, buf0, (bufp - buf0)) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_option_resp
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm "- unexpected option response: %s",
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_icap_read_hdr(ctx, option_hdrs, VS_OPT_HDR_MAX) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm "- missing or invalid option response hdrs");
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_respmod_request
911106dfb16696472af8c1b7b4c554a829354fa8jm * Send respmod request and receive and process ICAP response.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Preview:
911106dfb16696472af8c1b7b4c554a829354fa8jm * ICAP allows for an optional "preview" request. In the option negotiation,
911106dfb16696472af8c1b7b4c554a829354fa8jm * the server may ask for a list of types to be previewed, or to be sent
911106dfb16696472af8c1b7b4c554a829354fa8jm * complete (no preview).
911106dfb16696472af8c1b7b4c554a829354fa8jm * This is advisory. It is ok to skip the preview step, as done when the file
911106dfb16696472af8c1b7b4c554a829354fa8jm * is smaller than the preview_len.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Process Response:
911106dfb16696472af8c1b7b4c554a829354fa8jm * - read and parse the RESPMOD response headers
911106dfb16696472af8c1b7b4c554a829354fa8jm * - populate the result structure
911106dfb16696472af8c1b7b4c554a829354fa8jm * - read any encapsulated response headers
911106dfb16696472af8c1b7b4c554a829354fa8jm * - read any encapsulated response body and, if it represents cleaned
911106dfb16696472af8c1b7b4c554a829354fa8jm * file data, overwrite the file with it
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* If > block (VS_BUF_SZ) remains, re-align to block boundary */
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((ctx->vsc_fsize - (uint64_t)bytes_sent) > VS_BUF_SZ) {
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Send the remainder of the file... */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (rv == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* sending of ICAP request complete */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_may_preview
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 1 - preview
911106dfb16696472af8c1b7b4c554a829354fa8jm * 0 - don't preview
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* if the file is smaller than the preview size, don't preview */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (ctx->vsc_fsize < (uint64_t)ctx->vsc_options.vso_preview_len)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Preview everything except types in xfer_complete */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Preview only types in the the xfer_preview list */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_find_ext
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: ptr to file's extension in fname
911106dfb16696472af8c1b7b4c554a829354fa8jm * 0 if no extension
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic char *
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Get file extension */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_send_preview
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: bytes sent (preview + alignment)
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Send a RESPMOD request with "preview" mode. */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((bytes_sent = vs_icap_send_chunk(ctx, preview_len)) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_send_respmod_hdr
911106dfb16696472af8c1b7b4c554a829354fa8jm * Create and send the RESPMOD request headers to the scan engine.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 success
911106dfb16696472af8c1b7b4c554a829354fa8jm * < 0 error
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_send_respmod_hdr(vs_scan_ctx_t *ctx, int ispreview)
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((len = vs_icap_create_respmod_hdr(ctx, ispreview)) == -1) {
911106dfb16696472af8c1b7b4c554a829354fa8jm /* non SE error */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* send the headers */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_create_respmod_hdr
911106dfb16696472af8c1b7b4c554a829354fa8jm * Create the RESPMOD request headers.
911106dfb16696472af8c1b7b4c554a829354fa8jm * - RESPMOD, Host, Allow, [Preview], Encapsulated, encapsulated request hdr,
911106dfb16696472af8c1b7b4c554a829354fa8jm * encapsulated response hdr
911106dfb16696472af8c1b7b4c554a829354fa8jm * Encapsulated data is sent separately subsequent to vs_icap_send_respmod_hdr,
911106dfb16696472af8c1b7b4c554a829354fa8jm * via calls to vs_icap_send_chunk.
911106dfb16696472af8c1b7b4c554a829354fa8jm * The Symantec ICAP server REQUIRES the resource name (VS_SERVICE_NAME)
911106dfb16696472af8c1b7b4c554a829354fa8jm * after the IP address, otherwise it closes the connection.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: -1 error
911106dfb16696472af8c1b7b4c554a829354fa8jm * length of headers data
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_create_respmod_hdr(vs_scan_ctx_t *ctx, int ispreview)
911106dfb16696472af8c1b7b4c554a829354fa8jm char *encap_hdr, *encap_off0, *req_hdr, *res_hdr, *res_body;
911106dfb16696472af8c1b7b4c554a829354fa8jm if (gethostname(my_host_name, sizeof (my_host_name)) != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm /* non SE error */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* First the ICAP "request" part. (at offset 0) */
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = snprintf(hbufp, hbufsp, "RESPMOD icap://%s:%d/%s %s\r\n",
911106dfb16696472af8c1b7b4c554a829354fa8jm ctx->vsc_host, ctx->vsc_port, VS_SERVICE_NAME, VS_ICAP_VER);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = snprintf(hbufp, hbufsp, "Host: %s\r\n", my_host_name);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = snprintf(hbufp, hbufsp, "Preview: %d\r\n", preview_len);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Reserve space to later insert encapsulation offsets, & blank line */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* "offset zero" for the encapsulated parts that follow */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Encapsulated request header (req_hdr) & blank line */
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = snprintf(hbufp, hbufsp, "GET http://%s", my_host_name);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = vs_icap_uri_encode(hbufp, hbufsp, ctx->vsc_fname);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Encapsulated response header (res_hdr) & blank line */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm tlen = snprintf(hbufp, hbufsp, "Transfer-Encoding: chunked\r\n\r\n");
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* response body section - res-body ("chunked data") */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Insert offsets in encap_hdr */
911106dfb16696472af8c1b7b4c554a829354fa8jm "req-hdr=%d, res-hdr=%d, res-body=%d",
911106dfb16696472af8c1b7b4c554a829354fa8jm req_hdr - encap_off0, res_hdr - encap_off0, res_body - encap_off0);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* undo the null from snprintf */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* return length */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_respmod_resp
911106dfb16696472af8c1b7b4c554a829354fa8jm * Used for both preview and final RESMOD response
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_icap_read_hdr(ctx, resp_hdrs, VS_RESP_HDR_MAX) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* A VS_RESP_CONTINUE should not have encapsulated data */
911106dfb16696472af8c1b7b4c554a829354fa8jm "- encapsulated data in Continue response");
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_resp_code
911106dfb16696472af8c1b7b4c554a829354fa8jm * Get the response code from the icap response messages
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Break on error or non-blank line. */
911106dfb16696472af8c1b7b4c554a829354fa8jm for (;;) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((retval = vs_icap_readline(ctx, buf, VS_BUF_SZ)) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_hdr
911106dfb16696472af8c1b7b4c554a829354fa8jm * Reads all response headers.
911106dfb16696472af8c1b7b4c554a829354fa8jm * As each line is read it is parsed and passed to the appropriate handler.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_read_hdr(vs_scan_ctx_t *ctx, vs_hdr_t hdrs[], int num_hdrs)
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Break on error or blank line. */
911106dfb16696472af8c1b7b4c554a829354fa8jm for (;;) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((retval = vs_icap_readline(ctx, buf, VS_BUF_SZ)) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Empty line (CR/LF) normal break */
911106dfb16696472af8c1b7b4c554a829354fa8jm for (i = 0; i < num_hdrs; i++) {
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_set_scan_result
911106dfb16696472af8c1b7b4c554a829354fa8jm * Sets the vs_result_t vsr_rc from the icap_resp_code and
911106dfb16696472af8c1b7b4c554a829354fa8jm * any violation information in vs_result_t
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm ctx->vsc_options.vso_scanstamp, sizeof (vs_scanstamp_t));
911106dfb16696472af8c1b7b4c554a829354fa8jm /* if we have no violations , that means all ok */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Any infections not repaired? */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* file is repaired */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* file is infected and could not be repaired */
911106dfb16696472af8c1b7b4c554a829354fa8jm "- unsupported scan result: %s",
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_encap_hdr
911106dfb16696472af8c1b7b4c554a829354fa8jm * Read the encapsulated response header to determine the length of
911106dfb16696472af8c1b7b4c554a829354fa8jm * encapsulated data and, in some cases, to detect the infected state
911106dfb16696472af8c1b7b4c554a829354fa8jm * of the file.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Use of http response code:
911106dfb16696472af8c1b7b4c554a829354fa8jm * Trend IWSS does not return virus information in the RESPMOD response
911106dfb16696472af8c1b7b4c554a829354fa8jm * headers unless the OPTIONAL "include X_Infection_Found" checkbox is
911106dfb16696472af8c1b7b4c554a829354fa8jm * checked and "disable_infected_url_block=yes" is set in intscan.ini.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Thus if we haven't already detected the infected/cleaned status
911106dfb16696472af8c1b7b4c554a829354fa8jm * (ie if vsr_rc == VS_RESULT_CLEAN) we attempt to detect the
911106dfb16696472af8c1b7b4c554a829354fa8jm * infected/cleaned state of a file from a combination of the ICAP and
911106dfb16696472af8c1b7b4c554a829354fa8jm * http resp codes.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Here are the response code values that Trend IWSS returns:
911106dfb16696472af8c1b7b4c554a829354fa8jm * - clean: icap resp = VS_RESP_NO_CONT_NEEDED
911106dfb16696472af8c1b7b4c554a829354fa8jm * - quarantine: icap resp = VS_RESP_OK, http resp = VS_RESP_FORBIDDEN
911106dfb16696472af8c1b7b4c554a829354fa8jm * - cleaned: icap resp = VS_RESP_OK, http resp = VS_RESP_OK
911106dfb16696472af8c1b7b4c554a829354fa8jm * For all other vendors' scan engines (so far) the infected/cleaned
911106dfb16696472af8c1b7b4c554a829354fa8jm * state of the file has already been detected from the RESPMOD
911106dfb16696472af8c1b7b4c554a829354fa8jm * response headers.
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Break on error or blank line. */
911106dfb16696472af8c1b7b4c554a829354fa8jm for (;;) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((retval = vs_icap_readline(ctx, buf, VS_BUF_SZ)) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Empty line (CR/LF) normal break */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* if not yet detected infection, interpret http_rc */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_encap_data
911106dfb16696472af8c1b7b4c554a829354fa8jm * Read the encapsulated response data.
911106dfb16696472af8c1b7b4c554a829354fa8jm * If the response data represents cleaned file data (for an infected file)
911106dfb16696472af8c1b7b4c554a829354fa8jm * and VS_NO_REPAIR is not set, open repair file to save the reponse body
911106dfb16696472af8c1b7b4c554a829354fa8jm * data in. Set the repair flag in the scan context. The repair flag is used
911106dfb16696472af8c1b7b4c554a829354fa8jm * during the processing of the response data. If the flag is set then the
911106dfb16696472af8c1b7b4c554a829354fa8jm * data is written to file. If any error occurs which invalidates the repaired
911106dfb16696472af8c1b7b4c554a829354fa8jm * data file the repair flag gets reset to 0, and the data will be discarded.
911106dfb16696472af8c1b7b4c554a829354fa8jm * The result is reset to VS_RESULT_FORBIDDEN until all of the cleaned data
911106dfb16696472af8c1b7b4c554a829354fa8jm * has been successfully received and processed. It is then reset to
911106dfb16696472af8c1b7b4c554a829354fa8jm * VS_RESULT_CLEANED.
911106dfb16696472af8c1b7b4c554a829354fa8jm * If the data doesn't represent cleaned file data, or we cannot (or don't
911106dfb16696472af8c1b7b4c554a829354fa8jm * want to) write the cleaned data to file, the data is discarded (repair flag
911106dfb16696472af8c1b7b4c554a829354fa8jm * in ctx == 0).
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_resp_body handles errors internally;
911106dfb16696472af8c1b7b4c554a829354fa8jm * resets ctx->vsc_repair
911106dfb16696472af8c1b7b4c554a829354fa8jm /* repair file contains the cleaned data */
911106dfb16696472af8c1b7b4c554a829354fa8jm /* error occured processing data. Remove repair file */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_create_repair_file
911106dfb16696472af8c1b7b4c554a829354fa8jm * Create and open a file to save cleaned data in.
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_resp_body
911106dfb16696472af8c1b7b4c554a829354fa8jm * Repeatedly call vs_icap_read_body_chunk until it returns:
911106dfb16696472af8c1b7b4c554a829354fa8jm * 0 indicating that there's no more data to read or
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 indicating a read error -> reset ctx->vsc_repair 0
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 error
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read_body_chunk
911106dfb16696472af8c1b7b4c554a829354fa8jm * Read the chunk size, then read the chunk of data and write the
911106dfb16696472af8c1b7b4c554a829354fa8jm * data to file repair_fd (or discard it).
911106dfb16696472af8c1b7b4c554a829354fa8jm * If the data cannot be successfully written to file, set repair
911106dfb16696472af8c1b7b4c554a829354fa8jm * flag in ctx to 0, and discard all subsequent data.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: chunk size
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 on error
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Read and parse the chunk size. */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Read and save/discard chunk */
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((rsize = vs_icap_read(ctx->vsc_sockfd, lbuf, rsize)) <= 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Eat one CR/LF after the data */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm syslog(LOG_ERR, "ICAP protocol error - expected blank line");
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm/* *********************************************************************** */
911106dfb16696472af8c1b7b4c554a829354fa8jm/* Utility read, write functions */
911106dfb16696472af8c1b7b4c554a829354fa8jm/* *********************************************************************** */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_write
911106dfb16696472af8c1b7b4c554a829354fa8jm * Return: 0 if all data successfully written
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 otherwise
911106dfb16696472af8c1b7b4c554a829354fa8jm while (resid > 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_read
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: bytes_read (== len unless EOF hit before len bytes read)
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 error
911106dfb16696472af8c1b7b4c554a829354fa8jm while (resid > 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_send_chunk
911106dfb16696472af8c1b7b4c554a829354fa8jm * Send a "chunk" of file data, containing:
911106dfb16696472af8c1b7b4c554a829354fa8jm * - Length (in hex) CR/NL
911106dfb16696472af8c1b7b4c554a829354fa8jm * - [optiona data]
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: data length sent (not including encapsulation)
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Read the data. */
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((nread = vs_icap_read(ctx->vsc_fd, dbuf, chunk_len)) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (nread > 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm /* wrap data in a header and trailer */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_send_termination
911106dfb16696472af8c1b7b4c554a829354fa8jm * Send 0 length termination to scan engine: "0\r\n\r\n"
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_readline
911106dfb16696472af8c1b7b4c554a829354fa8jm * Read a line of response data from the socket. \n indicates end of line.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: bytes read
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 - error
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_readline(vs_scan_ctx_t *ctx, char *buf, int buflen)
911106dfb16696472af8c1b7b4c554a829354fa8jm for (;;) {
53c110294d8b1410cabc201a52f94b03ae2ef448jm if (retval <= 0) {
53c110294d8b1410cabc201a52f94b03ae2ef448jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (c == '\n')
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* remove preceding and trailing whitespace */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (i);
911106dfb16696472af8c1b7b4c554a829354fa8jm/* ************************************************************************ */
911106dfb16696472af8c1b7b4c554a829354fa8jm/* HEADER processing */
911106dfb16696472af8c1b7b4c554a829354fa8jm/* ************************************************************************ */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_parse_hdrs
911106dfb16696472af8c1b7b4c554a829354fa8jm * parse an icap hdr line to find name and value
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_parse_hdrs(char delimiter, char *line, char **name, char **val)
911106dfb16696472af8c1b7b4c554a829354fa8jm char *q = line;
911106dfb16696472af8c1b7b4c554a829354fa8jm /* strip any spaces */
911106dfb16696472af8c1b7b4c554a829354fa8jm while (*q == ' ')
911106dfb16696472af8c1b7b4c554a829354fa8jm /* Empty line is normal termination */
911106dfb16696472af8c1b7b4c554a829354fa8jm *q++ = '\0';
911106dfb16696472af8c1b7b4c554a829354fa8jm /* value part follows spaces */
911106dfb16696472af8c1b7b4c554a829354fa8jm while (*q == ' ')
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_resp_violations
911106dfb16696472af8c1b7b4c554a829354fa8jm/*ARGSUSED*/
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_resp_violations(vs_scan_ctx_t *ctx, int hdr_id, char *line)
911106dfb16696472af8c1b7b4c554a829354fa8jm for (i = 0; i < vcnt; i++) {
911106dfb16696472af8c1b7b4c554a829354fa8jm return (rv);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_resp_violation_rec
911106dfb16696472af8c1b7b4c554a829354fa8jm * take all violation data (up to VS_MAX_VIOLATIONS) and save it
911106dfb16696472af8c1b7b4c554a829354fa8jm * in violation_info.
911106dfb16696472af8c1b7b4c554a829354fa8jm * each violation has 4 lines of info: doc name, virus name,
911106dfb16696472af8c1b7b4c554a829354fa8jm * virus id and resolution
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_resp_violation_rec(vs_scan_ctx_t *ctx, int vr_idx)
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((retval = vs_icap_readline(ctx, buf, VS_BUF_SZ)) < 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* empty line? */
911106dfb16696472af8c1b7b4c554a829354fa8jm switch (vline) {
911106dfb16696472af8c1b7b4c554a829354fa8jm case 0: /* doc name */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_opt_value
911106dfb16696472af8c1b7b4c554a829354fa8jm * given an icap options hdr string, process value
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_opt_value(vs_scan_ctx_t *ctx, int hdr_id, char *line)
911106dfb16696472af8c1b7b4c554a829354fa8jm switch (hdr_id) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (*line == 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_resp_istag
911106dfb16696472af8c1b7b4c554a829354fa8jm * Called to handle ISTAG when received in RESPMOD response.
911106dfb16696472af8c1b7b4c554a829354fa8jm * - populate result->vsr_scanstamp from istag
911106dfb16696472af8c1b7b4c554a829354fa8jm * - update the scanstamp in vs_options and log the update.
911106dfb16696472af8c1b7b4c554a829354fa8jm/*ARGSUSED*/
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_resp_istag(vs_scan_ctx_t *ctx, int hdr_id, char *line)
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_icap_istag_to_scanstamp(line, ctx->vsc_result->vsr_scanstamp);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* update the scanstamp in vs_options */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_istag_to_scanstamp
911106dfb16696472af8c1b7b4c554a829354fa8jm * Copies istag into scanstamp, stripping leading and trailing
911106dfb16696472af8c1b7b4c554a829354fa8jm * quotes '"' from istag. If the istag is invalid (too long)
911106dfb16696472af8c1b7b4c554a829354fa8jm * scanstamp will be left unchanged.
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_scanstamp_t is defined to be large enough to hold the
911106dfb16696472af8c1b7b4c554a829354fa8jm * istag plus a null terminator.
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_istag_to_scanstamp(char *istag, vs_scanstamp_t scanstamp)
911106dfb16696472af8c1b7b4c554a829354fa8jm char *p = istag;
911106dfb16696472af8c1b7b4c554a829354fa8jm /* eliminate preceding '"' */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (p[0] == '"')
911106dfb16696472af8c1b7b4c554a829354fa8jm /* eliminate trailing '"' */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_opt_ext
911106dfb16696472af8c1b7b4c554a829354fa8jm * read the transfer preview / transfer complete headers to
911106dfb16696472af8c1b7b4c554a829354fa8jm * determine which file types can be previewed
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_opt_ext(vs_scan_ctx_t *ctx, int hdr_id, char *line)
911106dfb16696472af8c1b7b4c554a829354fa8jm switch (hdr_id) {
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_resp_infection
911106dfb16696472af8c1b7b4c554a829354fa8jm * read the type, resolution and threat description for each
911106dfb16696472af8c1b7b4c554a829354fa8jm * reported violation and save in ctx->vsc_result
911106dfb16696472af8c1b7b4c554a829354fa8jm/*ARGSUSED*/
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_resp_infection(vs_scan_ctx_t *ctx, int hdr_id, char *line)
911106dfb16696472af8c1b7b4c554a829354fa8jm for (i = 0; i < VS_INFECTION_FIELDS; i++) {
911106dfb16696472af8c1b7b4c554a829354fa8jm switch (i) {
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * We may have info from an X-Violations-Found record, (which provides
911106dfb16696472af8c1b7b4c554a829354fa8jm * more complete information). If so, don't destroy what we have.
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_resp_virus_id
911106dfb16696472af8c1b7b4c554a829354fa8jm * X-Virus-ID is defined as being a shorter alternative to X-Infection-Found.
911106dfb16696472af8c1b7b4c554a829354fa8jm * If we already have virus information, from either X-Infection-Found or
911106dfb16696472af8c1b7b4c554a829354fa8jm * X-Violations-Found, it will be more complete, so don't overwrite it with
911106dfb16696472af8c1b7b4c554a829354fa8jm * the info from X-Virus-ID.
911106dfb16696472af8c1b7b4c554a829354fa8jm/*ARGSUSED*/
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_resp_virus_id(vs_scan_ctx_t *ctx, int hdr_id, char *line)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_resp_encap
911106dfb16696472af8c1b7b4c554a829354fa8jm * get the encapsulated header info
911106dfb16696472af8c1b7b4c554a829354fa8jm/*ARGSUSED*/
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_resp_encap(vs_scan_ctx_t *ctx, int hdr_id, char *line)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * Utility functions for handling OPTIONS data: vs_options_t
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_compare_scanstamp
911106dfb16696472af8c1b7b4c554a829354fa8jm * compare scanstamp with that stored for engine idx
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - if equal
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_compare_scanstamp(int idx, vs_scanstamp_t scanstamp)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (rc);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_compare_se
911106dfb16696472af8c1b7b4c554a829354fa8jm * compare host and port with that stored for engine idx
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 - if equal
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_free_options
911106dfb16696472af8c1b7b4c554a829354fa8jm * Free dynamic parts of vs_options_t: xfer_preview, xfer_complete
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_copy_options
911106dfb16696472af8c1b7b4c554a829354fa8jmvs_icap_copy_options(vs_options_t *to_opt, vs_options_t *from_opt)
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_update_options
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vs_icap_compare_se(idx, ctx->vsc_host, ctx->vsc_port) == 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm vs_icap_copy_options(&vs_options[idx], &ctx->vsc_options);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_make_strvec
911106dfb16696472af8c1b7b4c554a829354fa8jm * Populate a iovec_t from line, where line is a string of 'sep'
911106dfb16696472af8c1b7b4c554a829354fa8jm * separated fields. Within the copy of line in the iovec_t each
911106dfb16696472af8c1b7b4c554a829354fa8jm * field will be null terminated with leading & trailing whitespace
911106dfb16696472af8c1b7b4c554a829354fa8jm * removed. This allows for fast searching.
911106dfb16696472af8c1b7b4c554a829354fa8jm * The iovec_t itself and the data it points to are allocated
911106dfb16696472af8c1b7b4c554a829354fa8jm * as a single chunk.
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* tokenize data for easier searching */
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_copy_strvec
911106dfb16696472af8c1b7b4c554a829354fa8jm * allocate and copy strvec
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((to_vec = (iovec_t *)calloc(1, from_vec->iov_len)) == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_check_ext
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 1 - if ext in strvec
911106dfb16696472af8c1b7b4c554a829354fa8jm * 0 - otherwise
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_resp_str
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic char *
911106dfb16696472af8c1b7b4c554a829354fa8jm return (p->vsm_msg);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_trimspace
911106dfb16696472af8c1b7b4c554a829354fa8jm * Trims whitespace from both the beginning and end of a string. This
911106dfb16696472af8c1b7b4c554a829354fa8jm * function alters the string buffer in-place.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Whitespaces found at the beginning of the string are eliminated by
911106dfb16696472af8c1b7b4c554a829354fa8jm * moving forward the start of the string at the first non-whitespace
911106dfb16696472af8c1b7b4c554a829354fa8jm * character.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Whitespace found at the end of the string are overwritten with nulls.
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
911106dfb16696472af8c1b7b4c554a829354fa8jm char *p = buf;
911106dfb16696472af8c1b7b4c554a829354fa8jm char *q = buf;
911106dfb16696472af8c1b7b4c554a829354fa8jm while (*p && isspace(*p))
911106dfb16696472af8c1b7b4c554a829354fa8jm while ((*q = *p++) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm if (q != buf) {
911106dfb16696472af8c1b7b4c554a829354fa8jm while ((--q, isspace(*q)) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm *q = '\0';
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_uri_encode
911106dfb16696472af8c1b7b4c554a829354fa8jm * Encode uri data (eg filename) in accordance with RFC 2396
911106dfb16696472af8c1b7b4c554a829354fa8jm * 'Illegal' characters should be replaced with %hh, where hh is
911106dfb16696472af8c1b7b4c554a829354fa8jm * the hex value of the character. For example a space would be
911106dfb16696472af8c1b7b4c554a829354fa8jm * replaced with %20.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Filenames are all already UTF-8 encoded. Any UTF-8 octects that
911106dfb16696472af8c1b7b4c554a829354fa8jm * are 'illegal' characters will be encoded as described above.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Paramaters: data - string to be encoded (NULL terminated)
911106dfb16696472af8c1b7b4c554a829354fa8jm * buf - output buffer (NULL terminated)
911106dfb16696472af8c1b7b4c554a829354fa8jm * size - size of output buffer
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: strlen of encoded data on success
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 size on error (contents of buf undefined)
911106dfb16696472af8c1b7b4c554a829354fa8jm /* modify the data */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm * vs_icap_uri_illegal_char
911106dfb16696472af8c1b7b4c554a829354fa8jm * The following us-ascii characters (UTF-8 octets) are 'illegal':
911106dfb16696472af8c1b7b4c554a829354fa8jm * < > # % " { } | \ ^ [ ] ` space, 0x01 -> 0x1F & 0x7F
911106dfb16696472af8c1b7b4c554a829354fa8jm * All non us-ascii UTF-8 octets ( >= 0x80) are illegal.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 1 if character is not allowed in a URI
911106dfb16696472af8c1b7b4c554a829354fa8jm * 0 otherwise
911106dfb16696472af8c1b7b4c554a829354fa8jm static const char *uri_illegal_chars = "<>#%\" {}|\\^[]`";
911106dfb16696472af8c1b7b4c554a829354fa8jm /* us-ascii non printable characters or non us-ascii */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm /* us-ascii dis-allowed characters */
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);