mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 09:57:34 +00:00
postfix-3.10-20241025
This commit is contained in:
parent
c7a9de81bf
commit
a559c5da49
@ -28439,3 +28439,11 @@ Apologies for any names omitted.
|
|||||||
Documentation: in a pgsql: client configuration, the setting
|
Documentation: in a pgsql: client configuration, the setting
|
||||||
"dbname" is required, but ignored when the setting "hosts"
|
"dbname" is required, but ignored when the setting "hosts"
|
||||||
contains an URI with a database name. File: proto/pgsql_table.
|
contains an URI with a database name. File: proto/pgsql_table.
|
||||||
|
|
||||||
|
20241025
|
||||||
|
|
||||||
|
Cleanup: accept any well-formed URI prefix as a pgsql: client
|
||||||
|
connection target (the PostgreSQL URI parser decides what
|
||||||
|
is allowed). The dbname setting is now optional if the hosts
|
||||||
|
setting specifies only URIs. Files: util/valid_uri_scheme.[hc],
|
||||||
|
proto/pgsql_table.
|
||||||
|
@ -43,22 +43,30 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
|
|
||||||
<b><a name="pgsql_parameters">PGSQL PARAMETERS</a></b>
|
<b><a name="pgsql_parameters">PGSQL PARAMETERS</a></b>
|
||||||
<b>hosts</b> The hosts that Postfix will try to connect to and query from.
|
<b>hosts</b> The hosts that Postfix will try to connect to and query from.
|
||||||
Besides a <b>postgresql://</b> connection URI, this setting supports
|
Besides a PostgreSQL connection URI, this setting supports the
|
||||||
the historical forms <b>unix:/</b><i>pathname</i> for UNIX-domain sockets and
|
historical forms <b>unix:/</b><i>pathname</i> for UNIX-domain sockets and
|
||||||
<b>inet:</b><i>host:port</i> for TCP connections, where the <b>unix:</b> and <b>inet:</b>
|
<b>inet:</b><i>host:port</i> for TCP connections, where the <b>unix:</b> and <b>inet:</b>
|
||||||
prefixes are accepted and ignored for backwards compatibility.
|
prefixes are accepted and ignored for backwards compatibility.
|
||||||
Examples:
|
Examples:
|
||||||
hosts = postgresql://username@example.com/<i>databasename</i>?sslmode=require
|
hosts = postgresql://username@example.com/<i>databasename</i>?sslmode=require
|
||||||
|
hosts = postgres://user:secret@localhost
|
||||||
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
||||||
hosts = host1.some.domain host2.some.domain:port
|
hosts = host1.some.domain host2.some.domain:port
|
||||||
hosts = unix:/file/name
|
hosts = unix:/file/name
|
||||||
|
|
||||||
|
See <a href="https://www.postgresql.org/docs/current/libpq-connect.html">https://www.postgresql.org/docs/current/libpq-connect.html</a>
|
||||||
|
for the supported connection URI syntax.
|
||||||
|
|
||||||
The hosts are tried in random order. The connections are auto-
|
The hosts are tried in random order. The connections are auto-
|
||||||
matically closed after being idle for about 1 minute, and are
|
matically closed after being idle for about 1 minute, and are
|
||||||
re-opened as necessary.
|
re-opened as necessary. See <b>idle_interval</b> for details.
|
||||||
|
|
||||||
NOTE: if "hosts" specifies one load balancer and no alternative
|
NOTE: if <b>hosts</b> specifies a PostgreSQL connection URI, the Post-
|
||||||
servers, specify the load balancer multiple times in the "hosts"
|
greSQL client library will ignore the <b>dbname</b> setting for that
|
||||||
|
connection.
|
||||||
|
|
||||||
|
NOTE: if <b>hosts</b> specifies one load balancer and no alternative
|
||||||
|
servers, specify the load balancer multiple times in the <b>hosts</b>
|
||||||
line. Without the duplicate info, the Postfix PostgreSQL client
|
line. Without the duplicate info, the Postfix PostgreSQL client
|
||||||
would not reconnect immediately to the same load balancer after
|
would not reconnect immediately to the same load balancer after
|
||||||
a PostgreSQL server failure.
|
a PostgreSQL server failure.
|
||||||
@ -71,12 +79,15 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
|||||||
user = someone
|
user = someone
|
||||||
password = some_password
|
password = some_password
|
||||||
|
|
||||||
<b>dbname</b> (required)
|
<b>dbname</b> The database name on the servers. Example:
|
||||||
The database name on the servers. Example:
|
|
||||||
dbname = customer_database
|
dbname = customer_database
|
||||||
|
|
||||||
This setting is required, but ignored when a postgresql:// URI
|
The <b>dbname</b> setting is ignored for <b>hosts</b> connections that are
|
||||||
specifies a database name.
|
specified as an URI.
|
||||||
|
|
||||||
|
The <b>dbname</b> setting is required with Postfix 3.10 and later, when
|
||||||
|
<b>hosts</b> specifies any non-URI connection; it is always required
|
||||||
|
with earlier Postfix versions.
|
||||||
|
|
||||||
<b>encoding</b>
|
<b>encoding</b>
|
||||||
The encoding used by the database client. The default setting
|
The encoding used by the database client. The default setting
|
||||||
|
@ -55,7 +55,7 @@ return the key itself or a constant value.
|
|||||||
.fi
|
.fi
|
||||||
.IP "\fBhosts\fR"
|
.IP "\fBhosts\fR"
|
||||||
The hosts that Postfix will try to connect to and query
|
The hosts that Postfix will try to connect to and query
|
||||||
from. Besides a \fBpostgresql://\fR connection URI, this
|
from. Besides a PostgreSQL connection URI, this
|
||||||
setting supports the historical forms \fBunix:/\fIpathname\fR
|
setting supports the historical forms \fBunix:/\fIpathname\fR
|
||||||
for UNIX\-domain sockets and \fBinet:\fIhost:port\fR for TCP
|
for UNIX\-domain sockets and \fBinet:\fIhost:port\fR for TCP
|
||||||
connections, where the \fBunix:\fR and \fBinet:\fR prefixes
|
connections, where the \fBunix:\fR and \fBinet:\fR prefixes
|
||||||
@ -63,18 +63,28 @@ are accepted and ignored for backwards compatibility.
|
|||||||
Examples:
|
Examples:
|
||||||
.nf
|
.nf
|
||||||
hosts = postgresql://username@example.com/\fIdatabasename\fR?sslmode=require
|
hosts = postgresql://username@example.com/\fIdatabasename\fR?sslmode=require
|
||||||
|
hosts = postgres://user:secret@localhost
|
||||||
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
hosts = inet:host1.some.domain inet:host2.some.domain:port
|
||||||
hosts = host1.some.domain host2.some.domain:port
|
hosts = host1.some.domain host2.some.domain:port
|
||||||
hosts = unix:/file/name
|
hosts = unix:/file/name
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
See https://www.postgresql.org/docs/current/libpq\-connect.html
|
||||||
|
for the supported connection URI syntax.
|
||||||
|
|
||||||
The hosts are tried in random order. The connections are
|
The hosts are tried in random order. The connections are
|
||||||
automatically closed after being idle for about 1 minute,
|
automatically closed after being idle for about 1 minute,
|
||||||
and are re\-opened as necessary.
|
and are re\-opened as necessary. See \fBidle_interval\fR
|
||||||
|
for details.
|
||||||
|
|
||||||
NOTE: if "hosts" specifies one load balancer and no alternative
|
NOTE: if \fBhosts\fR specifies a PostgreSQL connection URI,
|
||||||
|
the PostgreSQL client library will ignore the \fBdbname\fR
|
||||||
|
setting for that connection.
|
||||||
|
|
||||||
|
NOTE: if \fBhosts\fR specifies one load balancer and no
|
||||||
|
alternative
|
||||||
servers, specify the load balancer multiple times in the
|
servers, specify the load balancer multiple times in the
|
||||||
"hosts" line. Without the duplicate info, the Postfix
|
\fBhosts\fR line. Without the duplicate info, the Postfix
|
||||||
PostgreSQL client would not reconnect immediately to the
|
PostgreSQL client would not reconnect immediately to the
|
||||||
same load balancer after a PostgreSQL server failure.
|
same load balancer after a PostgreSQL server failure.
|
||||||
.IP "\fBuser\fR"
|
.IP "\fBuser\fR"
|
||||||
@ -85,14 +95,18 @@ Example:
|
|||||||
user = someone
|
user = someone
|
||||||
password = some_password
|
password = some_password
|
||||||
.fi
|
.fi
|
||||||
.IP "\fBdbname\fR (required)"
|
.IP "\fBdbname\fR"
|
||||||
The database name on the servers. Example:
|
The database name on the servers. Example:
|
||||||
.nf
|
.nf
|
||||||
dbname = customer_database
|
dbname = customer_database
|
||||||
.fi
|
.fi
|
||||||
.sp
|
.sp
|
||||||
This setting is required, but ignored when a postgresql://
|
The \fBdbname\fR setting is ignored for \fBhosts\fR connections
|
||||||
URI specifies a database name.
|
that are specified as an URI.
|
||||||
|
|
||||||
|
The \fBdbname\fR setting is required with Postfix 3.10 and later,
|
||||||
|
when \fBhosts\fR specifies any non\-URI connection; it is always
|
||||||
|
required with earlier Postfix versions.
|
||||||
.IP "\fBencoding\fR"
|
.IP "\fBencoding\fR"
|
||||||
The encoding used by the database client. The default setting
|
The encoding used by the database client. The default setting
|
||||||
is:
|
is:
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
# .fi
|
# .fi
|
||||||
# .IP "\fBhosts\fR"
|
# .IP "\fBhosts\fR"
|
||||||
# The hosts that Postfix will try to connect to and query
|
# The hosts that Postfix will try to connect to and query
|
||||||
# from. Besides a \fBpostgresql://\fR connection URI, this
|
# from. Besides a PostgreSQL connection URI, this
|
||||||
# setting supports the historical forms \fBunix:/\fIpathname\fR
|
# setting supports the historical forms \fBunix:/\fIpathname\fR
|
||||||
# for UNIX-domain sockets and \fBinet:\fIhost:port\fR for TCP
|
# for UNIX-domain sockets and \fBinet:\fIhost:port\fR for TCP
|
||||||
# connections, where the \fBunix:\fR and \fBinet:\fR prefixes
|
# connections, where the \fBunix:\fR and \fBinet:\fR prefixes
|
||||||
@ -53,18 +53,28 @@
|
|||||||
# Examples:
|
# Examples:
|
||||||
# .nf
|
# .nf
|
||||||
# hosts = postgresql://username@example.com/\fIdatabasename\fR?sslmode=require
|
# hosts = postgresql://username@example.com/\fIdatabasename\fR?sslmode=require
|
||||||
|
# hosts = postgres://user:secret@localhost
|
||||||
# hosts = inet:host1.some.domain inet:host2.some.domain:port
|
# hosts = inet:host1.some.domain inet:host2.some.domain:port
|
||||||
# hosts = host1.some.domain host2.some.domain:port
|
# hosts = host1.some.domain host2.some.domain:port
|
||||||
# hosts = unix:/file/name
|
# hosts = unix:/file/name
|
||||||
# .fi
|
# .fi
|
||||||
#
|
#
|
||||||
|
# See https://www.postgresql.org/docs/current/libpq-connect.html
|
||||||
|
# for the supported connection URI syntax.
|
||||||
|
#
|
||||||
# The hosts are tried in random order. The connections are
|
# The hosts are tried in random order. The connections are
|
||||||
# automatically closed after being idle for about 1 minute,
|
# automatically closed after being idle for about 1 minute,
|
||||||
# and are re-opened as necessary.
|
# and are re-opened as necessary. See \fBidle_interval\fR
|
||||||
|
# for details.
|
||||||
#
|
#
|
||||||
# NOTE: if "hosts" specifies one load balancer and no alternative
|
# NOTE: if \fBhosts\fR specifies a PostgreSQL connection URI,
|
||||||
|
# the PostgreSQL client library will ignore the \fBdbname\fR
|
||||||
|
# setting for that connection.
|
||||||
|
#
|
||||||
|
# NOTE: if \fBhosts\fR specifies one load balancer and no
|
||||||
|
# alternative
|
||||||
# servers, specify the load balancer multiple times in the
|
# servers, specify the load balancer multiple times in the
|
||||||
# "hosts" line. Without the duplicate info, the Postfix
|
# \fBhosts\fR line. Without the duplicate info, the Postfix
|
||||||
# PostgreSQL client would not reconnect immediately to the
|
# PostgreSQL client would not reconnect immediately to the
|
||||||
# same load balancer after a PostgreSQL server failure.
|
# same load balancer after a PostgreSQL server failure.
|
||||||
# .IP "\fBuser\fR"
|
# .IP "\fBuser\fR"
|
||||||
@ -75,14 +85,18 @@
|
|||||||
# user = someone
|
# user = someone
|
||||||
# password = some_password
|
# password = some_password
|
||||||
# .fi
|
# .fi
|
||||||
# .IP "\fBdbname\fR (required)"
|
# .IP "\fBdbname\fR"
|
||||||
# The database name on the servers. Example:
|
# The database name on the servers. Example:
|
||||||
# .nf
|
# .nf
|
||||||
# dbname = customer_database
|
# dbname = customer_database
|
||||||
# .fi
|
# .fi
|
||||||
# .sp
|
# .sp
|
||||||
# This setting is required, but ignored when a postgresql://
|
# The \fBdbname\fR setting is ignored for \fBhosts\fR connections
|
||||||
# URI specifies a database name.
|
# that are specified as an URI.
|
||||||
|
#
|
||||||
|
# The \fBdbname\fR setting is required with Postfix 3.10 and later,
|
||||||
|
# when \fBhosts\fR specifies any non-URI connection; it is always
|
||||||
|
# required with earlier Postfix versions.
|
||||||
# .IP "\fBencoding\fR"
|
# .IP "\fBencoding\fR"
|
||||||
# The encoding used by the database client. The default setting
|
# The encoding used by the database client. The default setting
|
||||||
# is:
|
# is:
|
||||||
|
@ -1252,6 +1252,7 @@ dict_pgsql.o: ../../include/myrand.h
|
|||||||
dict_pgsql.o: ../../include/split_at.h
|
dict_pgsql.o: ../../include/split_at.h
|
||||||
dict_pgsql.o: ../../include/stringops.h
|
dict_pgsql.o: ../../include/stringops.h
|
||||||
dict_pgsql.o: ../../include/sys_defs.h
|
dict_pgsql.o: ../../include/sys_defs.h
|
||||||
|
dict_pgsql.o: ../../include/valid_uri_scheme.h
|
||||||
dict_pgsql.o: ../../include/vbuf.h
|
dict_pgsql.o: ../../include/vbuf.h
|
||||||
dict_pgsql.o: ../../include/vstream.h
|
dict_pgsql.o: ../../include/vstream.h
|
||||||
dict_pgsql.o: ../../include/vstring.h
|
dict_pgsql.o: ../../include/vstring.h
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
#include "myrand.h"
|
#include "myrand.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "stringops.h"
|
#include "stringops.h"
|
||||||
|
#include "valid_uri_scheme.h"
|
||||||
|
|
||||||
/* Global library. */
|
/* Global library. */
|
||||||
|
|
||||||
@ -127,6 +128,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
int len_hosts; /* number of hosts */
|
int len_hosts; /* number of hosts */
|
||||||
HOST **db_hosts; /* hosts on which databases reside */
|
HOST **db_hosts; /* hosts on which databases reside */
|
||||||
|
char *non_uri_target; /* require dbname to be specified */
|
||||||
} PLPGSQL;
|
} PLPGSQL;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -626,7 +628,7 @@ static void pgsql_parse_config(DICT_PGSQL *dict_pgsql, const char *pgsqlcf)
|
|||||||
|
|
||||||
dict_pgsql->username = cfg_get_str(p, "user", "", 0, 0);
|
dict_pgsql->username = cfg_get_str(p, "user", "", 0, 0);
|
||||||
dict_pgsql->password = cfg_get_str(p, "password", "", 0, 0);
|
dict_pgsql->password = cfg_get_str(p, "password", "", 0, 0);
|
||||||
dict_pgsql->dbname = cfg_get_str(p, "dbname", "", 1, 0);
|
dict_pgsql->dbname = cfg_get_str(p, "dbname", "", 0, 0);
|
||||||
dict_pgsql->encoding = cfg_get_str(p, "encoding", "UTF8", 1, 0);
|
dict_pgsql->encoding = cfg_get_str(p, "encoding", "UTF8", 1, 0);
|
||||||
dict_pgsql->retry_interval = cfg_get_int(p, "retry_interval",
|
dict_pgsql->retry_interval = cfg_get_int(p, "retry_interval",
|
||||||
DEF_RETRY_INTV, 1, 0);
|
DEF_RETRY_INTV, 1, 0);
|
||||||
@ -723,6 +725,21 @@ DICT *dict_pgsql_open(const char *name, int open_flags, int dict_flags)
|
|||||||
dict_pgsql->pldb = plpgsql_init(dict_pgsql->hosts);
|
dict_pgsql->pldb = plpgsql_init(dict_pgsql->hosts);
|
||||||
if (dict_pgsql->pldb == NULL)
|
if (dict_pgsql->pldb == NULL)
|
||||||
msg_fatal("couldn't initialize pldb!\n");
|
msg_fatal("couldn't initialize pldb!\n");
|
||||||
|
if (msg_verbose && dict_pgsql->pldb->non_uri_target == 0
|
||||||
|
&& dict_pgsql->dbname[0] != 0)
|
||||||
|
msg_info("%s:%s table ignores 'dbname' field -- "
|
||||||
|
"all 'hosts' targets are URIs",
|
||||||
|
DICT_TYPE_PGSQL, name);
|
||||||
|
if (dict_pgsql->pldb->non_uri_target && dict_pgsql->dbname[0] == 0) {
|
||||||
|
DICT *ret;
|
||||||
|
|
||||||
|
ret == (dict_surrogate(DICT_TYPE_PGSQL, name, open_flags, dict_flags,
|
||||||
|
"%s:%s host target '%s' requires dbname setting",
|
||||||
|
DICT_TYPE_PGSQL, name,
|
||||||
|
dict_pgsql->pldb->non_uri_target));
|
||||||
|
dict_pgsql_close(&dict_pgsql->dict);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
dict_pgsql->dict.owner = cfg_get_owner(dict_pgsql->parser);
|
dict_pgsql->dict.owner = cfg_get_owner(dict_pgsql->parser);
|
||||||
return (DICT_DEBUG (&dict_pgsql->dict));
|
return (DICT_DEBUG (&dict_pgsql->dict));
|
||||||
}
|
}
|
||||||
@ -737,8 +754,12 @@ static PLPGSQL *plpgsql_init(ARGV *hosts)
|
|||||||
PLDB = (PLPGSQL *) mymalloc(sizeof(PLPGSQL));
|
PLDB = (PLPGSQL *) mymalloc(sizeof(PLPGSQL));
|
||||||
PLDB->len_hosts = hosts->argc;
|
PLDB->len_hosts = hosts->argc;
|
||||||
PLDB->db_hosts = (HOST **) mymalloc(sizeof(HOST *) * hosts->argc);
|
PLDB->db_hosts = (HOST **) mymalloc(sizeof(HOST *) * hosts->argc);
|
||||||
for (i = 0; i < hosts->argc; i++)
|
PLDB->non_uri_target = 0;
|
||||||
|
for (i = 0; i < hosts->argc; i++) {
|
||||||
PLDB->db_hosts[i] = host_init(hosts->argv[i]);
|
PLDB->db_hosts[i] = host_init(hosts->argv[i]);
|
||||||
|
if (PLDB->db_hosts[i]->type != TYPECONNSTR)
|
||||||
|
PLDB->non_uri_target = PLDB->db_hosts[i]->name;
|
||||||
|
}
|
||||||
|
|
||||||
return PLDB;
|
return PLDB;
|
||||||
}
|
}
|
||||||
@ -758,9 +779,9 @@ static HOST *host_init(const char *hostname)
|
|||||||
host->ts = 0;
|
host->ts = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modern syntax: "postgresql://connection-info".
|
* Modern syntax: connection URI.
|
||||||
*/
|
*/
|
||||||
if (strncmp(d, "postgresql:", 11) == 0) {
|
if (valid_uri_scheme(d)) {
|
||||||
host->type = TYPECONNSTR;
|
host->type = TYPECONNSTR;
|
||||||
host->name = mystrdup(d);
|
host->name = mystrdup(d);
|
||||||
host->port = 0;
|
host->port = 0;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20241024"
|
#define MAIL_RELEASE_DATE "20241025"
|
||||||
#define MAIL_VERSION_NUMBER "3.10"
|
#define MAIL_VERSION_NUMBER "3.10"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@ -46,7 +46,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
|
|||||||
sane_strtol.c hash_fnv.c ldseed.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c \
|
sane_strtol.c hash_fnv.c ldseed.c mkmap_cdb.c mkmap_db.c mkmap_dbm.c \
|
||||||
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \
|
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \
|
||||||
inet_addr_sizes.c quote_for_json.c mystrerror.c \
|
inet_addr_sizes.c quote_for_json.c mystrerror.c \
|
||||||
sane_sockaddr_to_hostaddr.c normalize_ws.c
|
sane_sockaddr_to_hostaddr.c normalize_ws.c valid_uri_scheme.c
|
||||||
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
||||||
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
|
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
|
||||||
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
|
||||||
@ -94,7 +94,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
|
|||||||
sane_strtol.o hash_fnv.o ldseed.o mkmap_db.o mkmap_dbm.o \
|
sane_strtol.o hash_fnv.o ldseed.o mkmap_db.o mkmap_dbm.o \
|
||||||
mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \
|
mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \
|
||||||
quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o \
|
quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o \
|
||||||
normalize_ws.o
|
normalize_ws.o valid_uri_scheme.o
|
||||||
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
|
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
|
||||||
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
|
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
|
||||||
# otherwise it sets the PLUGIN_* macros.
|
# otherwise it sets the PLUGIN_* macros.
|
||||||
@ -126,7 +126,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
|
|||||||
valid_utf8_hostname.h midna_domain.h dict_union.h dict_inline.h \
|
valid_utf8_hostname.h midna_domain.h dict_union.h dict_inline.h \
|
||||||
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
|
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
|
||||||
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \
|
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \
|
||||||
inet_prefix_top.h inet_addr_sizes.h
|
inet_prefix_top.h inet_addr_sizes.h valid_uri_scheme.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
|
||||||
DEFS = -I. -D$(SYSTYPE)
|
DEFS = -I. -D$(SYSTYPE)
|
||||||
@ -149,7 +149,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
|
|||||||
vbuf_print split_qnameval vstream msg_logger byte_mask \
|
vbuf_print split_qnameval vstream msg_logger byte_mask \
|
||||||
known_tcp_ports dict_stream find_inet binhash hash_fnv argv \
|
known_tcp_ports dict_stream find_inet binhash hash_fnv argv \
|
||||||
clean_env inet_prefix_top printable readlline quote_for_json \
|
clean_env inet_prefix_top printable readlline quote_for_json \
|
||||||
normalize_ws
|
normalize_ws valid_uri_scheme
|
||||||
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \
|
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \
|
||||||
$(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX)
|
$(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX)
|
||||||
HTABLE_FIX = NORANDOMIZE=1
|
HTABLE_FIX = NORANDOMIZE=1
|
||||||
@ -618,6 +618,11 @@ normalize_ws: $(LIB)
|
|||||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||||
mv junk $@.o
|
mv junk $@.o
|
||||||
|
|
||||||
|
valid_uri_scheme: $(LIB)
|
||||||
|
mv $@.o junk
|
||||||
|
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
|
||||||
|
mv junk $@.o
|
||||||
|
|
||||||
tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
|
tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
|
||||||
hex_quote_test ctable_test inet_addr_list_test base64_code_test \
|
hex_quote_test ctable_test inet_addr_list_test base64_code_test \
|
||||||
attr_scan64_test attr_scan0_test host_port_test dict_tests \
|
attr_scan64_test attr_scan0_test host_port_test dict_tests \
|
||||||
@ -629,7 +634,7 @@ tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
|
|||||||
vstream_test byte_mask_tests mystrtok_test known_tcp_ports_test \
|
vstream_test byte_mask_tests mystrtok_test known_tcp_ports_test \
|
||||||
binhash_test argv_test inet_prefix_top_test printable_test \
|
binhash_test argv_test inet_prefix_top_test printable_test \
|
||||||
valid_utf8_string_test readlline_test quote_for_json_test \
|
valid_utf8_string_test readlline_test quote_for_json_test \
|
||||||
normalize_ws_test
|
normalize_ws_test valid_uri_scheme_test
|
||||||
|
|
||||||
dict_tests: all dict_test \
|
dict_tests: all dict_test \
|
||||||
dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \
|
dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \
|
||||||
@ -1109,6 +1114,9 @@ quote_for_json_test: quote_for_json
|
|||||||
normalize_ws_test: normalize_ws
|
normalize_ws_test: normalize_ws
|
||||||
$(SHLIB_ENV) ${VALGRIND} ./normalize_ws
|
$(SHLIB_ENV) ${VALGRIND} ./normalize_ws
|
||||||
|
|
||||||
|
valid_uri_scheme_test: valid_uri_scheme
|
||||||
|
$(SHLIB_ENV) ${VALGRIND} ./valid_uri_scheme
|
||||||
|
|
||||||
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 \
|
||||||
@ -2893,6 +2901,16 @@ valid_hostname.o: valid_hostname.c
|
|||||||
valid_hostname.o: valid_hostname.h
|
valid_hostname.o: valid_hostname.h
|
||||||
valid_hostname.o: vbuf.h
|
valid_hostname.o: vbuf.h
|
||||||
valid_hostname.o: vstring.h
|
valid_hostname.o: vstring.h
|
||||||
|
valid_uri_scheme.o: check_arg.h
|
||||||
|
valid_uri_scheme.o: msg.h
|
||||||
|
valid_uri_scheme.o: msg_vstream.h
|
||||||
|
valid_uri_scheme.o: stringops.h
|
||||||
|
valid_uri_scheme.o: sys_defs.h
|
||||||
|
valid_uri_scheme.o: valid_uri_scheme.c
|
||||||
|
valid_uri_scheme.o: valid_uri_scheme.h
|
||||||
|
valid_uri_scheme.o: vbuf.h
|
||||||
|
valid_uri_scheme.o: vstream.h
|
||||||
|
valid_uri_scheme.o: vstring.h
|
||||||
valid_utf8_hostname.o: check_arg.h
|
valid_utf8_hostname.o: check_arg.h
|
||||||
valid_utf8_hostname.o: midna_domain.h
|
valid_utf8_hostname.o: midna_domain.h
|
||||||
valid_utf8_hostname.o: msg.h
|
valid_utf8_hostname.o: msg.h
|
||||||
|
129
postfix/src/util/valid_uri_scheme.c
Normal file
129
postfix/src/util/valid_uri_scheme.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* valid_uri_scheme 3
|
||||||
|
/* SUMMARY
|
||||||
|
/* validate scheme:// prefix
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <valid_uri_scheme.h>
|
||||||
|
/*
|
||||||
|
/* int valid_uri_scheme(const char *str)
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* valid_uri_scheme() takes a null-terminated string and returns
|
||||||
|
/* the length of a valid scheme:// prefix, or zero if no valid
|
||||||
|
/* prefix was found.
|
||||||
|
/*
|
||||||
|
/* This function requires that input is encoded in ASCII or UTF-8.
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* porcupine.org
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System library.
|
||||||
|
*/
|
||||||
|
#include <sys_defs.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility library.
|
||||||
|
*/
|
||||||
|
#include <valid_uri_scheme.h>
|
||||||
|
#include <msg.h>
|
||||||
|
#include <msg_vstream.h>
|
||||||
|
#include <stringops.h>
|
||||||
|
|
||||||
|
/* valid_uri_scheme - predicate that string starts with scheme:// */
|
||||||
|
|
||||||
|
ssize_t valid_uri_scheme(const char *str)
|
||||||
|
{
|
||||||
|
const char *cp = str;
|
||||||
|
int ch = *cp++;
|
||||||
|
|
||||||
|
/* Per RFC 3986, a valid scheme starts with ALPHA. */
|
||||||
|
if (!ISALPHA(ch))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
while ((ch = *cp++) != 0) {
|
||||||
|
/* A valid scheme continues with ALPHA | DIGIT | '+' | '-'. */
|
||||||
|
if (ISALNUM(ch) || ch == '+' || ch == '-')
|
||||||
|
continue;
|
||||||
|
/* A valid scheme is followed by "://". */
|
||||||
|
if (ch == ':' && *cp++ == '/' && *cp++ == '/')
|
||||||
|
return (cp - str);
|
||||||
|
/* Not a valid scheme. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Not a valid scheme. */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
typedef struct TEST_CASE {
|
||||||
|
const char *label;
|
||||||
|
const char *input;
|
||||||
|
const ssize_t want;
|
||||||
|
} TEST_CASE;
|
||||||
|
|
||||||
|
#define PASS (0)
|
||||||
|
#define FAIL (1)
|
||||||
|
|
||||||
|
static const TEST_CASE test_cases[] = {
|
||||||
|
{"accepts_alpha_scheme", "abcd://blah", sizeof("abcd://") - 1},
|
||||||
|
{"accepts_mixed_scheme", "a-bcd+123://blah", sizeof("a-bcd+123://") - 1},
|
||||||
|
{"rejects_minus_first", "-bcd+123://blah'", 0},
|
||||||
|
{"rejects_plus_first", "+123://blah", 0},
|
||||||
|
{"rejects_digit_first", "123://blah", 0},
|
||||||
|
{"rejects_other_first", "?123://blah", 0},
|
||||||
|
{"rejects_other_middle", "abcd?123://blah", 0},
|
||||||
|
{"rejects_other_end", "abcd-123?://blah", 0},
|
||||||
|
{"rejects_non_scheme", "inet:host:port", 0},
|
||||||
|
{"rejects_no_colon", "inet", 0},
|
||||||
|
{"rejects_colon_slash", "abcd:/blah", 0},
|
||||||
|
{"rejects_empty", "", 0},
|
||||||
|
{0,}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int test_validate_scheme(const TEST_CASE *tp)
|
||||||
|
{
|
||||||
|
int got;
|
||||||
|
|
||||||
|
got = valid_uri_scheme(tp->input);
|
||||||
|
if (got != tp->want) {
|
||||||
|
msg_warn("got '%ld', want '%ld'", (long) got, (long) tp->want);
|
||||||
|
return (FAIL);
|
||||||
|
}
|
||||||
|
return (PASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const TEST_CASE *tp;
|
||||||
|
int pass = 0;
|
||||||
|
int fail = 0;
|
||||||
|
|
||||||
|
msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
|
||||||
|
|
||||||
|
for (tp = test_cases; tp->label != 0; tp++) {
|
||||||
|
int test_failed;
|
||||||
|
|
||||||
|
msg_info("RUN %s", tp->label);
|
||||||
|
test_failed = test_validate_scheme(tp);
|
||||||
|
if (test_failed) {
|
||||||
|
msg_info("FAIL %s", tp->label);
|
||||||
|
fail++;
|
||||||
|
} else {
|
||||||
|
msg_info("PASS %s", tp->label);
|
||||||
|
pass++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg_info("PASS=%d FAIL=%d", pass, fail);
|
||||||
|
exit(fail != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
28
postfix/src/util/valid_uri_scheme.h
Normal file
28
postfix/src/util/valid_uri_scheme.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _VALID_SCHEME_H_INCLUDED_
|
||||||
|
#define _VALID_SCHEME_H_INCLUDED_
|
||||||
|
|
||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* valid_uri_scheme 3h
|
||||||
|
/* SUMMARY
|
||||||
|
/* validate scheme:// prefix
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <valid_uri_scheme.h>
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* .nf
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External interface.
|
||||||
|
*/
|
||||||
|
extern ssize_t valid_uri_scheme(const char *);
|
||||||
|
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema
|
||||||
|
/* porcupine.org
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user