mirror of
https://github.com/vdukhovni/postfix
synced 2025-09-01 14:45:32 +00:00
snapshot-20000823
This commit is contained in:
@@ -4147,3 +4147,12 @@ Apologies for any names omitted.
|
|||||||
that cannot be represented with the off_t type that is used
|
that cannot be represented with the off_t type that is used
|
||||||
by standard functions such as lseek(2). Problem reported
|
by standard functions such as lseek(2). Problem reported
|
||||||
by Blaz Zupan @ amis.net.
|
by Blaz Zupan @ amis.net.
|
||||||
|
|
||||||
|
20000823
|
||||||
|
|
||||||
|
Feature: all this discussion about when to reject mail and
|
||||||
|
when not made me decide to implement a TCP-based map type
|
||||||
|
so that it becomes relatively simple to implement dynamic
|
||||||
|
access controls, for example, hold off mail from an unknown
|
||||||
|
client or sender until we have completed some investigation,
|
||||||
|
after which we will either reject or accept.
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* Version of this program.
|
* Version of this program.
|
||||||
*/
|
*/
|
||||||
#define VAR_MAIL_VERSION "mail_version"
|
#define VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "Snapshot-20000822"
|
#define DEF_MAIL_VERSION "Snapshot-20000823"
|
||||||
extern char *var_mail_version;
|
extern char *var_mail_version;
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
1
postfix/util/.indent.pro
vendored
1
postfix/util/.indent.pro
vendored
@@ -32,6 +32,7 @@
|
|||||||
-TDICT_PCRE
|
-TDICT_PCRE
|
||||||
-TDICT_REGEXP
|
-TDICT_REGEXP
|
||||||
-TDICT_REGEXP_RULE
|
-TDICT_REGEXP_RULE
|
||||||
|
-TDICT_TCP
|
||||||
-TDICT_UNIX
|
-TDICT_UNIX
|
||||||
-TDNS_FIXED
|
-TDNS_FIXED
|
||||||
-TDNS_REPLY
|
-TDNS_REPLY
|
||||||
|
@@ -21,7 +21,8 @@ SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \
|
|||||||
write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \
|
write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \
|
||||||
stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
|
stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \
|
||||||
clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
|
clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \
|
||||||
sane_link.c unescape.c timed_read.c timed_write.c
|
sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \
|
||||||
|
hex_quote.c
|
||||||
OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
|
OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
|
||||||
close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
|
close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \
|
||||||
dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
|
dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
|
||||||
@@ -44,7 +45,8 @@ OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \
|
|||||||
write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \
|
write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \
|
||||||
stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
|
stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \
|
||||||
clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
|
clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \
|
||||||
sane_link.o unescape.o timed_read.o timed_write.o
|
sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \
|
||||||
|
hex_quote.o
|
||||||
HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
|
HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
|
||||||
dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
|
dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \
|
||||||
dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
|
dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \
|
||||||
@@ -59,7 +61,7 @@ HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \
|
|||||||
timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \
|
timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \
|
||||||
vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
|
vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \
|
||||||
dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
|
dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \
|
||||||
watchdog.h spawn_command.h sane_fsops.h
|
watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h
|
||||||
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
|
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
|
||||||
stream_test.c dup2_pass_on_exec.c
|
stream_test.c dup2_pass_on_exec.c
|
||||||
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
|
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
|
||||||
@@ -75,7 +77,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
|
|||||||
inet_addr_host inet_addr_local mac_parse make_dirs msg_syslog \
|
inet_addr_host inet_addr_local mac_parse make_dirs msg_syslog \
|
||||||
mystrtok sigdelay translit valid_hostname vstream_popen \
|
mystrtok sigdelay translit valid_hostname vstream_popen \
|
||||||
vstring vstring_vstream doze select_bug stream_test mac_expand \
|
vstring vstring_vstream doze select_bug stream_test mac_expand \
|
||||||
watchdog unescape
|
watchdog unescape hex_quote
|
||||||
|
|
||||||
LIB_DIR = ../lib
|
LIB_DIR = ../lib
|
||||||
INC_DIR = ../include
|
INC_DIR = ../include
|
||||||
@@ -249,6 +251,11 @@ unescape: $(LIB)
|
|||||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||||
mv junk $@.o
|
mv junk $@.o
|
||||||
|
|
||||||
|
hex_quote: $(LIB)
|
||||||
|
mv $@.o junk
|
||||||
|
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||||
|
mv junk $@.o
|
||||||
|
|
||||||
depend: $(MAKES)
|
depend: $(MAKES)
|
||||||
(sed '1,/^# do not edit/!d' Makefile.in; \
|
(sed '1,/^# do not edit/!d' Makefile.in; \
|
||||||
set -e; for i in [a-z][a-z0-9]*.c; do \
|
set -e; for i in [a-z][a-z0-9]*.c; do \
|
||||||
@@ -260,7 +267,8 @@ depend: $(MAKES)
|
|||||||
stream_test: stream_test.c $(LIB)
|
stream_test: stream_test.c $(LIB)
|
||||||
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS)
|
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||||
|
|
||||||
tests: valid_hostname_test mac_expand_test dict_test unescape_test
|
tests: valid_hostname_test mac_expand_test dict_test unescape_test \
|
||||||
|
hex_quote_test
|
||||||
|
|
||||||
valid_hostname_test: valid_hostname valid_hostname.in valid_hostname.ref
|
valid_hostname_test: valid_hostname valid_hostname.in valid_hostname.ref
|
||||||
./valid_hostname <valid_hostname.in 2>valid_hostname.tmp
|
./valid_hostname <valid_hostname.in 2>valid_hostname.tmp
|
||||||
@@ -277,6 +285,12 @@ unescape_test: unescape unescape.in unescape.ref
|
|||||||
diff -b unescape.ref unescape.tmp
|
diff -b unescape.ref unescape.tmp
|
||||||
rm -f unescape.tmp
|
rm -f unescape.tmp
|
||||||
|
|
||||||
|
hex_quote_test: hex_quote
|
||||||
|
./hex_quote <hex_quote.c | od -cb >hex_quote.tmp
|
||||||
|
od -cb <hex_quote.c >hex_quote.ref
|
||||||
|
cmp hex_quote.ref hex_quote.tmp
|
||||||
|
rm -f hex_quote.ref hex_quote.tmp
|
||||||
|
|
||||||
DB_TYPE = `../postconf/postconf -h default_database_type`
|
DB_TYPE = `../postconf/postconf -h default_database_type`
|
||||||
|
|
||||||
dict_test: dict_open testdb dict_test.in dict_test.ref
|
dict_test: dict_open testdb dict_test.in dict_test.ref
|
||||||
@@ -416,6 +430,7 @@ dict_open.o: vstream.h
|
|||||||
dict_open.o: vbuf.h
|
dict_open.o: vbuf.h
|
||||||
dict_open.o: dict_env.h
|
dict_open.o: dict_env.h
|
||||||
dict_open.o: dict_unix.h
|
dict_open.o: dict_unix.h
|
||||||
|
dict_open.o: dict_tcp.h
|
||||||
dict_open.o: dict_dbm.h
|
dict_open.o: dict_dbm.h
|
||||||
dict_open.o: dict_db.h
|
dict_open.o: dict_db.h
|
||||||
dict_open.o: dict_nis.h
|
dict_open.o: dict_nis.h
|
||||||
@@ -445,6 +460,20 @@ dict_regexp.o: dict.h
|
|||||||
dict_regexp.o: argv.h
|
dict_regexp.o: argv.h
|
||||||
dict_regexp.o: dict_regexp.h
|
dict_regexp.o: dict_regexp.h
|
||||||
dict_regexp.o: mac_parse.h
|
dict_regexp.o: mac_parse.h
|
||||||
|
dict_tcp.o: dict_tcp.c
|
||||||
|
dict_tcp.o: sys_defs.h
|
||||||
|
dict_tcp.o: msg.h
|
||||||
|
dict_tcp.o: mymalloc.h
|
||||||
|
dict_tcp.o: vstring.h
|
||||||
|
dict_tcp.o: vbuf.h
|
||||||
|
dict_tcp.o: vstream.h
|
||||||
|
dict_tcp.o: vstring_vstream.h
|
||||||
|
dict_tcp.o: connect.h
|
||||||
|
dict_tcp.o: iostuff.h
|
||||||
|
dict_tcp.o: hex_quote.h
|
||||||
|
dict_tcp.o: dict.h
|
||||||
|
dict_tcp.o: argv.h
|
||||||
|
dict_tcp.o: dict_tcp.h
|
||||||
dict_unix.o: dict_unix.c
|
dict_unix.o: dict_unix.c
|
||||||
dict_unix.o: sys_defs.h
|
dict_unix.o: sys_defs.h
|
||||||
dict_unix.o: msg.h
|
dict_unix.o: msg.h
|
||||||
@@ -465,6 +494,7 @@ doze.o: doze.c
|
|||||||
doze.o: sys_defs.h
|
doze.o: sys_defs.h
|
||||||
doze.o: msg.h
|
doze.o: msg.h
|
||||||
doze.o: iostuff.h
|
doze.o: iostuff.h
|
||||||
|
dup2_pass_on_exec.o: dup2_pass_on_exec.c
|
||||||
duplex_pipe.o: duplex_pipe.c
|
duplex_pipe.o: duplex_pipe.c
|
||||||
duplex_pipe.o: sys_defs.h
|
duplex_pipe.o: sys_defs.h
|
||||||
duplex_pipe.o: iostuff.h
|
duplex_pipe.o: iostuff.h
|
||||||
@@ -526,6 +556,12 @@ get_hostname.o: mymalloc.h
|
|||||||
get_hostname.o: msg.h
|
get_hostname.o: msg.h
|
||||||
get_hostname.o: valid_hostname.h
|
get_hostname.o: valid_hostname.h
|
||||||
get_hostname.o: get_hostname.h
|
get_hostname.o: get_hostname.h
|
||||||
|
hex_quote.o: hex_quote.c
|
||||||
|
hex_quote.o: sys_defs.h
|
||||||
|
hex_quote.o: msg.h
|
||||||
|
hex_quote.o: vstring.h
|
||||||
|
hex_quote.o: vbuf.h
|
||||||
|
hex_quote.o: hex_quote.h
|
||||||
htable.o: htable.c
|
htable.o: htable.c
|
||||||
htable.o: sys_defs.h
|
htable.o: sys_defs.h
|
||||||
htable.o: mymalloc.h
|
htable.o: mymalloc.h
|
||||||
@@ -948,6 +984,7 @@ vstring_vstream.o: vstream.h
|
|||||||
vstring_vstream.o: vstring_vstream.h
|
vstring_vstream.o: vstring_vstream.h
|
||||||
watchdog.o: watchdog.c
|
watchdog.o: watchdog.c
|
||||||
watchdog.o: sys_defs.h
|
watchdog.o: sys_defs.h
|
||||||
|
watchdog.o: posix_signals.h
|
||||||
watchdog.o: msg.h
|
watchdog.o: msg.h
|
||||||
watchdog.o: mymalloc.h
|
watchdog.o: mymalloc.h
|
||||||
watchdog.o: watchdog.h
|
watchdog.o: watchdog.h
|
||||||
|
@@ -156,6 +156,7 @@
|
|||||||
#include <dict.h>
|
#include <dict.h>
|
||||||
#include <dict_env.h>
|
#include <dict_env.h>
|
||||||
#include <dict_unix.h>
|
#include <dict_unix.h>
|
||||||
|
#include <dict_tcp.h>
|
||||||
#include <dict_dbm.h>
|
#include <dict_dbm.h>
|
||||||
#include <dict_db.h>
|
#include <dict_db.h>
|
||||||
#include <dict_nis.h>
|
#include <dict_nis.h>
|
||||||
@@ -180,6 +181,7 @@ typedef struct {
|
|||||||
static DICT_OPEN_INFO dict_open_info[] = {
|
static DICT_OPEN_INFO dict_open_info[] = {
|
||||||
"environ", dict_env_open,
|
"environ", dict_env_open,
|
||||||
"unix", dict_unix_open,
|
"unix", dict_unix_open,
|
||||||
|
"tcp", dict_tcp_open,
|
||||||
#ifdef HAS_DBM
|
#ifdef HAS_DBM
|
||||||
"dbm", dict_dbm_open,
|
"dbm", dict_dbm_open,
|
||||||
#endif
|
#endif
|
||||||
@@ -318,6 +320,7 @@ ARGV *dict_mapnames()
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
/* Utility library. */
|
/* Utility library. */
|
||||||
|
|
||||||
@@ -343,6 +346,8 @@ main(int argc, char **argv)
|
|||||||
const char *value;
|
const char *value;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
msg_vstream_init(argv[0], VSTREAM_ERR);
|
msg_vstream_init(argv[0], VSTREAM_ERR);
|
||||||
while ((ch = GETOPT(argc, argv, "v")) > 0) {
|
while ((ch = GETOPT(argc, argv, "v")) > 0) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
@@ -380,7 +385,9 @@ main(int argc, char **argv)
|
|||||||
vstream_printf("%s: deleted\n", key);
|
vstream_printf("%s: deleted\n", key);
|
||||||
} else if (strcmp(cmd, "get") == 0 && key && !value) {
|
} else if (strcmp(cmd, "get") == 0 && key && !value) {
|
||||||
if ((value = dict_get(dict, key)) == 0) {
|
if ((value = dict_get(dict, key)) == 0) {
|
||||||
vstream_printf("%s: not found\n", key);
|
vstream_printf("%s: %s\n", key,
|
||||||
|
dict_errno == DICT_ERR_RETRY ?
|
||||||
|
"soft error" : "not found");
|
||||||
} else {
|
} else {
|
||||||
vstream_printf("%s=%s\n", key, value);
|
vstream_printf("%s=%s\n", key, value);
|
||||||
}
|
}
|
||||||
@@ -388,7 +395,7 @@ main(int argc, char **argv)
|
|||||||
dict_put(dict, key, value);
|
dict_put(dict, key, value);
|
||||||
vstream_printf("%s=%s\n", key, value);
|
vstream_printf("%s=%s\n", key, value);
|
||||||
} else {
|
} else {
|
||||||
vstream_printf("usage: del key|get key|put key=value");
|
vstream_printf("usage: del key|get key|put key=value\n");
|
||||||
}
|
}
|
||||||
vstream_fflush(VSTREAM_OUT);
|
vstream_fflush(VSTREAM_OUT);
|
||||||
}
|
}
|
||||||
|
191
postfix/util/dict_tcp.c
Normal file
191
postfix/util/dict_tcp.c
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* dict_tcp 3
|
||||||
|
/* SUMMARY
|
||||||
|
/* dictionary manager interface to tcp-based lookup tables
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <dict_tcp.h>
|
||||||
|
/*
|
||||||
|
/* DICT *dict_tcp_open(map, dummy, dict_flags)
|
||||||
|
/* const char *map;
|
||||||
|
/* int dummy;
|
||||||
|
/* int dict_flags;
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* dict_tcp_open() makes a TCP server accessible via the generic
|
||||||
|
/* dictionary operations described in dict_open(3).
|
||||||
|
/* The \fIdummy\fR argument is not used. Server access is read-only
|
||||||
|
/* (i.e., only lookups are implemented).
|
||||||
|
/*
|
||||||
|
/* Map names have the form host:port.
|
||||||
|
/*
|
||||||
|
/* The map implements a very simple protocol: the query is sent as
|
||||||
|
/* one line of text, and the reply is sent back in the same format.
|
||||||
|
/* Data is sent as a newline-terminated string. % and non-printable
|
||||||
|
/* characters are replaced by %xx, xx being the corresponding
|
||||||
|
/* hexadecimal value.
|
||||||
|
/* SEE ALSO
|
||||||
|
/* dict(3) generic dictionary manager
|
||||||
|
/* DIAGNOSTICS
|
||||||
|
/* Fatal errors: out of memory, unknown host or service name,
|
||||||
|
/* attempt to update map.
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* IBM T.J. Watson Research
|
||||||
|
/* P.O. Box 704
|
||||||
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
/* System library. */
|
||||||
|
|
||||||
|
#include "sys_defs.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Utility library. */
|
||||||
|
|
||||||
|
#include "msg.h"
|
||||||
|
#include "mymalloc.h"
|
||||||
|
#include "vstring.h"
|
||||||
|
#include "vstream.h"
|
||||||
|
#include "vstring_vstream.h"
|
||||||
|
#include "connect.h"
|
||||||
|
#include "hex_quote.h"
|
||||||
|
#include "dict.h"
|
||||||
|
#include "dict_tcp.h"
|
||||||
|
|
||||||
|
/* Application-specific. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DICT dict; /* generic members */
|
||||||
|
char *map; /* server host:port */
|
||||||
|
VSTRING *raw_buf; /* raw buffer */
|
||||||
|
VSTRING *hex_buf; /* hexified buffer */
|
||||||
|
VSTREAM *fp; /* I/O stream */
|
||||||
|
} DICT_TCP;
|
||||||
|
|
||||||
|
#define DICT_TCP_MAXTRY 10
|
||||||
|
#define DICT_TCP_TMOUT 100
|
||||||
|
|
||||||
|
#define STR(x) vstring_str(x)
|
||||||
|
|
||||||
|
/* dict_tcp_lookup - query TCP server */
|
||||||
|
|
||||||
|
static const char *dict_tcp_lookup(DICT *dict, const char *key)
|
||||||
|
{
|
||||||
|
DICT_TCP *dict_tcp = (DICT_TCP *) dict;
|
||||||
|
int fd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dict_errno = 0;
|
||||||
|
|
||||||
|
for (i = 0; /* see below */ ; i++) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to connect a few times before giving up.
|
||||||
|
*/
|
||||||
|
if (i >= DICT_TCP_MAXTRY) {
|
||||||
|
dict_errno = DICT_ERR_RETRY;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sleep between connection attempts.
|
||||||
|
*/
|
||||||
|
if (i > 0)
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to connect to the server.
|
||||||
|
*/
|
||||||
|
if (dict_tcp->fp == 0) {
|
||||||
|
if ((fd = inet_connect(dict_tcp->map, BLOCKING, 0)) < 0) {
|
||||||
|
msg_warn("connect to TCP map %s: %m", dict_tcp->map);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dict_tcp->fp = vstream_fdopen(fd, O_RDWR);
|
||||||
|
vstream_control(dict_tcp->fp,
|
||||||
|
VSTREAM_CTL_TIMEOUT, DICT_TCP_TMOUT,
|
||||||
|
VSTREAM_CTL_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate per-map buffers on the fly.
|
||||||
|
*/
|
||||||
|
if (dict_tcp->raw_buf == 0) {
|
||||||
|
dict_tcp->raw_buf = vstring_alloc(10);
|
||||||
|
dict_tcp->hex_buf = vstring_alloc(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send query and receive response. Both are %XX quoted and both are
|
||||||
|
* terminated by newline.
|
||||||
|
*/
|
||||||
|
hex_quote(dict_tcp->hex_buf, key);
|
||||||
|
vstream_fprintf(dict_tcp->fp, "%s\n", STR(dict_tcp->hex_buf));
|
||||||
|
errno = 0;
|
||||||
|
if (vstring_get_nonl(dict_tcp->hex_buf, dict_tcp->fp) == VSTREAM_EOF) {
|
||||||
|
msg_warn("read TCP map reply from %s: %m", dict_tcp->map);
|
||||||
|
} else if (!hex_unquote(dict_tcp->raw_buf, STR(dict_tcp->hex_buf))) {
|
||||||
|
msg_warn("read TCP map reply from %s: malformed reply %.100s",
|
||||||
|
dict_tcp->map, STR(dict_tcp->hex_buf));
|
||||||
|
} else {
|
||||||
|
return (STR(dict_tcp->raw_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* That did not work. Clean up and try again.
|
||||||
|
*/
|
||||||
|
(void) vstream_fclose(dict_tcp->fp);
|
||||||
|
dict_tcp->fp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dict_tcp_update - add or update table entry */
|
||||||
|
|
||||||
|
static void dict_tcp_update(DICT *dict, const char *unused_name, const char *unused_value)
|
||||||
|
{
|
||||||
|
DICT_TCP *dict_tcp = (DICT_TCP *) dict;
|
||||||
|
|
||||||
|
msg_fatal("dict_tcp_update: attempt to update map %s", dict_tcp->map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dict_tcp_close - close TCP map */
|
||||||
|
|
||||||
|
static void dict_tcp_close(DICT *dict)
|
||||||
|
{
|
||||||
|
DICT_TCP *dict_tcp = (DICT_TCP *) dict;
|
||||||
|
|
||||||
|
if (dict_tcp->fp)
|
||||||
|
(void) vstream_fclose(dict_tcp->fp);
|
||||||
|
if (dict_tcp->raw_buf)
|
||||||
|
vstring_free(dict_tcp->raw_buf);
|
||||||
|
if (dict_tcp->hex_buf)
|
||||||
|
vstring_free(dict_tcp->hex_buf);
|
||||||
|
myfree(dict_tcp->map);
|
||||||
|
myfree((char *) dict_tcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dict_tcp_open - open TCP map */
|
||||||
|
|
||||||
|
DICT *dict_tcp_open(const char *map, int unused_flags, int dict_flags)
|
||||||
|
{
|
||||||
|
DICT_TCP *dict_tcp;
|
||||||
|
|
||||||
|
dict_errno = 0;
|
||||||
|
|
||||||
|
dict_tcp = (DICT_TCP *) mymalloc(sizeof(*dict_tcp));
|
||||||
|
dict_tcp->fp = 0;
|
||||||
|
dict_tcp->raw_buf = dict_tcp->hex_buf = 0;
|
||||||
|
dict_tcp->dict.lookup = dict_tcp_lookup;
|
||||||
|
dict_tcp->dict.update = dict_tcp_update;
|
||||||
|
dict_tcp->dict.close = dict_tcp_close;
|
||||||
|
dict_tcp->dict.fd = -1;
|
||||||
|
dict_tcp->map = mystrdup(map);
|
||||||
|
dict_tcp->dict.flags = dict_flags | DICT_FLAG_FIXED;
|
||||||
|
return (&dict_tcp->dict);
|
||||||
|
}
|
35
postfix/util/dict_tcp.h
Normal file
35
postfix/util/dict_tcp.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef _DICT_TCP_H_INCLUDED_
|
||||||
|
#define _DICT_TCP_H_INCLUDED_
|
||||||
|
|
||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* dict_tcp 3h
|
||||||
|
/* SUMMARY
|
||||||
|
/* dictionary manager interface to tcp-based lookup tables
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <dict_tcp.h>
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* .nf
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility library.
|
||||||
|
*/
|
||||||
|
#include <dict.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External interface.
|
||||||
|
*/
|
||||||
|
extern DICT *dict_tcp_open(const char *, int, int);
|
||||||
|
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* IBM T.J. Watson Research
|
||||||
|
/* P.O. Box 704
|
||||||
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
#endif
|
148
postfix/util/hex_quote.c
Normal file
148
postfix/util/hex_quote.c
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* hex_quote 3
|
||||||
|
/* SUMMARY
|
||||||
|
/* quote/unquote text, HTTP style.
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <hex_quote.h>
|
||||||
|
/*
|
||||||
|
/* VSTRING *hex_quote(hex, raw)
|
||||||
|
/* VSTRING *hex;
|
||||||
|
/* const char *raw;
|
||||||
|
/*
|
||||||
|
/* VSTRING *hex_unquote(raw, hex)
|
||||||
|
/* VSTRING *raw;
|
||||||
|
/* const char *hex;
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* hex_quote() takes a null-terminated string and replaces non-printable
|
||||||
|
/* characters and % by %XX, XX being the two-digit hexadecimal equivalent.
|
||||||
|
/* The hexadecimal codes are produced as upper-case characters. The result
|
||||||
|
/* value is the hex argument.
|
||||||
|
/*
|
||||||
|
/* hex_unquote() performs the opposite transformation. This function
|
||||||
|
/* understands lowercase and uppercase %XX sequences. The result
|
||||||
|
/* value is the raw argument in case of success, a null pointer otherwise.
|
||||||
|
/* BUGS
|
||||||
|
/* Cannot process null characters.
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* IBM T.J. Watson Research
|
||||||
|
/* P.O. Box 704
|
||||||
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
/* System library. */
|
||||||
|
|
||||||
|
#include "sys_defs.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/* Utility library. */
|
||||||
|
|
||||||
|
#include "msg.h"
|
||||||
|
#include "vstring.h"
|
||||||
|
#include "hex_quote.h"
|
||||||
|
|
||||||
|
/* Application-specific. */
|
||||||
|
|
||||||
|
#define STR(x) vstring_str(x)
|
||||||
|
#define LEN(x) VSTRING_LEN(x)
|
||||||
|
|
||||||
|
/* hex_quote - raw data to quoted */
|
||||||
|
|
||||||
|
VSTRING *hex_quote(VSTRING *hex, const char *raw)
|
||||||
|
{
|
||||||
|
const char *cp;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
VSTRING_RESET(hex);
|
||||||
|
for (cp = raw; (ch = *(unsigned const char *) cp) != 0; cp++) {
|
||||||
|
if (ch != '%' && ISPRINT(ch)) {
|
||||||
|
VSTRING_ADDCH(hex, ch);
|
||||||
|
} else {
|
||||||
|
vstring_sprintf_append(hex, "%%%02X", ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VSTRING_TERMINATE(hex);
|
||||||
|
return (hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hex_unquote - quoted data to raw */
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Proof-of-concept test program: convert to hex and back.
|
||||||
|
*/
|
||||||
|
#include <vstream.h>
|
||||||
|
|
||||||
|
#define BUFLEN 1024
|
||||||
|
|
||||||
|
static int read_buf(VSTREAM *fp, VSTRING *buf)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
VSTRING_RESET(buf);
|
||||||
|
len = vstream_fread(fp, STR(buf), vstring_avail(buf));
|
||||||
|
VSTRING_AT_OFFSET(buf, len); /* XXX */
|
||||||
|
VSTRING_TERMINATE(buf);
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
main(int unused_argc, char **unused_argv)
|
||||||
|
{
|
||||||
|
VSTRING *raw = vstring_alloc(BUFLEN);
|
||||||
|
VSTRING *hex = vstring_alloc(100);
|
||||||
|
int len;
|
||||||
|
|
||||||
|
while ((len = read_buf(VSTREAM_IN, raw)) > 0) {
|
||||||
|
hex_quote(hex, STR(raw));
|
||||||
|
if (hex_unquote(raw, STR(hex)) == 0)
|
||||||
|
msg_fatal("bad input: %.100s", STR(hex));
|
||||||
|
if (LEN(raw) != len)
|
||||||
|
msg_fatal("len %d != raw len %d", len, LEN(raw));
|
||||||
|
if (vstream_fwrite(VSTREAM_OUT, STR(raw), LEN(raw)) != LEN(raw))
|
||||||
|
msg_fatal("write error: %m");
|
||||||
|
}
|
||||||
|
vstream_fflush(VSTREAM_OUT);
|
||||||
|
vstring_free(raw);
|
||||||
|
vstring_free(hex);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
postfix/util/hex_quote.h
Normal file
36
postfix/util/hex_quote.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _HEX_QUOTE_H_INCLUDED_
|
||||||
|
#define _HEX_QUOTE_H_INCLUDED_
|
||||||
|
|
||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* hex_quote 3h
|
||||||
|
/* SUMMARY
|
||||||
|
/* quote/unquote text, HTTP style.
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <hex_quote.h>
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* .nf
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility library.
|
||||||
|
*/
|
||||||
|
#include <vstring.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External interface.
|
||||||
|
*/
|
||||||
|
extern VSTRING *hex_quote(VSTRING *, const char *);
|
||||||
|
extern VSTRING *hex_unquote(VSTRING *, const char *);
|
||||||
|
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* IBM T.J. Watson Research
|
||||||
|
/* P.O. Box 704
|
||||||
|
/* Yorktown Heights, NY 10598, USA
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
#endif
|
@@ -825,7 +825,7 @@ typedef int pid_t;
|
|||||||
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7
|
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7
|
||||||
#define PRINTFLIKE(x,y) __attribute__ ((format (printf, (x), (y))))
|
#define PRINTFLIKE(x,y) __attribute__ ((format (printf, (x), (y))))
|
||||||
#else
|
#else
|
||||||
#define PRINTFLIKE
|
#define PRINTFLIKE(x,y)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user