24 |
|
|
25 |
#include "headers.h" |
#include "headers.h" |
26 |
#include "extern.h" |
#include "extern.h" |
27 |
|
#include "rcfile.h" |
28 |
|
|
29 |
static int optlength(char *); |
#define setbool(a, b, c) \ |
30 |
static void match_options_common(int, char *); |
do {\ |
31 |
static int get_regex(int, char *, char *, int); |
if (strcmp("yes", a) == 0) \ |
32 |
static char *parse_line_regex(char *); |
(b) |= (c); \ |
33 |
static void get_action_line(char *); |
else if (strcmp("no", a) == 0) \ |
34 |
static void match_action(char *, const char *); |
(b) &= ~(c); \ |
35 |
|
else \ |
36 |
static time_t global_mtime; |
return RC_KW_ERROR; \ |
37 |
|
} while (0) |
|
#define set(a, b, c) \ |
|
|
if ((optlen = strlen((char *)a)) == 0) \ |
|
|
return; \ |
|
|
if (strncmp("yes", (char *)a, optlen) == 0) \ |
|
|
b |= c; \ |
|
|
else if (strncmp("no", (char *)a, optlen) == 0) \ |
|
|
b &= ~c; \ |
|
|
return; |
|
|
|
|
|
#define if_empty_quit(a) \ |
|
|
if (strlen((char *)a) == 0) \ |
|
|
return; |
|
38 |
|
|
39 |
#define if_empty_set(a, b, c) \ |
#define if_empty_set(a, b, c) \ |
40 |
if (strlen((char *)a) == 0) { \ |
do {\ |
41 |
b &= ~c; \ |
if (strlen(a) == 0) { \ |
42 |
return; \ |
(b) &= ~(c); \ |
43 |
} \ |
} else { \ |
44 |
else if (strlen((char *)a) != 0) { \ |
(b) |= (c); \ |
45 |
b |= c; \ |
}\ |
46 |
return; \ |
} while (0) |
47 |
} |
|
48 |
|
#define MAX_SECTIONS 10 |
49 |
|
|
50 |
|
static RC_SECTION *parse_tree; |
51 |
|
static int parse_tree_method; |
52 |
|
static struct rc_secdef anubis_rc_sections[MAX_SECTIONS]; |
53 |
|
static int anubis_rc_numsections; |
54 |
|
|
55 |
void |
struct rc_secdef * |
56 |
open_rcfile(int method) |
anubis_add_section(char *name) |
57 |
|
{ |
58 |
|
int i; |
59 |
|
|
60 |
|
if (anubis_rc_numsections >= MAX_SECTIONS) |
61 |
|
abort(); /*FIXME*/ |
62 |
|
|
63 |
|
for (i = 0; i < anubis_rc_numsections; i++) |
64 |
|
if (strcmp(anubis_rc_sections[i].name, name) == 0) |
65 |
|
return &anubis_rc_sections[i]; |
66 |
|
|
67 |
|
anubis_rc_sections[anubis_rc_numsections].name = name; |
68 |
|
anubis_rc_sections[anubis_rc_numsections].child = NULL; |
69 |
|
return &anubis_rc_sections[anubis_rc_numsections++]; |
70 |
|
} |
71 |
|
|
72 |
|
RC_SECTION * |
73 |
|
_open_rcfile(int method) |
74 |
{ |
{ |
|
int n; |
|
75 |
char homedir[MAXPATHLEN+1]; |
char homedir[MAXPATHLEN+1]; |
|
char local_rcfile[] = DEFAULT_LOCAL_RCFILE; |
|
76 |
char *rcfile = 0; |
char *rcfile = 0; |
77 |
char *user = 0; |
RC_SECTION *sec; |
|
|
|
|
if (method == SUPERVISOR) |
|
|
user = session.supervisor; |
|
|
else if (method == CLIENT) |
|
|
user = session.client; |
|
|
|
|
|
get_homedir(user, homedir, sizeof(homedir)); |
|
|
n = strlen(homedir) + strlen(local_rcfile) + 2; |
|
|
n = n > MAXPATHLEN ? MAXPATHLEN + 1 : n + 1; |
|
78 |
|
|
79 |
if (method == SUPERVISOR) { |
switch (method) { |
80 |
|
case CF_SUPERVISOR: |
81 |
|
case CF_INIT: |
82 |
if (topt & T_ALTRC) { |
if (topt & T_ALTRC) { |
83 |
if (check_filename(options.altrc) == 0) |
if (check_filename(options.altrc) == 0) |
84 |
return; |
return NULL; |
85 |
rcfile = allocbuf(options.altrc, MAXPATHLEN); |
rcfile = strdup(options.altrc); |
86 |
} |
} else if (check_superuser()) |
87 |
|
rcfile = strdup(DEFAULT_GLOBAL_RCFILE); |
88 |
else { |
else { |
89 |
if (check_superuser()) |
get_homedir(session.supervisor, |
90 |
rcfile = allocbuf(DEFAULT_GLOBAL_RCFILE, MAXPATHLEN); |
homedir, sizeof(homedir)); |
91 |
else { |
rcfile = xmalloc(strlen(homedir) + |
92 |
rcfile = (char *)xmalloc(n); |
strlen(DEFAULT_LOCAL_RCFILE) + 2); |
93 |
#ifdef HAVE_SNPRINTF |
sprintf(rcfile, "%s/%s", homedir, |
94 |
snprintf(rcfile, n - 1, |
DEFAULT_LOCAL_RCFILE); |
95 |
#else |
} |
96 |
sprintf(rcfile, |
info(DEBUG, |
97 |
#endif /* HAVE_SNPRINTF */ |
_("Reading system configuration file %s..."), rcfile); |
98 |
"%s/%s", homedir, local_rcfile); |
break; |
99 |
} |
|
100 |
} |
case CF_CLIENT: |
101 |
} |
get_homedir(session.client, |
102 |
else if (method == CLIENT) { |
homedir, sizeof(homedir)); |
103 |
rcfile = (char *)xmalloc(n); |
rcfile = xmalloc(strlen(homedir) + |
104 |
#ifdef HAVE_SNPRINTF |
strlen(DEFAULT_LOCAL_RCFILE) + 2); |
105 |
snprintf(rcfile, n - 1, |
sprintf(rcfile, "%s/%s", homedir, DEFAULT_LOCAL_RCFILE); |
106 |
#else |
info(DEBUG, |
107 |
sprintf(rcfile, |
_("Reading user configuration file %s..."), rcfile); |
|
#endif /* HAVE_SNPRINTF */ |
|
|
"%s/%s", homedir, local_rcfile); |
|
108 |
} |
} |
109 |
|
|
110 |
if (check_filemode(rcfile) == 0) { /* Wrong permissions... */ |
if (check_filemode(rcfile) == 0) { /* Wrong permissions... */ |
111 |
free(rcfile); |
free(rcfile); |
112 |
return; |
return NULL; |
113 |
} |
} |
114 |
|
|
115 |
if (method == SUPERVISOR) { |
sec = rc_parse(rcfile); |
116 |
struct stat st; |
/* FIXME: |
117 |
if (stat(rcfile, &st) == 0) { |
1) check 'sec' against anubis_rc_sections and remove the |
118 |
if (global_mtime != st.st_mtime) |
erroneous statements |
119 |
global_mtime = st.st_mtime; |
2) rc_section_link(&rc_section, sec); */ |
|
else { |
|
|
free(rcfile); |
|
|
return; |
|
|
} |
|
|
} |
|
|
} |
|
|
fp_rcfile = fopen(rcfile, "r"); |
|
|
if (fp_rcfile == 0) { |
|
|
if (options.termlevel == DEBUG) |
|
|
anubis_error(SOFT, _("Anubis RC file error: %s."), strerror(errno)); |
|
|
} |
|
|
else { |
|
|
if (method == SUPERVISOR) |
|
|
info(DEBUG, _("Reading system configuration file %s..."), rcfile); |
|
|
else if (method == CLIENT) |
|
|
info(DEBUG, _("Reading user configuration file %s..."), rcfile); |
|
|
} |
|
120 |
free(rcfile); |
free(rcfile); |
121 |
return; |
return sec; |
122 |
} |
} |
123 |
|
|
124 |
void |
void |
125 |
read_rcfile(int method) |
open_rcfile(int method) |
126 |
{ |
{ |
127 |
char rcline[LINEBUFFER+1]; |
if (!parse_tree || parse_tree_method != method) { |
128 |
unsigned long rcfile_position = 0; |
RC_SECTION *sec; |
129 |
|
parse_tree_method = method; |
130 |
if (fp_rcfile == 0) |
sec = _open_rcfile(method); |
131 |
return; |
if (sec) |
132 |
|
rc_section_link(&parse_tree, sec); |
|
rcfile_position = get_position(BEGIN_CONTROL); |
|
|
if (rcfile_position == 0) |
|
|
return; |
|
|
else |
|
|
info(DEBUG, _("The %s section has been found. Processing..."), "CONTROL"); |
|
|
|
|
|
fseek(fp_rcfile, rcfile_position, SEEK_SET); |
|
|
while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0) |
|
|
{ |
|
|
if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0) |
|
|
continue; /* skip: an empty line, comment (#) */ |
|
|
else if (strncmp(rcline, END_SECTION, endsection_len) == 0) |
|
|
break; /* THE END */ |
|
|
else |
|
|
match_options_common(method, rcline); |
|
|
} |
|
|
if (!(topt & T_ALLOW_LOCAL_MTA)) |
|
|
topt &= ~T_LOCAL_MTA; |
|
|
|
|
|
if (method >= SUPERVISOR) { |
|
|
rcfile_position = get_position(BEGIN_TRANSLATION); |
|
|
if (rcfile_position == 0) { |
|
|
topt &= ~T_TRANSLATION_MAP; |
|
|
return; |
|
|
} |
|
|
else |
|
|
info(DEBUG, _("The %s section has been found. Processing..."), "TRANSLATION"); |
|
|
|
|
|
destroy_list(&session.transmap); |
|
|
topt |= T_TRANSLATION_MAP; |
|
|
|
|
|
fseek(fp_rcfile, rcfile_position, SEEK_SET); |
|
|
while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0) |
|
|
{ |
|
|
if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0) |
|
|
continue; /* skip: an empty line, comment (#) */ |
|
|
else if (strncmp(rcline, END_SECTION, endsection_len) == 0) |
|
|
break; /* THE END */ |
|
|
else { |
|
|
remcrlf(rcline); |
|
|
session.transmap_tail = new_element(session.transmap_tail, |
|
|
&session.transmap, rcline); |
|
|
} |
|
|
} |
|
133 |
} |
} |
|
return; |
|
134 |
} |
} |
135 |
|
|
136 |
void |
void |
137 |
read_rcfile_allsection(void) |
process_rcfile(int method) |
138 |
{ |
{ |
139 |
char rcline[LINEBUFFER+1]; |
rc_run_section_list(method, parse_tree, anubis_rc_sections); |
|
|
|
|
if (fp_rcfile == 0) |
|
|
return; |
|
|
|
|
|
if (all_position == 0) { |
|
|
all_position = get_position(BEGIN_ALL); |
|
|
if (all_position == 0) |
|
|
return; |
|
|
else |
|
|
info(DEBUG, _("The %s section has been found. Processing..."), "ALL"); |
|
|
} |
|
|
|
|
|
fseek(fp_rcfile, all_position, SEEK_SET); |
|
|
while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0) |
|
|
{ |
|
|
if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0) |
|
|
continue; /* skip: an empty line, comment (#) */ |
|
|
else if (strncmp(rcline, END_SECTION, endsection_len) == 0) |
|
|
break; /* THE END */ |
|
|
else { |
|
|
get_action_line(rcline); |
|
|
match_action(rcline, NULL); |
|
|
} |
|
|
} |
|
|
return; |
|
140 |
} |
} |
141 |
|
|
142 |
#ifdef WITH_GUILE |
/* ************************** The CONTROL Section ************************* */ |
143 |
static void |
#define KW_BIND 0 |
144 |
match_action_guile(char *buf) |
#define KW_TERMLEVEL 1 |
145 |
{ |
#define KW_ALLOW_LOCAL_MTA 2 |
146 |
char *ptr = 0; |
#define KW_ALLOW_NOTPRIVILEGED 3 |
147 |
int optlen; |
#define KW_LOGLEVEL 4 |
148 |
|
#define KW_LOGFILE 5 |
149 |
optlen = optlength(buf); |
#define KW_REMOTE_MTA 6 |
150 |
if (optlen == 0) |
#define KW_LOCAL_MTA 7 |
151 |
return; |
#define KW_ESMTP_AUTH 8 |
152 |
|
#define KW_SOCKS_PROXY 9 |
153 |
/* |
#define KW_SOCKS_V4 10 |
154 |
Guile |
#define KW_SOCKS_AUTH 11 |
|
*/ |
|
|
|
|
|
if (strncmp("guile-output", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(buf); |
|
|
if_empty_quit(ptr); |
|
|
xfree(options.guile_logfile); |
|
|
options.guile_logfile = allocbuf(ptr, MAXPATHLEN); |
|
|
return; |
|
|
} |
|
|
if (strncmp("guile-debug", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(buf); |
|
|
if_empty_quit(ptr); |
|
|
guile_debug(strncmp("yes", ptr, 3) == 0); |
|
|
return; |
|
|
} |
|
|
if (strncmp("guile-load-path-append", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(buf); |
|
|
if_empty_quit(ptr); |
|
|
guile_load_path_append(ptr); |
|
|
return; |
|
|
} |
|
|
if (strncmp("guile-load-program", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(buf); |
|
|
if_empty_quit(ptr); |
|
|
guile_load_program(ptr); |
|
|
return; |
|
|
} |
|
|
if (strncmp("guile-postprocess", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(buf); |
|
|
if_empty_quit(ptr); |
|
|
xfree(options.guile_postprocess); |
|
|
options.guile_postprocess = allocbuf(ptr, MAXPATHLEN); |
|
|
return; |
|
|
} |
|
|
} |
|
155 |
|
|
156 |
void |
int |
157 |
read_rcfile_guile(void) |
control_parser(int method, int key, char *arg, |
158 |
|
void *inv_data, void *func_data, char *line) |
159 |
{ |
{ |
160 |
char rcline[LINEBUFFER+1]; |
switch (key) { |
161 |
|
case KW_BIND: |
162 |
if (fp_rcfile == 0) |
parse_mtahost(arg, session.tunnel, &session.tunnel_port); |
163 |
return; |
if (strlen(session.tunnel) != 0) |
164 |
|
topt |= T_NAMES; |
165 |
if (guile_position == 0) { |
break; |
166 |
guile_position = get_position(BEGIN_GUILE); |
|
167 |
if (guile_position == 0) |
case KW_TERMLEVEL: |
168 |
return; |
if (strcmp("silent", arg) == 0) |
169 |
|
options.termlevel = SILENT; |
170 |
|
else if (strcmp("normal", arg) == 0) |
171 |
|
options.termlevel = NORMAL; |
172 |
|
else if (strcmp("verbose", arg) == 0) |
173 |
|
options.termlevel = VERBOSE; |
174 |
|
else if (strcmp("debug", arg) == 0) |
175 |
|
options.termlevel = DEBUG; |
176 |
else |
else |
177 |
info(DEBUG, _("The %s section has been found. Processing..."), "GUILE"); |
return RC_KW_ERROR; |
178 |
} |
break; |
179 |
|
|
180 |
|
case KW_ALLOW_LOCAL_MTA: |
181 |
|
setbool(arg, topt, T_ALLOW_LOCAL_MTA); |
182 |
|
break; |
183 |
|
|
184 |
|
case KW_ALLOW_NOTPRIVILEGED: |
185 |
|
safe_strcpy(session.notprivileged, arg); |
186 |
|
break; |
187 |
|
|
188 |
fseek(fp_rcfile, guile_position, SEEK_SET); |
case KW_LOGFILE: |
189 |
while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0) |
if (method & (CF_SUPERVISOR|CF_INIT)) { |
|
{ |
|
|
if (strncmp(rcline, "#", 1) == 0 |
|
|
|| strncmp(rcline, LF, 1) == 0) |
|
|
continue; /* skip: an empty line, comment (#) */ |
|
|
else if (strncmp(rcline, END_SECTION, endsection_len) == 0) |
|
|
break; /* THE END */ |
|
|
else { |
|
|
get_action_line(rcline); |
|
|
match_action_guile(rcline); |
|
|
} |
|
|
} |
|
|
return; |
|
|
} |
|
|
#endif /* WITH_GUILE */ |
|
|
|
|
|
void |
|
|
close_rcfile(void) |
|
|
{ |
|
|
if (fp_rcfile == 0) |
|
|
return; |
|
|
if (fclose(fp_rcfile) != 0) |
|
|
anubis_error(SOFT, _("Fatal fclose() error. %s."), strerror(errno)); |
|
|
fp_rcfile = 0; |
|
|
return; |
|
|
} |
|
|
|
|
|
char * |
|
|
parse_line_option(char *line) |
|
|
{ |
|
|
char *ptr = 0; |
|
|
ptr = strchr(line, '='); |
|
|
|
|
|
if (ptr == 0) |
|
|
return line; |
|
|
do { |
|
|
ptr++; |
|
|
} while (*ptr == ' ' || *ptr == '\t'); |
|
|
|
|
|
remcrlf(ptr); |
|
|
return ptr; |
|
|
} |
|
|
|
|
|
static int |
|
|
optlength(char *p) |
|
|
{ |
|
|
register int n = 0; |
|
|
while (*p != ' ' && *p != '\t' && *p != '=') |
|
|
{ |
|
|
n++; |
|
|
p++; |
|
|
} |
|
|
return n; |
|
|
} |
|
|
|
|
|
static void |
|
|
match_options_common(int method, char *rcline) |
|
|
{ |
|
|
char *ptr = 0; |
|
|
char buf[LINEBUFFER+1]; |
|
|
int optlen; |
|
|
|
|
|
safe_strcpy(buf, rcline); |
|
|
change_to_lower(buf); |
|
|
optlen = optlength(buf); |
|
|
if (optlen == 0) |
|
|
return; |
|
|
|
|
|
if (method == INIT) { |
|
|
if (strncmp("bind", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
|
parse_mtahost(ptr, session.tunnel, &session.tunnel_port); |
|
|
if (strlen(session.tunnel) != 0) |
|
|
topt |= T_NAMES; |
|
|
return; |
|
|
} |
|
|
} |
|
|
if (method >= SUPERVISOR) { |
|
|
if (strncmp("termlevel", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(buf); |
|
|
if ((optlen = strlen(ptr)) == 0) |
|
|
return; |
|
|
if (strncmp("silent", ptr, optlen) == 0) |
|
|
options.termlevel = SILENT; |
|
|
else if (strncmp("normal", ptr, optlen) == 0) |
|
|
options.termlevel = NORMAL; |
|
|
else if (strncmp("verbose", ptr, optlen) == 0) |
|
|
options.termlevel = VERBOSE; |
|
|
else if (strncmp("debug", ptr, optlen) == 0) |
|
|
options.termlevel = DEBUG; |
|
|
return; |
|
|
} |
|
|
if (strncmp("allow-local-mta", buf, optlen) == 0) { |
|
|
set(parse_line_option(buf), topt, T_ALLOW_LOCAL_MTA); |
|
|
} |
|
|
if (strncmp("user-notprivileged", buf, optlen) == 0) { |
|
|
safe_strcpy(session.notprivileged, parse_line_option(rcline)); |
|
|
if_empty_set(session.notprivileged, topt, T_USER_NOTPRIVIL); |
|
|
} |
|
|
} |
|
|
if (strncmp("logfile", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
|
|
|
|
if (method >= SUPERVISOR) { |
|
190 |
xfree(options.slogfile); |
xfree(options.slogfile); |
191 |
options.slogfile = allocbuf(ptr, MAXPATHLEN); |
options.slogfile = allocbuf(arg, MAXPATHLEN); |
192 |
return; |
} else if (method == CF_CLIENT) { |
|
} |
|
|
if (method == CLIENT) { |
|
193 |
xfree(options.ulogfile); |
xfree(options.ulogfile); |
194 |
options.ulogfile = allocbuf(ptr, MAXPATHLEN); |
options.ulogfile = allocbuf(arg, MAXPATHLEN); |
|
return; |
|
|
} |
|
|
return; |
|
|
} |
|
|
if (method == CLIENT) { |
|
|
if (strncmp("loglevel", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(buf); |
|
|
if ((optlen = strlen(ptr)) == 0) |
|
|
return; |
|
|
if (strncmp("none", ptr, optlen) == 0) |
|
|
options.uloglevel = NONE; |
|
|
else if (strncmp("all", ptr, optlen) == 0) |
|
|
options.uloglevel = ALL; |
|
|
else if (strncmp("fails", ptr, optlen) == 0) |
|
|
options.uloglevel = FAILS; |
|
|
return; |
|
195 |
} |
} |
196 |
} |
break; |
197 |
if (strncmp("remote-mta", buf, optlen) == 0) { |
|
198 |
ptr = parse_line_option(rcline); |
case KW_LOGLEVEL: |
199 |
if_empty_quit(ptr); |
if (strcmp("none", arg) == 0) |
200 |
parse_mtaport(ptr, session.mta, &session.mta_port); |
options.uloglevel = NONE; |
201 |
return; |
else if (strcmp("all", arg) == 0) |
202 |
} |
options.uloglevel = ALL; |
203 |
if (strncmp("local-mta", buf, optlen) == 0) { |
else if (strcmp("fails", arg) == 0) |
204 |
|
options.uloglevel = FAILS; |
205 |
|
else |
206 |
|
return RC_KW_ERROR; |
207 |
|
break; |
208 |
|
|
209 |
|
case KW_REMOTE_MTA: |
210 |
|
parse_mtaport(arg, session.mta, &session.mta_port); |
211 |
|
break; |
212 |
|
|
213 |
|
case KW_LOCAL_MTA: { |
214 |
char *a = 0; |
char *a = 0; |
215 |
char *p = 0; |
char *p = 0; |
216 |
char tmp[LINEBUFFER+1]; |
char tmp[LINEBUFFER+1]; |
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
217 |
|
|
218 |
a = strchr(ptr, ' '); /* an extra arguments */ |
a = strchr(arg, ' '); /* an extra arguments */ |
219 |
if (a) { |
if (a) { |
220 |
*a++ = '\0'; |
*a++ = '\0'; |
221 |
p = strrchr(ptr, '/'); |
p = strrchr(arg, '/'); |
222 |
if (p) |
if (p) |
223 |
p++; |
p++; |
224 |
else |
else |
225 |
p = ptr; |
p = arg; |
226 |
#ifdef HAVE_SNPRINTF |
snprintf(tmp, sizeof(tmp), "%s %s", p, a); |
227 |
snprintf(tmp, LINEBUFFER, |
p = arg; |
|
#else |
|
|
sprintf(tmp, |
|
|
#endif /* HAVE_SNPRINTF */ |
|
|
"%s %s", p, a); |
|
|
p = ptr; |
|
228 |
a = tmp; |
a = tmp; |
229 |
} |
} else { /* no arguments */ |
230 |
else { /* no arguments */ |
p = arg; |
231 |
p = ptr; |
a = strrchr(arg, '/'); |
|
a = strrchr(ptr, '/'); |
|
232 |
if (a) |
if (a) |
233 |
a++; |
a++; |
234 |
else |
else |
235 |
a = ptr; |
a = arg; |
236 |
} |
} |
237 |
xfree(session.execpath); |
xfree(session.execpath); |
238 |
session.execpath = allocbuf(p, MAXPATHLEN); |
session.execpath = allocbuf(p, MAXPATHLEN); |
243 |
} |
} |
244 |
session.execargs = gen_execargs(a); |
session.execargs = gen_execargs(a); |
245 |
topt |= T_RCEXECARGS; |
topt |= T_RCEXECARGS; |
|
return; |
|
246 |
} |
} |
247 |
if (strncmp("esmtp-auth", buf, optlen) == 0) { |
break; |
248 |
char *p = 0; |
|
249 |
ptr = parse_line_option(rcline); |
case KW_ESMTP_AUTH: { |
250 |
if_empty_quit(ptr); |
char *p = strchr(arg, ':'); |
|
p = strchr(ptr, ':'); |
|
251 |
if (p) { |
if (p) { |
252 |
safe_strcpy(session.mta_password, ++p); |
safe_strcpy(session.mta_password, ++p); |
253 |
*--p = '\0'; |
*--p = '\0'; |
254 |
safe_strcpy(session.mta_username, ptr); |
safe_strcpy(session.mta_username, arg); |
255 |
topt |= T_ESMTP_AUTH; |
topt |= T_ESMTP_AUTH; |
256 |
} |
} |
257 |
return; |
} |
258 |
} |
break; |
259 |
|
|
260 |
/* |
case KW_SOCKS_PROXY: |
261 |
Proxies. |
parse_mtaport(arg, session.socks, &session.socks_port); |
|
*/ |
|
|
|
|
|
if (strncmp("socks-proxy", buf, optlen) == 0) { |
|
|
parse_mtaport(parse_line_option(rcline), session.socks, |
|
|
&session.socks_port); |
|
262 |
if_empty_set(session.socks, topt, T_SOCKS); |
if_empty_set(session.socks, topt, T_SOCKS); |
263 |
} |
break; |
264 |
if (strncmp("socks-v4", buf, optlen) == 0) { |
|
265 |
set(parse_line_option(buf), topt, T_SOCKS_V4); |
case KW_SOCKS_V4: |
266 |
} |
setbool(arg, topt, T_SOCKS_V4); |
267 |
if (strncmp("socks-auth", buf, optlen) == 0) { |
break; |
268 |
|
|
269 |
|
case KW_SOCKS_AUTH: { |
270 |
char *p = 0; |
char *p = 0; |
271 |
ptr = parse_line_option(rcline); |
p = strchr(arg, ':'); |
|
if_empty_quit(ptr); |
|
|
p = strchr(ptr, ':'); |
|
272 |
if (p) { |
if (p) { |
273 |
safe_strcpy(session.socks_password, ++p); |
safe_strcpy(session.socks_password, ++p); |
274 |
*--p = '\0'; |
*--p = '\0'; |
275 |
safe_strcpy(session.socks_username, ptr); |
safe_strcpy(session.socks_username, arg); |
276 |
topt |= T_SOCKS_AUTH; |
topt |= T_SOCKS_AUTH; |
277 |
} |
} |
278 |
return; |
break; |
279 |
|
} |
280 |
|
|
281 |
|
default: |
282 |
|
return RC_KW_UNKNOWN; |
283 |
} |
} |
284 |
|
return RC_KW_HANDLED; |
285 |
|
} |
286 |
|
|
287 |
/* |
static struct rc_kwdef init_kw[] = { |
288 |
TLS/SSL. |
{ "bind", KW_BIND }, |
289 |
*/ |
{ NULL }, |
290 |
|
}; |
291 |
|
|
292 |
|
static struct rc_secdef_child init_sect_child = { |
293 |
|
NULL, |
294 |
|
CF_INIT, |
295 |
|
init_kw, |
296 |
|
control_parser, |
297 |
|
NULL |
298 |
|
}; |
299 |
|
|
300 |
|
static struct rc_kwdef init_supervisor_kw[] = { |
301 |
|
{ "termlevel", KW_TERMLEVEL }, |
302 |
|
{ "allow-local-mta", KW_ALLOW_LOCAL_MTA }, |
303 |
|
{ "user-notprivileged", KW_ALLOW_NOTPRIVILEGED }, |
304 |
|
{ NULL } |
305 |
|
}; |
306 |
|
|
307 |
|
static struct rc_secdef_child init_supervisor_sect_child = { |
308 |
|
NULL, |
309 |
|
CF_INIT|CF_SUPERVISOR, |
310 |
|
init_supervisor_kw, |
311 |
|
control_parser, |
312 |
|
NULL |
313 |
|
}; |
314 |
|
|
315 |
|
struct rc_kwdef client_kw[] = { |
316 |
|
{ "loglevel", KW_LOGLEVEL }, |
317 |
|
{ NULL }, |
318 |
|
}; |
319 |
|
|
320 |
|
static struct rc_secdef_child client_sect_child = { |
321 |
|
NULL, |
322 |
|
CF_CLIENT, |
323 |
|
client_kw, |
324 |
|
control_parser, |
325 |
|
NULL |
326 |
|
}; |
327 |
|
|
328 |
|
struct rc_kwdef control_kw[] = { |
329 |
|
{ "logfile", KW_LOGFILE }, |
330 |
|
{ "remote-mta", KW_REMOTE_MTA }, |
331 |
|
{ "local-mta", KW_LOCAL_MTA }, |
332 |
|
{ "esmtp-auth", KW_ESMTP_AUTH }, |
333 |
|
{ "socks-proxy", KW_SOCKS_PROXY }, |
334 |
|
{ "socks-v4", KW_SOCKS_V4 }, |
335 |
|
{ "socks-auth", KW_SOCKS_AUTH }, |
336 |
|
{ NULL }, |
337 |
|
}; |
338 |
|
|
339 |
|
static struct rc_secdef_child control_sect_child = { |
340 |
|
NULL, |
341 |
|
CF_ALL, |
342 |
|
control_kw, |
343 |
|
control_parser, |
344 |
|
NULL |
345 |
|
}; |
346 |
|
|
347 |
|
/* FIXME: This belongs to another file */ |
348 |
#if defined(HAVE_TLS) || defined(HAVE_SSL) |
#if defined(HAVE_TLS) || defined(HAVE_SSL) |
349 |
if (strncmp("ssl", buf, optlen) == 0) { |
#define KW_SSL 1 |
350 |
set(parse_line_option(buf), topt, T_SSL); |
#define KW_ONEWAY_SSL 2 |
351 |
} |
#define KW_CERT 3 |
352 |
if (strncmp("oneway-ssl", buf, optlen) == 0) { |
#define KW_KEY 4 |
353 |
set(parse_line_option(buf), topt, T_SSL_ONEWAY); |
#define KW_CAFILE 5 |
354 |
} |
|
355 |
if (strncmp("cert", buf, optlen) == 0) { |
int |
356 |
ptr = parse_line_option(rcline); |
tls_parser(int method, int key, char *arg, |
357 |
if_empty_quit(ptr); |
void *inv_data, void *func_data, char *line) |
358 |
|
{ |
359 |
|
switch (key) { |
360 |
|
case KW_SSL: |
361 |
|
setbool(arg, topt, T_SSL); |
362 |
|
break; |
363 |
|
|
364 |
|
case KW_ONEWAY_SSL: |
365 |
|
setbool(arg, topt, T_SSL_ONEWAY); |
366 |
|
break; |
367 |
|
|
368 |
|
case KW_CERT: |
369 |
xfree(secure.cert); |
xfree(secure.cert); |
370 |
secure.cert = allocbuf(ptr, MAXPATHLEN); |
secure.cert = allocbuf(arg, MAXPATHLEN); |
371 |
if (method == CLIENT) |
if (method == CF_CLIENT) |
372 |
topt |= T_SSL_CKCLIENT; |
topt |= T_SSL_CKCLIENT; |
373 |
return; |
break; |
374 |
} |
|
375 |
if (strncmp("key", buf, optlen) == 0) { |
case KW_KEY: |
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
376 |
xfree(secure.key); |
xfree(secure.key); |
377 |
secure.key = allocbuf(ptr, MAXPATHLEN); |
secure.key = allocbuf(arg, MAXPATHLEN); |
378 |
if (method == CLIENT) |
if (method == CF_CLIENT) |
379 |
topt |= T_SSL_CKCLIENT; |
topt |= T_SSL_CKCLIENT; |
380 |
return; |
break; |
381 |
} |
|
382 |
if (strncmp("cafile", buf, optlen) == 0) { |
case KW_CAFILE: |
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
383 |
xfree(secure.cafile); |
xfree(secure.cafile); |
384 |
secure.cafile = allocbuf(ptr, MAXPATHLEN); |
secure.cafile = allocbuf(arg, MAXPATHLEN); |
385 |
return; |
break; |
386 |
} |
|
387 |
#endif /* HAVE_TLS or HAVE_SSL */ |
default: |
388 |
|
return RC_KW_UNKNOWN; |
389 |
return; |
} |
390 |
} |
return RC_KW_HANDLED; |
391 |
|
} |
392 |
|
|
393 |
|
static struct rc_kwdef tls_kw[] = { |
394 |
|
{ "ssl", KW_SSL }, |
395 |
|
{ "oneway-ssl", KW_ONEWAY_SSL }, |
396 |
|
{ "cert", KW_CERT }, |
397 |
|
{ "key", KW_KEY }, |
398 |
|
{ "cafile", KW_CAFILE }, |
399 |
|
{ NULL } |
400 |
|
}; |
401 |
|
|
402 |
|
static struct rc_secdef_child tls_sect_child = { |
403 |
|
NULL, |
404 |
|
CF_ALL, |
405 |
|
tls_kw, |
406 |
|
tls_parser, |
407 |
|
NULL |
408 |
|
}; |
409 |
|
#endif |
410 |
|
|
411 |
int |
void |
412 |
read_regex_block(int method, char *regex, int size) |
control_section_init() |
|
{ |
|
|
char rcline[LINEBUFFER+1]; |
|
|
|
|
|
if (fp_rcfile == 0) |
|
|
return 0; |
|
|
|
|
|
while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0) |
|
|
{ |
|
|
if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0) |
|
|
continue; /* skip: an empty line, comment (#) */ |
|
|
else if (strncmp(rcline, END_SECTION, endsection_len) == 0) |
|
|
break; /* END OF REGEX BLOCK */ |
|
|
else { |
|
|
if (get_regex(method, rcline, regex, size) == 0) |
|
|
continue; |
|
|
else |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
static int |
|
|
get_regex(int method, char *rcline, char *regex, int size) |
|
413 |
{ |
{ |
414 |
char *ptr = 0; |
struct rc_secdef *sp = anubis_add_section("CONTROL"); |
415 |
int rs = 0; |
rc_secdef_add_child(sp, &init_sect_child); |
416 |
|
rc_secdef_add_child(sp, &init_supervisor_sect_child); |
417 |
if (method == HEADER) { /* "IF HEADER =..." */ |
rc_secdef_add_child(sp, &client_sect_child); |
418 |
rs = regex_match("[ \t]*if[ \t]+header.*=", rcline); |
rc_secdef_add_child(sp, &control_sect_child); |
419 |
if (rs == 0) |
#if defined(HAVE_TLS) || defined(HAVE_SSL) |
420 |
rs = regex_match("[ \t]*rule.*=", rcline); |
rc_secdef_add_child(sp, &tls_sect_child); |
421 |
} |
#endif |
|
else if (method == COMMAND) { /* "IF COMMAND =..." */ |
|
|
rs = regex_match("[ \t]*if[ \t]+command.*=", rcline); |
|
|
} |
|
|
if (rs == 0) |
|
|
return 0; |
|
|
ptr = parse_line_regex(rcline); |
|
|
if (strlen(ptr) == 0) |
|
|
return 0; |
|
|
strncpy(regex, ptr, size); |
|
|
return 1; |
|
|
} |
|
|
|
|
|
static char * |
|
|
parse_line_regex(char *rcline) |
|
|
{ |
|
|
char *ptr = 0; |
|
|
char *optptr = 0; |
|
|
int len; |
|
|
char optbuf[LINEBUFFER+1]; |
|
|
memset(optbuf, 0, LINEBUFFER + 1); |
|
|
|
|
|
ptr = strchr(rcline, '='); |
|
|
if (ptr == 0) |
|
|
return rcline; |
|
|
|
|
|
len = strlen(rcline); |
|
|
len -= strlen(ptr); |
|
|
strncpy(optbuf, rcline, len); |
|
|
|
|
|
optptr = strchr(optbuf, ':'); /* additional options */ |
|
|
if (optptr) { |
|
|
optptr++; |
|
|
change_to_lower(optptr); |
|
|
if (strstr(optptr, "basic")) |
|
|
ropt |= R_BASIC; |
|
|
if (strstr(optptr, "scase")) |
|
|
ropt |= R_SCASE; |
|
|
#ifdef HAVE_PCRE |
|
|
if (strstr(optptr, "perlre")) |
|
|
ropt |= R_PERLRE; |
|
|
#endif /* HAVE_PCRE */ |
|
|
} |
|
|
else |
|
|
ropt = 0; |
|
|
ptr++; |
|
|
remcrlf(ptr); |
|
|
return ptr; |
|
422 |
} |
} |
423 |
|
|
424 |
/********************* |
/* ********************** The ALL and RULE Sections *********************** */ |
425 |
Read an ACTION-BLOCK |
#define KW_ADD 1 |
426 |
**********************/ |
#define KW_REMOVE 2 |
427 |
|
#define KW_MODIFY 3 |
428 |
|
#define KW_SIGNATURE_FILE_APPEND 4 |
429 |
|
#define KW_BODY_APPEND 5 |
430 |
|
#define KW_BODY_CLEAR_APPEND 6 |
431 |
|
#define KW_ROT13_SUBJECT 7 |
432 |
|
#define KW_ROT13_BODY 8 |
433 |
|
#define KW_RM_RRT 9 |
434 |
|
#define KW_RM_POST 10 |
435 |
|
#define KW_RM_HEADER 11 |
436 |
|
#define KW_RM_LT 12 |
437 |
|
#define KW_RM_RLT 13 |
438 |
|
#define KW_EXTERNAL_BODY_PROCESSOR 14 |
439 |
|
|
440 |
int |
int |
441 |
read_action_block(const char *source_line) |
all_parser(int method, int key, char *arg, |
442 |
{ |
void *inv_data, void *func_data, char *line) |
|
char rcline[LINEBUFFER+1]; |
|
|
|
|
|
if (fp_rcfile == 0) |
|
|
return 0; |
|
|
|
|
|
while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0) |
|
|
{ |
|
|
if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0) |
|
|
continue; /* skip: an empty line, comment (#) */ |
|
|
else if (regex_match("[ \t]*(done|fi)[^0-9A-Za-z][ \t]*", rcline)) |
|
|
break; /* 'fi' - END OF REGEX BLOCK ACTION */ |
|
|
else { |
|
|
get_action_line(rcline); |
|
|
match_action(rcline, source_line); |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
static void |
|
|
get_action_line(char *rcline) |
|
|
{ |
|
|
char *ptr = 0; |
|
|
char buf[LINEBUFFER+1]; |
|
|
|
|
|
safe_strcpy(buf, rcline); |
|
|
ptr = buf; |
|
|
while (*ptr == ' ' || *ptr == '\t') |
|
|
ptr++; |
|
|
|
|
|
remcrlf(ptr); |
|
|
strncpy(rcline, ptr, LINEBUFFER); |
|
|
return; |
|
|
} |
|
|
|
|
|
static void |
|
|
match_action(char *rcline, const char *source_line) |
|
443 |
{ |
{ |
444 |
char *ptr = 0; |
switch (key) { |
445 |
char *outbuf = 0; |
case KW_ADD: |
|
char buf[LINEBUFFER+1]; |
|
|
int optlen; |
|
|
|
|
|
outbuf = substitute(rcline, submatch); |
|
|
if (outbuf) { |
|
|
strncpy(rcline, outbuf, LINEBUFFER); |
|
|
free(outbuf); |
|
|
} |
|
|
safe_strcpy(buf, rcline); |
|
|
change_to_lower(buf); |
|
|
optlen = optlength(buf); |
|
|
if (optlen == 0) |
|
|
return; |
|
|
|
|
|
if (strncmp("add", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
446 |
message.addlist_tail = new_element(message.addlist_tail, |
message.addlist_tail = new_element(message.addlist_tail, |
447 |
&message.addlist, ptr); |
&message.addlist, arg); |
448 |
return; |
break; |
449 |
} |
|
450 |
if (strncmp("remove", buf, optlen) == 0) { |
case KW_REMOVE: |
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
451 |
message.remlist_tail = new_element(message.remlist_tail, |
message.remlist_tail = new_element(message.remlist_tail, |
452 |
&message.remlist, ptr); |
&message.remlist, arg); |
453 |
return; |
break; |
454 |
} |
|
455 |
if (strncmp("modify", buf, optlen) == 0) { |
case KW_MODIFY: { |
456 |
char *p = 0; |
char *p = 0; |
457 |
char modify[LINEBUFFER+1]; |
char modify[LINEBUFFER+1]; |
458 |
ptr = parse_line_option(rcline); |
|
459 |
if_empty_quit(ptr); |
p = strstr(arg, " >> "); /* "SPC>>SPC" is a separator */ |
|
p = strstr(ptr, " >> "); /* "SPC>>SPC" is a separator */ |
|
460 |
if (p) { |
if (p) { |
461 |
p += 4; |
p += 4; |
462 |
strncpy(modify, p, LINEBUFFER-2); |
strncpy(modify, p, LINEBUFFER-2); |
463 |
strcat(modify, CRLF); |
strcat(modify, CRLF); |
464 |
p -= 4; |
p -= 4; |
465 |
*p = '\0'; |
*p = '\0'; |
466 |
message.modlist_tail = new_element(message.modlist_tail, |
message.modlist_tail = |
467 |
&message.modlist, ptr); |
new_element(message.modlist_tail, |
468 |
|
&message.modlist, arg); |
469 |
message.modlist_tail->modify = strdup(modify); |
message.modlist_tail->modify = strdup(modify); |
470 |
} |
} |
|
return; |
|
|
} |
|
|
if (strncmp("rot13-subject", buf, optlen) == 0) { |
|
|
set(parse_line_option(buf), mopt, M_ROT13S); |
|
|
} |
|
|
if (strncmp("rot13-body", buf, optlen) == 0) { |
|
|
set(parse_line_option(buf), mopt, M_ROT13B); |
|
471 |
} |
} |
472 |
if (strncmp("signature-file-append", buf, optlen) == 0) { |
break; |
473 |
set(parse_line_option(buf), mopt, M_SIGNATURE); |
|
474 |
} |
case KW_SIGNATURE_FILE_APPEND: |
475 |
if (strncmp("body-clear-append", buf, optlen) == 0) { |
setbool(arg, mopt, M_SIGNATURE); |
476 |
ptr = parse_line_option(rcline); |
break; |
477 |
if_empty_quit(ptr); |
|
478 |
|
case KW_BODY_APPEND: |
479 |
xfree(message.body_append); |
xfree(message.body_append); |
480 |
message.body_append = allocbuf(ptr, MAXPATHLEN); |
message.body_append = allocbuf(arg, MAXPATHLEN); |
481 |
mopt |= M_BODYAPPEND; |
mopt |= M_BODYAPPEND; |
482 |
mopt |= M_BODYCLEARAPPEND; |
mopt &= ~M_BODYCLEARAPPEND; |
483 |
return; |
break; |
484 |
} |
|
485 |
if (strncmp("body-append", buf, optlen) == 0) { |
case KW_BODY_CLEAR_APPEND: |
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
486 |
xfree(message.body_append); |
xfree(message.body_append); |
487 |
message.body_append = allocbuf(ptr, MAXPATHLEN); |
message.body_append = allocbuf(arg, MAXPATHLEN); |
488 |
mopt |= M_BODYAPPEND; |
mopt |= M_BODYAPPEND; |
489 |
mopt &= ~M_BODYCLEARAPPEND; |
mopt |= M_BODYCLEARAPPEND; |
490 |
return; |
break; |
491 |
} |
|
492 |
if (strncmp("external-body-processor", buf, optlen) == 0) { |
case KW_ROT13_SUBJECT: |
493 |
ptr = parse_line_option(rcline); |
setbool(arg, mopt, M_ROT13S); |
494 |
if_empty_quit(ptr); |
break; |
495 |
|
|
496 |
|
case KW_ROT13_BODY: |
497 |
|
setbool(arg, mopt, M_ROT13B); |
498 |
|
break; |
499 |
|
|
500 |
|
case KW_RM_RRT: |
501 |
|
xfree(rm.rrt); |
502 |
|
rm.rrt = allocbuf(arg, 0); |
503 |
|
mopt |= M_RM; |
504 |
|
mopt |= M_RMRRT; |
505 |
|
break; |
506 |
|
|
507 |
|
case KW_RM_POST: |
508 |
|
xfree(rm.post); |
509 |
|
rm.post = allocbuf(arg, 0); |
510 |
|
mopt |= M_RM; |
511 |
|
mopt |= M_RMPOST; |
512 |
|
break; |
513 |
|
|
514 |
|
case KW_RM_HEADER: |
515 |
|
xfree(rm.header); |
516 |
|
rm.header = allocbuf(arg, LINEBUFFER + 1); |
517 |
|
mopt |= M_RMHEADER; |
518 |
|
break; |
519 |
|
|
520 |
|
case KW_RM_LT: |
521 |
|
xfree(rm.latent_time); |
522 |
|
rm.latent_time = allocbuf(arg, 16); |
523 |
|
mopt |= M_RMLT; |
524 |
|
break; |
525 |
|
|
526 |
|
case KW_RM_RLT: |
527 |
|
xfree(rm.latent_time); |
528 |
|
rm.latent_time = allocbuf(arg, 16); |
529 |
|
mopt |= M_RMLT; |
530 |
|
break; |
531 |
|
|
532 |
|
case KW_EXTERNAL_BODY_PROCESSOR: |
533 |
xfree(message.exteditor); |
xfree(message.exteditor); |
534 |
message.exteditor = allocbuf(ptr, MAXPATHLEN); |
message.exteditor = allocbuf(arg, MAXPATHLEN); |
535 |
mopt |= M_EXTBODYPROC; |
mopt |= M_EXTBODYPROC; |
536 |
return; |
break; |
537 |
} |
|
538 |
|
default: |
539 |
|
return RC_KW_UNKNOWN; |
540 |
|
} |
541 |
|
return RC_KW_HANDLED; |
542 |
|
} |
543 |
|
|
544 |
|
struct rc_kwdef all_kw[] = { |
545 |
|
{ "add", KW_ADD }, |
546 |
|
{ "remove", KW_REMOVE }, |
547 |
|
{ "modify", KW_MODIFY }, |
548 |
|
{ "signature-file-append", KW_SIGNATURE_FILE_APPEND }, |
549 |
|
{ "body-append", KW_BODY_APPEND }, |
550 |
|
{ "body-clear-append", KW_BODY_CLEAR_APPEND }, |
551 |
|
{ "rot13-subject", KW_ROT13_SUBJECT }, |
552 |
|
{ "rot13-body", KW_ROT13_BODY }, |
553 |
|
{ "rm-rrt", KW_RM_RRT }, |
554 |
|
{ "rm-post", KW_RM_POST }, |
555 |
|
{ "rm-header", KW_RM_HEADER }, |
556 |
|
{ "rm-lt", KW_RM_LT }, |
557 |
|
{ "rm-rlt", KW_RM_RLT }, |
558 |
|
{ "external-body-processor", KW_EXTERNAL_BODY_PROCESSOR }, |
559 |
|
{ NULL } |
560 |
|
}; |
561 |
|
|
562 |
|
static struct rc_secdef_child all_sect_child = { |
563 |
|
NULL, |
564 |
|
CF_CLIENT, |
565 |
|
all_kw, |
566 |
|
all_parser, |
567 |
|
NULL |
568 |
|
}; |
569 |
|
|
570 |
|
|
|
/* |
|
|
GnuPG support. |
|
|
*/ |
|
571 |
|
|
572 |
#ifdef HAVE_GPG |
#ifdef HAVE_GPG |
573 |
if (strncmp("gpg-passphrase", buf, optlen) == 0) { |
#define KW_GPG_PASSPHRASE 1 |
574 |
ptr = parse_line_option(rcline); |
#define KW_GPG_ENCRYPT 2 |
575 |
if_empty_quit(ptr); |
#define KW_GPG_SIGN 3 |
576 |
|
#define KW_RM_GPG 4 |
577 |
|
|
578 |
|
int |
579 |
|
gpg_parser(int method, int key, char *arg, |
580 |
|
void *inv_data, void *func_data, char *line) |
581 |
|
{ |
582 |
|
switch (key) { |
583 |
|
case KW_GPG_PASSPHRASE: |
584 |
if (gpg.passphrase) { |
if (gpg.passphrase) { |
585 |
memset(gpg.passphrase, 0, strlen(gpg.passphrase)); |
memset(gpg.passphrase, 0, strlen(gpg.passphrase)); |
586 |
xfree(gpg.passphrase); |
xfree(gpg.passphrase); |
587 |
} |
} |
588 |
gpg.passphrase = allocbuf(ptr, 0); |
gpg.passphrase = allocbuf(arg, 0); |
589 |
mopt |= M_GPG_PASSPHRASE; |
mopt |= M_GPG_PASSPHRASE; |
590 |
return; |
break; |
591 |
} |
|
592 |
if (strncmp("gpg-encrypt", buf, optlen) == 0) { |
case KW_GPG_ENCRYPT: |
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
593 |
xfree(gpg.keys); |
xfree(gpg.keys); |
594 |
gpg.keys = allocbuf(ptr, 0); |
gpg.keys = allocbuf(arg, 0); |
595 |
gpg.keys = (char *)xrealloc((char *)gpg.keys, strlen(gpg.keys) + 2); |
gpg.keys = xrealloc(gpg.keys, strlen(gpg.keys) + 2); |
596 |
strcat(gpg.keys, ","); |
strcat(gpg.keys, ","); |
597 |
mopt |= M_GPG_ENCRYPT; |
mopt |= M_GPG_ENCRYPT; |
598 |
return; |
break; |
599 |
} |
|
600 |
if (strncmp("gpg-sign", buf, optlen) == 0) { |
case KW_GPG_SIGN: |
601 |
ptr = parse_line_option(rcline); |
if (strcmp(arg, "yes") == 0 |
602 |
if_empty_quit(ptr); |
|| (mopt & M_GPG_PASSPHRASE) == 0) { |
|
if (regex_match("yes", ptr) == 0 |
|
|
|| (mopt & M_GPG_PASSPHRASE) == 0) { |
|
603 |
if (gpg.passphrase) { |
if (gpg.passphrase) { |
604 |
memset(gpg.passphrase, 0, strlen(gpg.passphrase)); |
memset(gpg.passphrase, 0, |
605 |
|
strlen(gpg.passphrase)); |
606 |
xfree(gpg.passphrase); |
xfree(gpg.passphrase); |
607 |
} |
} |
608 |
gpg.passphrase = allocbuf(ptr, 0); |
gpg.passphrase = allocbuf(arg, 0); |
609 |
} |
} |
610 |
mopt |= M_GPG_SIGN; |
mopt |= M_GPG_SIGN; |
611 |
return; |
break; |
612 |
} |
|
613 |
#endif /* HAVE_GPG */ |
case KW_RM_GPG: |
|
|
|
|
/* |
|
|
Guile support |
|
|
*/ |
|
|
#ifdef WITH_GUILE |
|
|
if (strncmp("guile-rewrite-line", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
|
guile_rewrite_line(ptr, source_line); |
|
|
return; |
|
|
} |
|
|
#endif /* WITH_GUILE */ |
|
|
|
|
|
/* |
|
|
Remailer Type-I support. |
|
|
*/ |
|
|
|
|
|
if (strncmp("rm-rrt", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
|
xfree(rm.rrt); |
|
|
rm.rrt = allocbuf(ptr, 0); |
|
|
mopt |= M_RM; |
|
|
mopt |= M_RMRRT; |
|
|
return; |
|
|
} |
|
|
if (strncmp("rm-post", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
|
xfree(rm.post); |
|
|
rm.post = allocbuf(ptr, 0); |
|
|
mopt |= M_RM; |
|
|
mopt |= M_RMPOST; |
|
|
return; |
|
|
} |
|
|
#ifdef HAVE_GPG |
|
|
if (strncmp("rm-gpg", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
614 |
xfree(gpg.rm_key); |
xfree(gpg.rm_key); |
615 |
gpg.rm_key = allocbuf(ptr, 0); |
gpg.rm_key = allocbuf(arg, 0); |
616 |
mopt |= M_RMGPG; |
mopt |= M_RMGPG; |
617 |
return; |
break; |
618 |
} |
|
619 |
#endif /* HAVE_GPG */ |
default: |
620 |
if (strncmp("rm-header", buf, optlen) == 0) { |
return RC_KW_UNKNOWN; |
621 |
ptr = parse_line_option(rcline); |
} |
622 |
if_empty_quit(ptr); |
return RC_KW_HANDLED; |
|
xfree(rm.header); |
|
|
rm.header = allocbuf(ptr, LINEBUFFER + 1); |
|
|
mopt |= M_RMHEADER; |
|
|
return; |
|
|
} |
|
|
if (strncmp("rm-lt", buf, optlen) == 0) { |
|
|
ptr = parse_line_option(rcline); |
|
|
if_empty_quit(ptr); |
|
|
xfree(rm.latent_time); |
|
|
rm.latent_time = allocbuf(ptr, 16); |
|
|
mopt |= M_RMLT; |
|
|
return; |
|
|
} |
|
|
if (strncmp("rm-rlt", buf, optlen) == 0) { |
|
|
set(parse_line_option(buf), mopt, M_RMRLT); |
|
|
} |
|
|
return; |
|
623 |
} |
} |
624 |
|
|
|
/************************** |
|
|
Find the 'LINE' position. |
|
|
***************************/ |
|
625 |
|
|
626 |
unsigned long |
struct rc_kwdef gpg_kw[] = { |
627 |
get_position(char *line) |
{ "gpg-passphrase", KW_GPG_PASSPHRASE }, |
628 |
|
{ "gpg-encrypt", KW_GPG_ENCRYPT }, |
629 |
|
{ "gpg-sign", KW_GPG_SIGN }, |
630 |
|
{ "rm-gpg", KW_RM_GPG }, |
631 |
|
{ NULL }, |
632 |
|
}; |
633 |
|
|
634 |
|
static struct rc_secdef_child gpg_sect_child = { |
635 |
|
NULL |
636 |
|
CF_CLIENT, |
637 |
|
gpg_kw, |
638 |
|
gpg_parser, |
639 |
|
NULL |
640 |
|
}; |
641 |
|
|
642 |
|
#endif |
643 |
|
|
644 |
|
void |
645 |
|
all_section_init() |
646 |
{ |
{ |
647 |
char buf[LINEBUFFER+1]; |
struct rc_secdef *sp = anubis_add_section("ALL"); |
648 |
|
rc_secdef_add_child(sp, &all_sect_child); |
649 |
|
#ifdef HAVE_GPG |
650 |
|
rc_secdef_add_child(sp, &gpg_sect_child); |
651 |
|
#endif |
652 |
|
} |
653 |
|
|
654 |
if (fp_rcfile == 0 || line == 0) |
void |
655 |
return 0; |
rule_section_init() |
656 |
|
{ |
657 |
|
struct rc_secdef *sp = anubis_add_section("RULE"); |
658 |
|
|
659 |
|
rc_secdef_add_child(sp, &all_sect_child); |
660 |
|
#ifdef HAVE_GPG |
661 |
|
rc_secdef_add_child(sp, &gpg_sect_child); |
662 |
|
#endif |
663 |
|
} |
664 |
|
|
665 |
rewind(fp_rcfile); |
void |
666 |
while (fgets(buf, LINEBUFFER, fp_rcfile) != 0) |
rc_system_init() |
667 |
{ |
{ |
668 |
if (strncmp(buf, line, strlen(line)) == 0) |
control_section_init(); |
669 |
return (unsigned long)ftell(fp_rcfile); |
all_section_init(); |
670 |
} |
translate_section_init(); |
671 |
return 0; |
rule_section_init(); |
672 |
|
#ifdef WITH_GUILE |
673 |
|
guile_section_init(); |
674 |
|
#endif |
675 |
} |
} |
676 |
|
|
677 |
/* EOF */ |
/* Placeholders */ |
678 |
|
void |
679 |
|
rcfile_process_cond(char *name, int method, char *line) |
680 |
|
{ |
681 |
|
RC_SECTION *sec = rc_section_lookup(parse_tree, name); |
682 |
|
rc_run_section(CF_CLIENT, sec, anubis_rc_sections, method, line, NULL); |
683 |
|
} |
684 |
|
|
685 |
|
void |
686 |
|
rcfile_process_section(int method, char *name, void *data) |
687 |
|
{ |
688 |
|
RC_SECTION *sec = rc_section_lookup(parse_tree, name); |
689 |
|
rc_run_section(method, sec, anubis_rc_sections, 0, NULL, data); |
690 |
|
} |