1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2010-2021 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <mailutils/mailutils.h>
19 #include <mailutils/nls.h>
20 #include <sysexits.h>
21 #include "mu.h"
22
23 char acl_docstring[] = N_("test access control lists");
24 static char acl_args_doc[] = N_("ADDRESS [ADDRESS...]");
25
26 static char *input_file_name;
27 static struct mu_sockaddr *target_sa;
28 static mu_acl_t acl;
29 static const char *path = "acl";
30
31 static struct mu_option acl_options[] = {
32 { "file", 'f', N_("FILE"), MU_OPTION_DEFAULT,
33 N_("read ACLs from FILE"),
34 mu_c_string, &input_file_name },
35 { "path", 'p', N_("PATH"), MU_OPTION_DEFAULT,
36 N_("path to the ACL in the configuration tree"),
37 mu_c_string, &path },
38 { NULL }
39 };
40
41
42 static struct mu_cfg_param acl_cfg_param[] = {
43 { "acl", mu_cfg_section, &acl, 0, NULL, "access control list" },
44 { NULL }
45 };
46
47 int
main(int argc,char ** argv)48 main (int argc, char **argv)
49 {
50 int rc;
51 mu_acl_result_t result;
52 mu_cfg_tree_t *tree = NULL, *temp_tree = NULL;
53 mu_cfg_node_t *node;
54 struct mu_cfg_parse_hints hints;
55
56 mu_action_getopt (&argc, &argv, acl_options, acl_docstring, acl_args_doc);
57
58 if (argc == 0)
59 {
60 mu_error (_("not enough arguments"));
61 return 1;
62 }
63
64 memset (&hints, 0, sizeof (hints));
65 hints.flags = MU_CFHINT_CUSTOM_FILE;
66 hints.custom_file = input_file_name;
67
68 mu_acl_cfg_init ();
69 if (mu_cfg_parse_config (&tree, &hints))
70 exit (EX_CONFIG);
71 if (!tree)
72 return 0;
73
74 if (mu_cfg_find_node (tree, path, &node))
75 {
76 mu_error (_("cannot find node: %s"), path);
77 return 1;
78 }
79
80 mu_cfg_tree_create (&temp_tree);
81 mu_cfg_tree_add_node (temp_tree, node);
82 rc = mu_cfg_tree_reduce (temp_tree, NULL, acl_cfg_param, NULL);
83 if (rc)
84 return 1;
85 if (!acl)
86 {
87 mu_error (_("No ACL found in config"));
88 return 1;
89 }
90
91 while (argc--)
92 {
93 const char *ap = *argv++;
94
95 rc = mu_sockaddr_from_node (&target_sa, ap, NULL, NULL);
96 if (rc)
97 {
98 mu_error ("mu_sockaddr_from_node: %s", mu_strerror (rc));
99 exit (1);
100 }
101
102 mu_printf ("Testing %s:\n", ap);
103 rc = mu_acl_check_sockaddr (acl, target_sa->addr, target_sa->addrlen,
104 &result);
105 mu_sockaddr_free_list (target_sa);
106 if (rc)
107 {
108 mu_error ("mu_acl_check_sockaddr failed: %s", mu_strerror (rc));
109 return 1;
110 }
111
112 switch (result)
113 {
114 case mu_acl_result_undefined:
115 mu_printf ("%s: undefined\n", ap);
116 break;
117
118 case mu_acl_result_accept:
119 mu_printf ("%s: accept\n", ap);
120 break;
121
122 case mu_acl_result_deny:
123 mu_printf ("%s: deny\n", ap);
124 break;
125 }
126 }
127
128 mu_cfg_destroy_tree (&tree);
129 mu_cfg_destroy_tree (&temp_tree);
130
131 return 0;
132 }
133