Пример #1
0
static void mime_state_downgrade(MIME_STATE *state, int rec_type,
				         const char *text, int len)
{
    static char hexchars[] = "0123456789ABCDEF";
    const unsigned char *cp;
    int     ch;

#define QP_ENCODE(buffer, ch) { \
	VSTRING_ADDCH(buffer, '='); \
	VSTRING_ADDCH(buffer, hexchars[(ch >> 4) & 0xff]); \
	VSTRING_ADDCH(buffer, hexchars[ch & 0xf]); \
    }

    /*
     * Insert a soft line break when the output reaches a critical length
     * before we reach a hard line break.
     */
    for (cp = CU_CHAR_PTR(text); cp < CU_CHAR_PTR(text + len); cp++) {
	/* Critical length before hard line break. */
	if (LEN(state->output_buffer) > 72) {
	    VSTRING_ADDCH(state->output_buffer, '=');
	    VSTRING_TERMINATE(state->output_buffer);
	    BODY_OUT(state, REC_TYPE_NORM,
		     STR(state->output_buffer),
		     LEN(state->output_buffer));
	    VSTRING_RESET(state->output_buffer);
	}
	/* Append the next character. */
	ch = *cp;
	if ((ch < 32 && ch != '\t') || ch == '=' || ch > 126) {
	    QP_ENCODE(state->output_buffer, ch);
	} else {
	    VSTRING_ADDCH(state->output_buffer, ch);
	}
    }

    /*
     * Flush output after a hard line break (i.e. the end of a REC_TYPE_NORM
     * record). Fix trailing whitespace as per the RFC: in the worst case,
     * the output length will grow from 73 characters to 75 characters.
     */
    if (rec_type == REC_TYPE_NORM) {
	if (LEN(state->output_buffer) > 0
	    && ((ch = END(state->output_buffer)[-1]) == ' ' || ch == '\t')) {
	    vstring_truncate(state->output_buffer,
			     LEN(state->output_buffer) - 1);
	    QP_ENCODE(state->output_buffer, ch);
	}
	VSTRING_TERMINATE(state->output_buffer);
	BODY_OUT(state, REC_TYPE_NORM,
		 STR(state->output_buffer),
		 LEN(state->output_buffer));
	VSTRING_RESET(state->output_buffer);
    }
}
Пример #2
0
VSTRING *off_cvt_number(VSTRING *buf, off_t offset)
{
    static char digs[] = "0123456789";
    char   *start;
    char   *last;
    int     i;

    /*
     * Sanity checks
     */
    if (offset < 0)
        msg_panic("off_cvt_number: negative offset -%s",
                  STR(off_cvt_number(buf, -offset)));

    /*
     * First accumulate the result, backwards.
     */
    VSTRING_RESET(buf);
    while (offset != 0) {
        VSTRING_ADDCH(buf, digs[offset % 10]);
        offset /= 10;
    }
    VSTRING_TERMINATE(buf);

    /*
     * Then, reverse the result.
     */
    start = STR(buf);
    last = END(buf) - 1;
    for (i = 0; i < VSTRING_LEN(buf) / 2; i++)
        SWAP(int, start[i], last[-i]);
    return (buf);
}
Пример #3
0
VSTRING *unquote_822_local(VSTRING *dst, const char *mbox)
{
    const char *start;			/* first byte of localpart */
    const char *end;			/* first byte after localpart */
    const char *colon;
    const char *cp;

    if (mbox[0] == '@' && (colon = strchr(mbox, ':')) != 0) {
	start = colon + 1;
	vstring_strncpy(dst, mbox, start - mbox);
    } else {
	start = mbox;
	VSTRING_RESET(dst);
    }
    if ((end = strrchr(start, '@')) == 0)
	end = start + strlen(start);
    for (cp = start; cp < end; cp++) {
	if (*cp == '"')
	    continue;
	if (*cp == '\\') {
	    if (cp[1] == 0)
		continue;
	    cp++;
	}
	VSTRING_ADDCH(dst, *cp);
    }
    if (*end)
	vstring_strcat(dst, end);
    else
	VSTRING_TERMINATE(dst);
    return (dst);
}
Пример #4
0
VSTRING *quote_822_local_flags(VSTRING *dst, const char *mbox, int flags)
{
    const char *start;			/* first byte of localpart */
    const char *end;			/* first byte after localpart */
    const char *colon;

    /*
     * According to RFC 822, a local-part is a dot-string or a quoted-string.
     * We first see if the local-part is a dot-string. If it is not, we turn
     * it into a quoted-string. Anything else would be too painful. But
     * first, skip over any source route that precedes the local-part.
     */
    if (mbox[0] == '@' && (colon = strchr(mbox, ':')) != 0)
	start = colon + 1;
    else
	start = mbox;
    if ((end = strrchr(start, '@')) == 0)
	end = start + strlen(start);
    if ((flags & QUOTE_FLAG_APPEND) == 0)
	VSTRING_RESET(dst);
    if (is_822_dot_string(start, end, flags)) {
	return (vstring_strcat(dst, mbox));
    } else {
	vstring_strncat(dst, mbox, start - mbox);
	make_822_quoted_string(dst, start, end, flags & QUOTE_FLAG_8BITCLEAN);
	return (vstring_strcat(dst, end));
    }
}
Пример #5
0
VSTRING *xtext_unquote(VSTRING *unquoted, const char *quoted)
{
    const char *cp;
    int     ch;

    VSTRING_RESET(unquoted);
    for (cp = quoted; (ch = *cp) != 0; cp++) {
	if (ch == '+') {
	    if (ISDIGIT(cp[1]))
		ch = (cp[1] - '0') << 4;
	    else if (cp[1] >= 'a' && cp[1] <= 'f')
		ch = (cp[1] - 'a' + 10) << 4;
	    else if (cp[1] >= 'A' && cp[1] <= 'F')
		ch = (cp[1] - 'A' + 10) << 4;
	    else
		return (0);
	    if (ISDIGIT(cp[2]))
		ch |= (cp[2] - '0');
	    else if (cp[2] >= 'a' && cp[2] <= 'f')
		ch |= (cp[2] - 'a' + 10);
	    else if (cp[2] >= 'A' && cp[2] <= 'F')
		ch |= (cp[2] - 'A' + 10);
	    else
		return (0);
	    cp += 2;
	}
	VSTRING_ADDCH(unquoted, ch);
    }
    VSTRING_TERMINATE(unquoted);
    return (unquoted);
}
Пример #6
0
static void qmqpd_reply(QMQPD_STATE *state, int log_message,
			        int status_code, const char *fmt,...)
{
    va_list ap;

    /*
     * Optionally change hard errors into retryable ones. Send the reply and
     * optionally log it. Always insert a delay before reporting a problem.
     * This slows down software run-away conditions.
     */
    if (status_code == QMQPD_STAT_HARD && var_soft_bounce)
	status_code = QMQPD_STAT_RETRY;
    VSTRING_RESET(state->buf);
    VSTRING_ADDCH(state->buf, status_code);
    va_start(ap, fmt);
    vstring_vsprintf_append(state->buf, fmt, ap);
    va_end(ap);
    NETSTRING_PUT_BUF(state->client, state->buf);
    if (log_message)
	(status_code == QMQPD_STAT_OK ? msg_info : msg_warn) ("%s: %s: %s",
		      state->queue_id, state->namaddr, STR(state->buf) + 1);
    if (status_code != QMQPD_STAT_OK)
	sleep(var_qmqpd_err_sleep);
    netstring_fflush(state->client);
}
Пример #7
0
VSTRING *hex_decode(VSTRING *result, const char *in, ssize_t len)
{
    const unsigned char *cp;
    ssize_t count;
    unsigned int hex;
    unsigned int bin;

    VSTRING_RESET(result);
    for (cp = UCHAR_PTR(in), count = len; count > 0; cp += 2, count -= 2) {
	if (count < 2)
	    return (0);
	hex = cp[0];
	if (hex >= '0' && hex <= '9')
	    bin = (hex - '0') << 4;
	else if (hex >= 'A' && hex <= 'F')
	    bin = (hex - 'A' + 10) << 4;
	else if (hex >= 'a' && hex <= 'f')
	    bin = (hex - 'a' + 10) << 4;
	else
	    return (0);
	hex = cp[1];
	if (hex >= '0' && hex <= '9')
	    bin |= (hex - '0');
	else if (hex >= 'A' && hex <= 'F')
	    bin |= (hex - 'A' + 10);
	else if (hex >= 'a' && hex <= 'f')
	    bin |= (hex - 'a' + 10);
	else
	    return (0);
	VSTRING_ADDCH(result, bin);
    }
    VSTRING_TERMINATE(result);
    return (result);
}
Пример #8
0
SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, int endp_key_flags)
{
    SMTP_SESSION *session;
    int     fd;

    /*
     * Don't look up an existing plaintext connection when a new connection
     * would (try to) use TLS.
     */
#ifdef USE_TLS
    if (state->tls->level > TLS_LEV_NONE)
	return (0);
#endif

    /*
     * Look up the session by its IP address. This means that we have no
     * destination-to-address binding properties.
     */
    smtp_key_prefix(state->endp_label, SMTP_REUSE_KEY_DELIM_NA,
		    state->iterator, endp_key_flags);
    if ((fd = scache_find_endp(smtp_scache, STR(state->endp_label),
			       state->endp_prop)) < 0)
	return (0);
    VSTRING_RESET(state->dest_prop);
    VSTRING_TERMINATE(state->dest_prop);

    /*
     * Re-activate the SMTP_SESSION object, and verify that the session is
     * still good.
     */
    session = smtp_reuse_common(state, fd, STR(state->endp_label));

    return (session);
}
Пример #9
0
static const char *dict_union_lookup(DICT *dict, const char *query)
{
    static const char myname[] = "dict_union_lookup";
    DICT_UNION *dict_union = (DICT_UNION *) dict;
    DICT   *map;
    char  **cpp;
    char   *dict_type_name;
    const char *result = 0;

    /*
     * After Roel van Meer, postfix-users mailing list, Sept 2014.
     */
    VSTRING_RESET(dict_union->re_buf);
    for (cpp = dict_union->map_union->argv; (dict_type_name = *cpp) != 0; cpp++) {
	if ((map = dict_handle(dict_type_name)) == 0)
	    msg_panic("%s: dictionary \"%s\" not found", myname, dict_type_name);
	if ((result = dict_get(map, query)) == 0)
	    continue;
	if (VSTRING_LEN(dict_union->re_buf) > 0)
	    VSTRING_ADDCH(dict_union->re_buf, ',');
	vstring_strcat(dict_union->re_buf, result);
    }
    DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE,
			VSTRING_LEN(dict_union->re_buf) > 0 ?
			STR(dict_union->re_buf) : 0);
}
Пример #10
0
VSTRING *hex_unquote(VSTRING *raw, const char *hex)
{
    const char *cp;
    int     ch;

    VSTRING_RESET(raw);
    for (cp = hex; (ch = *cp) != 0; cp++) {
	if (ch == '%') {
	    if (ISDIGIT(cp[1]))
		ch = (cp[1] - '0') << 4;
	    else if (cp[1] >= 'a' && cp[1] <= 'f')
		ch = (cp[1] - 'a' + 10) << 4;
	    else if (cp[1] >= 'A' && cp[1] <= 'F')
		ch = (cp[1] - 'A' + 10) << 4;
	    else
		return (0);
	    if (ISDIGIT(cp[2]))
		ch |= (cp[2] - '0');
	    else if (cp[2] >= 'a' && cp[2] <= 'f')
		ch |= (cp[2] - 'a' + 10);
	    else if (cp[2] >= 'A' && cp[2] <= 'F')
		ch |= (cp[2] - 'A' + 10);
	    else
		return (0);
	    cp += 2;
	}
	VSTRING_ADDCH(raw, ch);
    }
    VSTRING_TERMINATE(raw);
    return (raw);
}
Пример #11
0
const char *cleanup_strflags(unsigned flags)
{
    static VSTRING *result;
    unsigned i;

    if (flags == 0)
	return ("none");

    if (result == 0)
	result = vstring_alloc(20);
    else
	VSTRING_RESET(result);

    for (i = 0; i < sizeof(cleanup_flag_map) / sizeof(cleanup_flag_map[0]); i++) {
	if (cleanup_flag_map[i].flag & flags) {
	    vstring_sprintf_append(result, "%s ", cleanup_flag_map[i].text);
	    flags &= ~cleanup_flag_map[i].flag;
	}
    }

    if (flags != 0 || VSTRING_LEN(result) == 0)
	msg_panic("cleanup_strflags: unrecognized flag value(s) 0x%x", flags);

    vstring_truncate(result, VSTRING_LEN(result) - 1);
    VSTRING_TERMINATE(result);

    return (vstring_str(result));
}
Пример #12
0
char   *safe_ultostr(VSTRING *buf, unsigned long ulval, int base,
		             int padlen, int padchar)
{
    const char *myname = "safe_ultostr";
    char   *start;
    char   *last;
    int     i;

    /*
     * Sanity check.
     */
    if (base < SAFE_MIN_BASE || base > SAFE_MAX_BASE)
	msg_panic("%s: bad base: %d", myname, base);

    /*
     * First accumulate the result, backwards.
     */
    VSTRING_RESET(buf);
    while (ulval != 0) {
	VSTRING_ADDCH(buf, safe_chars[ulval % base]);
	ulval /= base;
    }
    while (VSTRING_LEN(buf) < padlen)
	VSTRING_ADDCH(buf, padchar);
    VSTRING_TERMINATE(buf);

    /*
     * Then, reverse the result.
     */
    start = STR(buf);
    last = END(buf) - 1;
    for (i = 0; i < VSTRING_LEN(buf) / 2; i++)
	SWAP(int, start[i], last[-i]);
    return (STR(buf));
}
Пример #13
0
int     mac_expand(VSTRING *result, const char *pattern, int flags,
		           const char *filter,
		           MAC_EXP_LOOKUP_FN lookup, char *context)
{
    MAC_EXP mc;
    int     status;

    /*
     * Bundle up the request and do the substitutions.
     */
    mc.result = result;
    mc.flags = flags;
    mc.filter = filter;
    mc.lookup = lookup;
    mc.context = context;
    mc.status = 0;
    mc.level = 0;
    if ((flags & (MAC_EXP_FLAG_APPEND | MAC_EXP_FLAG_SCAN)) == 0)
	VSTRING_RESET(result);
    status = mac_parse(pattern, mac_expand_callback, (char *) &mc);
    if ((flags & MAC_EXP_FLAG_SCAN) == 0)
	VSTRING_TERMINATE(result);

    return (status);
}
Пример #14
0
VSTRING *netstring_get_data(VSTREAM *stream, VSTRING *buf, ssize_t len)
{
    const char *myname = "netstring_get_data";

    /*
     * Allocate buffer space.
     */
    VSTRING_RESET(buf);
    VSTRING_SPACE(buf, len);

    /*
     * Read the payload and absorb the terminator.
     */
    if (vstream_fread(stream, STR(buf), len) != len)
	netstring_except(stream, vstream_ftimeout(stream) ?
			 NETSTRING_ERR_TIME : NETSTRING_ERR_EOF);
    if (msg_verbose > 1)
	msg_info("%s: read netstring data %.*s",
		 myname, (int) (len < 30 ? len : 30), STR(buf));
    netstring_get_terminator(stream);

    /*
     * Position the buffer.
     */
    VSTRING_AT_OFFSET(buf, len);
    return (buf);
}
Пример #15
0
int     main(int argc, char **argv)
{
    VSTRING *in = vstring_alloc(10);
    VSTRING *out = vstring_alloc(10);
    double  tval;
    int     sec;
    int     usec;
    int     sig_dig;
    int     max_dig;

    while (vstring_get_nonl(in, VSTREAM_IN) > 0) {
	vstream_printf(">> %s\n", vstring_str(in));
	if (vstring_str(in)[0] == 0 || vstring_str(in)[0] == '#')
	    continue;
	if (sscanf(vstring_str(in), "%lf %d %d", &tval, &sig_dig, &max_dig) != 3)
	    msg_fatal("bad input: %s", vstring_str(in));
	sec = (int) tval;			/* raw seconds */
	usec = (tval - sec) * MILLION;		/* raw microseconds */
	VSTRING_RESET(out);
	format_tv(out, sec, usec, sig_dig, max_dig);
	vstream_printf("%s\n", vstring_str(out));
	vstream_fflush(VSTREAM_OUT);
    }
    vstring_free(in);
    vstring_free(out);
    return (0);
}
Пример #16
0
static int attr_scan_plain_string(VSTREAM *fp, VSTRING *plain_buf,
				        int terminator, const char *context)
{
#if 0
    extern int var_line_limit;		/* XXX */
    int     limit = var_line_limit * 4;

#endif
    int     ch;

    VSTRING_RESET(plain_buf);
    while ((ch = VSTREAM_GETC(fp)) != '\n'
	   && (terminator == 0 || ch != terminator)) {
	if (ch == VSTREAM_EOF) {
	    msg_warn("%s on %s while reading %s",
		vstream_ftimeout(fp) ? "timeout" : "premature end-of-input",
		     VSTREAM_PATH(fp), context);
	    return (-1);
	}
	VSTRING_ADDCH(plain_buf, ch);
#if 0
	if (LEN(plain_buf) > limit) {
	    msg_warn("string length > %d characters from %s while reading %s",
		     limit, VSTREAM_PATH(fp), context);
	    return (-1);
	}
#endif
    }
    VSTRING_TERMINATE(plain_buf);

    if (msg_verbose)
	msg_info("%s: %s", context, *STR(plain_buf) ? STR(plain_buf) : "(end)");
    return (ch);
}
Пример #17
0
VSTRING *vstring_vsprintf(VSTRING *vp, const char *format, va_list ap)
{
    VSTRING_RESET(vp);
    vbuf_print(&vp->vbuf, format, ap);
    VSTRING_TERMINATE(vp);
    return (vp);
}
Пример #18
0
static void scache_single_free_endp(SCACHE_SINGLE *sp)
{
    const char *myname = "scache_single_free_endp";

    if (msg_verbose)
	msg_info("%s: %s", myname, STR(sp->endp.endp_label));

    event_cancel_timer(scache_single_expire_endp, (char *) sp);
    if (sp->endp.fd >= 0 && close(sp->endp.fd) < 0)
	msg_warn("close session endpoint %s: %m", STR(sp->endp.endp_label));
    VSTRING_RESET(sp->endp.endp_label);
    VSTRING_TERMINATE(sp->endp.endp_label);
    VSTRING_RESET(sp->endp.endp_prop);
    VSTRING_TERMINATE(sp->endp.endp_prop);
    sp->endp.fd = -1;
}
Пример #19
0
static void scache_single_free_dest(SCACHE_SINGLE *sp)
{
    const char *myname = "scache_single_free_dest";

    if (msg_verbose)
	msg_info("%s: %s -> %s", myname, STR(sp->dest.dest_label),
		 STR(sp->dest.endp_label));

    event_cancel_timer(scache_single_expire_dest, (char *) sp);
    VSTRING_RESET(sp->dest.dest_label);
    VSTRING_TERMINATE(sp->dest.dest_label);
    VSTRING_RESET(sp->dest.dest_prop);
    VSTRING_TERMINATE(sp->dest.dest_prop);
    VSTRING_RESET(sp->dest.endp_label);
    VSTRING_TERMINATE(sp->dest.endp_label);
}
Пример #20
0
VSTRING *vstring_memcpy(VSTRING *vp, const char *src, ssize_t len)
{
    VSTRING_RESET(vp);

    VSTRING_SPACE(vp, len);
    memcpy(vstring_str(vp), src, len);
    VSTRING_AT_OFFSET(vp, len);
    return (vp);
}
int     xsasl_cyrus_server_first(XSASL_SERVER *xp, const char *sasl_method,
			          const char *init_response, VSTRING *reply)
{
    const char *myname = "xsasl_cyrus_server_first";
    XSASL_CYRUS_SERVER *server = (XSASL_CYRUS_SERVER *) xp;
    char   *dec_buffer;
    unsigned dec_length;
    unsigned reply_len;
    unsigned serveroutlen;
    int     sasl_status;
    SERVEROUT_TYPE serverout = 0;
    int     xsasl_status;

#if SASL_VERSION_MAJOR < 2
    const char *errstr = 0;

#endif

#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))

    if (msg_verbose)
	msg_info("%s: sasl_method %s%s%s", myname, sasl_method,
		 IFELSE(init_response, ", init_response ", ""),
		 IFELSE(init_response, init_response, ""));

    /*
     * SASL authentication protocol start-up. Process any initial client
     * response that was sent along in the AUTH command.
     */
    if (init_response) {
	reply_len = strlen(init_response);
	VSTRING_RESET(server->decoded);		/* Fix 200512 */
	VSTRING_SPACE(server->decoded, reply_len);
	if ((sasl_status = SASL_DECODE64(init_response, reply_len,
					 dec_buffer = STR(server->decoded),
					 vstring_avail(server->decoded),
					 &dec_length)) != SASL_OK) {
	    vstring_strcpy(reply, xsasl_cyrus_strerror(sasl_status));
	    return (XSASL_AUTH_FORM);
	}
	if (msg_verbose)
	    msg_info("%s: decoded initial response %s", myname, dec_buffer);
    } else {
	dec_buffer = 0;
	dec_length = 0;
    }
    sasl_status = SASL_SERVER_START(server->sasl_conn, sasl_method, dec_buffer,
				    dec_length, &serverout,
				    &serveroutlen, &errstr);
    xsasl_status = xsasl_cyrus_server_auth_response(sasl_status, serverout,
						    serveroutlen, reply);
#if SASL_VERSION_MAJOR < 2
    /* SASL version 1 doesn't free memory that it allocates. */
    free(serverout);
#endif
    return (xsasl_status);
}
Пример #22
0
static ssize_t read_buf(VSTREAM *fp, VSTRING *buf)
{
    ssize_t len;

    VSTRING_RESET(buf);
    len = vstream_fread(fp, STR(buf), vstring_avail(buf));
    VSTRING_AT_OFFSET(buf, len);		/* XXX */
    VSTRING_TERMINATE(buf);
    return (len);
}
Пример #23
0
int     vstring_get_null(VSTRING *vp, VSTREAM *fp)
{
    int     c;

    VSTRING_RESET(vp);
    while ((c = VSTREAM_GETC(fp)) != VSTREAM_EOF && c != 0)
	VSTRING_ADDCH(vp, c);
    VSTRING_TERMINATE(vp);
    return (c == 0 ? c : VSTRING_GET_RESULT(vp));
}
Пример #24
0
VSTRING *readlline(VSTRING *buf, VSTREAM *fp, int *lineno)
{
    int     ch;
    int     next;
    int     start;
    char   *cp;

    VSTRING_RESET(buf);

    /*
     * Ignore comment lines, all whitespace lines, and empty lines. Terminate
     * at EOF or at the beginning of the next logical line.
     */
    for (;;) {
	/* Read one line, possibly not newline terminated. */
	start = LEN(buf);
	while ((ch = VSTREAM_GETC(fp)) != VSTREAM_EOF && ch != '\n')
	    VSTRING_ADDCH(buf, ch);
	if (ch == '\n' && lineno != 0)
	    *lineno += 1;
	/* Ignore comment line, all whitespace line, or empty line. */
	for (cp = STR(buf) + start; cp < END(buf) && ISSPACE(*cp); cp++)
	     /* void */ ;
	if (cp == END(buf) || *cp == '#')
	    vstring_truncate(buf, start);
	/* Terminate at EOF or at the beginning of the next logical line. */
	if (ch == VSTREAM_EOF)
	    break;
	if (LEN(buf) > 0) {
	    if ((next = VSTREAM_GETC(fp)) != VSTREAM_EOF)
		vstream_ungetc(fp, next);
	    if (next != '#' && !ISSPACE(next))
		break;
	}
    }
    VSTRING_TERMINATE(buf);

    /*
     * Invalid input: continuing text without preceding text. Allowing this
     * would complicate "postconf -e", which implements its own multi-line
     * parsing routine. Do not abort, just warn, so that critical programs
     * like postmap do not leave behind a truncated table.
     */
    if (LEN(buf) > 0 && ISSPACE(*STR(buf))) {
	msg_warn("%s: logical line must not start with whitespace: \"%.30s%s\"",
		 VSTREAM_PATH(fp), STR(buf),
		 LEN(buf) > 30 ? "..." : "");
	return (readlline(buf, fp, lineno));
    }

    /*
     * Done.
     */
    return (LEN(buf) > 0 ? buf : 0);
}
Пример #25
0
VSTRING *vstring_strncpy(VSTRING *vp, const char *src, ssize_t len)
{
    VSTRING_RESET(vp);

    while (len-- > 0 && *src) {
	VSTRING_ADDCH(vp, *src);
	src++;
    }
    VSTRING_TERMINATE(vp);
    return (vp);
}
Пример #26
0
char   *smtp_key_prefix(VSTRING *buffer, const char *delim_na,
			        SMTP_ITERATOR *iter, int flags)
{
    static const char myname[] = "smtp_key_prefix";
    SMTP_STATE *state = iter->parent;	/* private member */

    /*
     * Sanity checks.
     */
    if (state == 0)
	msg_panic("%s: no parent state", myname);
    if (flags & ~SMTP_KEY_MASK_ALL)
	msg_panic("%s: unknown key flags 0x%x",
		  myname, flags & ~SMTP_KEY_MASK_ALL);
    if (flags == 0)
	msg_panic("%s: zero flags", myname);

    /*
     * Initialize.
     */
    VSTRING_RESET(buffer);

    /*
     * Per-service and per-request context.
     */
    if (flags & SMTP_KEY_FLAG_SERVICE)
	smtp_key_append_str(buffer, state->service, delim_na);
    if (flags & SMTP_KEY_FLAG_SENDER)
	smtp_key_append_str(buffer, state->request->sender, delim_na);

    /*
     * Per-destination context, non-canonicalized form.
     */
    if (flags & SMTP_KEY_FLAG_REQ_NEXTHOP)
	smtp_key_append_str(buffer, STR(iter->request_nexthop), delim_na);
    if (flags & SMTP_KEY_FLAG_NEXTHOP)
	smtp_key_append_str(buffer, STR(iter->dest), delim_na);

    /*
     * Per-host context, canonicalized form.
     */
    if (flags & SMTP_KEY_FLAG_HOSTNAME)
	smtp_key_append_str(buffer, STR(iter->host), delim_na);
    if (flags & SMTP_KEY_FLAG_ADDR)
	smtp_key_append_str(buffer, STR(iter->addr), delim_na);
    if (flags & SMTP_KEY_FLAG_PORT)
	smtp_key_append_uint(buffer, ntohs(iter->port), delim_na);

    /* Similarly, provide unique TLS fingerprint when applicable. */

    VSTRING_TERMINATE(buffer);

    return STR(buffer);
}
Пример #27
0
int     main(int unused_argc, char **unused_argv)
{
    VSTRING *buf = vstring_alloc(100);
    VSTRING *result = vstring_alloc(100);
    char   *cp;
    char   *name;
    char   *value;
    HTABLE *table;
    int     stat;

    while (!vstream_feof(VSTREAM_IN)) {

	table = htable_create(0);

	/*
	 * Read a block of definitions, terminated with an empty line.
	 */
	while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
	    vstream_printf("<< %s\n", vstring_str(buf));
	    vstream_fflush(VSTREAM_OUT);
	    if (VSTRING_LEN(buf) == 0)
		break;
	    cp = vstring_str(buf);
	    name = mystrtok(&cp, " \t\r\n=");
	    value = mystrtok(&cp, " \t\r\n=");
	    htable_enter(table, name, value ? mystrdup(value) : 0);
	}

	/*
	 * Read a block of patterns, terminated with an empty line or EOF.
	 */
	while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
	    vstream_printf("<< %s\n", vstring_str(buf));
	    vstream_fflush(VSTREAM_OUT);
	    if (VSTRING_LEN(buf) == 0)
		break;
	    cp = vstring_str(buf);
	    VSTRING_RESET(result);
	    stat = mac_expand(result, vstring_str(buf), MAC_EXP_FLAG_NONE,
			      (char *) 0, lookup, (char *) table);
	    vstream_printf("stat=%d result=%s\n", stat, vstring_str(result));
	    vstream_fflush(VSTREAM_OUT);
	}
	htable_free(table, myfree);
	vstream_printf("\n");
    }

    /*
     * Clean up.
     */
    vstring_free(buf);
    vstring_free(result);
    exit(0);
}
Пример #28
0
static void encode_utf8(VSTRING *buffer, int codepoint)
{
    const char myname[] = "encode_utf8";

    VSTRING_RESET(buffer);
    if (codepoint < 0x80) {
	VSTRING_ADDCH(buffer, codepoint);
    } else if (codepoint < 0x800) {
	VSTRING_ADDCH(buffer, 0xc0 | (codepoint >> 6));
	VSTRING_ADDCH(buffer, 0x80 | (codepoint & 0x3f));
    } else if (codepoint < 0x10000) {
Пример #29
0
VSTRING *vstring_strcpy(VSTRING *vp, const char *src)
{
    VSTRING_RESET(vp);

    while (*src) {
	VSTRING_ADDCH(vp, *src);
	src++;
    }
    VSTRING_TERMINATE(vp);
    return (vp);
}
Пример #30
0
static int smtpd_proxy_xforward_flush(SMTPD_STATE *state, VSTRING *buf)
{
    int     ret;

    if (VSTRING_LEN(buf) > 0) {
	ret = smtpd_proxy_cmd(state, SMTPD_PROX_WANT_OK,
			      XFORWARD_CMD "%s", STR(buf));
	VSTRING_RESET(buf);
	return (ret);
    }
    return (0);
}