Postfix3.3.1
valid_mailhost_addr.c
[詳解]
1 /*++
2 /* NAME
3 /* valid_mailhost_addr 3
4 /* SUMMARY
5 /* mailhost address syntax validation
6 /* SYNOPSIS
7 /* #include <valid_mailhost_addr.h>
8 /*
9 /* const char *valid_mailhost_addr(name, gripe)
10 /* const char *name;
11 /* int gripe;
12 /*
13 /* int valid_mailhost_literal(addr, gripe)
14 /* const char *addr;
15 /* int gripe;
16 /* DESCRIPTION
17 /* valid_mailhost_addr() requires that the input is a valid
18 /* RFC 2821 string representation of an IPv4 or IPv6 network
19 /* address. A valid IPv4 address is in dotted quad decimal
20 /* form. A valid IPv6 address includes the "IPV6:" prefix as
21 /* required by RFC 2821, and is in valid hexadecimal form or
22 /* in valid IPv4-in-IPv6 form. The result value is the bare
23 /* address in the input argument (i.e. text after "IPV6:"
24 /* prefix, if any) in case of success, a null pointer in case
25 /* of failure.
26 /*
27 /* valid_mailhost_literal() requires an address enclosed in
28 /* []. The result is non-zero in case of success, zero in
29 /* case of failure.
30 /*
31 /* These routines operate silently unless the gripe parameter
32 /* specifies a non-zero value. The macros DO_GRIPE and DONT_GRIPE
33 /* provide suitable constants.
34 /*
35 /* The IPV6_COL macro defines the "IPv6:" prefix.
36 /* DIAGNOSTICS
37 /* Warnings are logged with msg_warn().
38 /* SEE ALSO
39 /* valid_hostname(3)
40 /* RFC 952, RFC 1123, RFC 1035, RFC 2821
41 /* LICENSE
42 /* .ad
43 /* .fi
44 /* The Secure Mailer license must be distributed with this software.
45 /* AUTHOR(S)
46 /* Wietse Venema
47 /* IBM T.J. Watson Research
48 /* P.O. Box 704
49 /* Yorktown Heights, NY 10598, USA
50 /*--*/
51 
52 
53 /* System library. */
54 
55 #include <sys_defs.h>
56 #include <string.h>
57 
58 #ifdef STRCASECMP_IN_STRINGS_H
59 #include <strings.h>
60 #endif
61 
62 /* Utility library. */
63 
64 #include <msg.h>
65 #include <myaddrinfo.h>
66 
67 /* Global library. */
68 
69 #include <valid_mailhost_addr.h>
70 
71 /* Application-specific. */
72 
73 #define IPV6_COL_LEN (sizeof(IPV6_COL) - 1)
74 #define HAS_IPV6_COL(str) (strncasecmp((str), IPV6_COL, IPV6_COL_LEN) == 0)
75 #define SKIP_IPV6_COL(str) (HAS_IPV6_COL(str) ? (str) + IPV6_COL_LEN : (str))
76 
77 /* valid_mailhost_addr - validate RFC 2821 numerical address form */
78 
79 const char *valid_mailhost_addr(const char *addr, int gripe)
80 {
81  const char *bare_addr;
82 
83  bare_addr = SKIP_IPV6_COL(addr);
84  return ((bare_addr != addr ? valid_ipv6_hostaddr : valid_ipv4_hostaddr)
85  (bare_addr, gripe) ? bare_addr : 0);
86 }
87 
88 /* valid_mailhost_literal - validate [RFC 2821 numerical address] form */
89 
90 int valid_mailhost_literal(const char *addr, int gripe)
91 {
92  const char *myname = "valid_mailhost_literal";
93  MAI_HOSTADDR_STR hostaddr;
94  const char *last;
95  size_t address_bytes;
96 
97  if (*addr != '[') {
98  if (gripe)
99  msg_warn("%s: '[' expected at start: %.100s", myname, addr);
100  return (0);
101  }
102  if ((last = strchr(addr, ']')) == 0) {
103  if (gripe)
104  msg_warn("%s: ']' expected at end: %.100s", myname, addr);
105  return (0);
106  }
107  if (last[1]) {
108  if (gripe)
109  msg_warn("%s: unexpected text after ']': %.100s", myname, addr);
110  return (0);
111  }
112  if ((address_bytes = last - addr - 1) >= sizeof(hostaddr.buf)) {
113  if (gripe)
114  msg_warn("%s: too much text: %.100s", myname, addr);
115  return (0);
116  }
117  strncpy(hostaddr.buf, addr + 1, address_bytes);
118  hostaddr.buf[address_bytes] = 0;
119  return (valid_mailhost_addr(hostaddr.buf, gripe) != 0);
120 }
121 
122 #ifdef TEST
123 
124  /*
125  * Test program - reads hostnames from stdin, reports invalid hostnames to
126  * stderr.
127  */
128 #include <stdlib.h>
129 
130 #include <vstring.h>
131 #include <vstream.h>
132 #include <vstring_vstream.h>
133 #include <msg_vstream.h>
134 
135 int main(int unused_argc, char **argv)
136 {
137  VSTRING *buffer = vstring_alloc(1);
138 
139  msg_vstream_init(argv[0], VSTREAM_ERR);
140  msg_verbose = 1;
141 
142  while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
143  msg_info("testing: \"%s\"", vstring_str(buffer));
144  if (vstring_str(buffer)[0] == '[')
146  else
148  }
149  exit(0);
150 }
151 
152 #endif
int msg_verbose
Definition: msg.c:177
#define vstring_fgets_nonl(s, p)
int valid_ipv6_hostaddr(const char *addr, int gripe)
const char * valid_mailhost_addr(const char *addr, int gripe)
#define vstring_str(vp)
Definition: vstring.h:71
int main(int argc, char **argv)
Definition: anvil.c:1010
#define VSTREAM_IN
Definition: vstream.h:66
int valid_ipv4_hostaddr(const char *addr, int gripe)
char buf[MAI_HOSTADDR_STRSIZE]
Definition: myaddrinfo.h:146
int valid_mailhost_literal(const char *addr, int gripe)
#define SKIP_IPV6_COL(str)
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
#define DO_GRIPE
Definition: haproxy_srvr.h:30
void msg_vstream_init(const char *name, VSTREAM *vp)
Definition: msg_vstream.c:77
#define VSTREAM_ERR
Definition: vstream.h:68
void msg_info(const char *fmt,...)
Definition: msg.c:199