Added client authentication and packet filtering capability
to management interface.
Extended packet filtering capability to work on both --dev tun
and --dev tap tunnels.
Updated valgrind-suppress file.
Made "Linux ip addr del failed" error nonfatal.
Amplified --client-cert-not-required warning.
Added #pragma pack to proto.h.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@2991 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -819,3 +819,130 @@ valign4 (const struct buffer *buf, const char *file, const int line) |
| 819 | 819 |
} |
| 820 | 820 |
} |
| 821 | 821 |
#endif |
| 822 |
+ |
|
| 823 |
+/* |
|
| 824 |
+ * struct buffer_list |
|
| 825 |
+ */ |
|
| 826 |
+ |
|
| 827 |
+#ifdef ENABLE_BUFFER_LIST |
|
| 828 |
+ |
|
| 829 |
+struct buffer_list * |
|
| 830 |
+buffer_list_new (const int max_size) |
|
| 831 |
+{
|
|
| 832 |
+ struct buffer_list *ret; |
|
| 833 |
+ ALLOC_OBJ_CLEAR (ret, struct buffer_list); |
|
| 834 |
+ ret->max_size = max_size; |
|
| 835 |
+ ret->size = 0; |
|
| 836 |
+ return ret; |
|
| 837 |
+} |
|
| 838 |
+ |
|
| 839 |
+void |
|
| 840 |
+buffer_list_free (struct buffer_list *ol) |
|
| 841 |
+{
|
|
| 842 |
+ buffer_list_reset (ol); |
|
| 843 |
+ free (ol); |
|
| 844 |
+} |
|
| 845 |
+ |
|
| 846 |
+bool |
|
| 847 |
+buffer_list_defined (const struct buffer_list *ol) |
|
| 848 |
+{
|
|
| 849 |
+ return ol->head != NULL; |
|
| 850 |
+} |
|
| 851 |
+ |
|
| 852 |
+void |
|
| 853 |
+buffer_list_reset (struct buffer_list *ol) |
|
| 854 |
+{
|
|
| 855 |
+ struct buffer_entry *e = ol->head; |
|
| 856 |
+ while (e) |
|
| 857 |
+ {
|
|
| 858 |
+ struct buffer_entry *next = e->next; |
|
| 859 |
+ free_buf (&e->buf); |
|
| 860 |
+ free (e); |
|
| 861 |
+ e = next; |
|
| 862 |
+ } |
|
| 863 |
+ ol->head = ol->tail = NULL; |
|
| 864 |
+ ol->size = 0; |
|
| 865 |
+} |
|
| 866 |
+ |
|
| 867 |
+void |
|
| 868 |
+buffer_list_push (struct buffer_list *ol, const unsigned char *str) |
|
| 869 |
+{
|
|
| 870 |
+ if (!ol->max_size || ol->size < ol->max_size) |
|
| 871 |
+ {
|
|
| 872 |
+ struct buffer_entry *e; |
|
| 873 |
+ ALLOC_OBJ_CLEAR (e, struct buffer_entry); |
|
| 874 |
+ |
|
| 875 |
+ ++ol->size; |
|
| 876 |
+ if (ol->tail) |
|
| 877 |
+ {
|
|
| 878 |
+ ASSERT (ol->head); |
|
| 879 |
+ ol->tail->next = e; |
|
| 880 |
+ } |
|
| 881 |
+ else |
|
| 882 |
+ {
|
|
| 883 |
+ ASSERT (!ol->head); |
|
| 884 |
+ ol->head = e; |
|
| 885 |
+ } |
|
| 886 |
+ e->buf = string_alloc_buf ((const char *) str, NULL); |
|
| 887 |
+ ol->tail = e; |
|
| 888 |
+ } |
|
| 889 |
+} |
|
| 890 |
+ |
|
| 891 |
+const struct buffer * |
|
| 892 |
+buffer_list_peek (struct buffer_list *ol) |
|
| 893 |
+{
|
|
| 894 |
+ if (ol->head) |
|
| 895 |
+ return &ol->head->buf; |
|
| 896 |
+ else |
|
| 897 |
+ return NULL; |
|
| 898 |
+} |
|
| 899 |
+ |
|
| 900 |
+static void |
|
| 901 |
+buffer_list_pop (struct buffer_list *ol) |
|
| 902 |
+{
|
|
| 903 |
+ if (ol->head) |
|
| 904 |
+ {
|
|
| 905 |
+ struct buffer_entry *e = ol->head->next; |
|
| 906 |
+ free_buf (&ol->head->buf); |
|
| 907 |
+ free (ol->head); |
|
| 908 |
+ ol->head = e; |
|
| 909 |
+ --ol->size; |
|
| 910 |
+ if (!e) |
|
| 911 |
+ ol->tail = NULL; |
|
| 912 |
+ } |
|
| 913 |
+} |
|
| 914 |
+ |
|
| 915 |
+void |
|
| 916 |
+buffer_list_advance (struct buffer_list *ol, int n) |
|
| 917 |
+{
|
|
| 918 |
+ if (ol->head) |
|
| 919 |
+ {
|
|
| 920 |
+ struct buffer *buf = &ol->head->buf; |
|
| 921 |
+ ASSERT (buf_advance (buf, n)); |
|
| 922 |
+ if (!BLEN (buf)) |
|
| 923 |
+ buffer_list_pop (ol); |
|
| 924 |
+ } |
|
| 925 |
+} |
|
| 926 |
+ |
|
| 927 |
+struct buffer_list * |
|
| 928 |
+buffer_list_file (const char *fn, int max_line_len) |
|
| 929 |
+{
|
|
| 930 |
+ FILE *fp = fopen (fn, "r"); |
|
| 931 |
+ struct buffer_list *bl = NULL; |
|
| 932 |
+ |
|
| 933 |
+ if (fp) |
|
| 934 |
+ {
|
|
| 935 |
+ char *line = (char *) malloc (max_line_len); |
|
| 936 |
+ if (line) |
|
| 937 |
+ {
|
|
| 938 |
+ bl = buffer_list_new (0); |
|
| 939 |
+ while (fgets (line, max_line_len, fp) != NULL) |
|
| 940 |
+ buffer_list_push (bl, (unsigned char *)line); |
|
| 941 |
+ free (line); |
|
| 942 |
+ } |
|
| 943 |
+ fclose (fp); |
|
| 944 |
+ } |
|
| 945 |
+ return bl; |
|
| 946 |
+} |
|
| 947 |
+ |
|
| 948 |
+#endif |
| ... | ... |
@@ -723,4 +723,38 @@ check_malloc_return (void *p) |
| 723 | 723 |
out_of_memory (); |
| 724 | 724 |
} |
| 725 | 725 |
|
| 726 |
+/* |
|
| 727 |
+ * Manage lists of buffers |
|
| 728 |
+ */ |
|
| 729 |
+ |
|
| 730 |
+#ifdef ENABLE_BUFFER_LIST |
|
| 731 |
+ |
|
| 732 |
+struct buffer_entry |
|
| 733 |
+{
|
|
| 734 |
+ struct buffer buf; |
|
| 735 |
+ struct buffer_entry *next; |
|
| 736 |
+}; |
|
| 737 |
+ |
|
| 738 |
+struct buffer_list |
|
| 739 |
+{
|
|
| 740 |
+ struct buffer_entry *head; /* next item to pop/peek */ |
|
| 741 |
+ struct buffer_entry *tail; /* last item pushed */ |
|
| 742 |
+ int size; /* current number of entries */ |
|
| 743 |
+ int max_size; /* maximum size list should grow to */ |
|
| 744 |
+}; |
|
| 745 |
+ |
|
| 746 |
+struct buffer_list *buffer_list_new (const int max_size); |
|
| 747 |
+void buffer_list_free (struct buffer_list *ol); |
|
| 748 |
+ |
|
| 749 |
+bool buffer_list_defined (const struct buffer_list *ol); |
|
| 750 |
+void buffer_list_reset (struct buffer_list *ol); |
|
| 751 |
+ |
|
| 752 |
+void buffer_list_push (struct buffer_list *ol, const unsigned char *str); |
|
| 753 |
+const struct buffer *buffer_list_peek (struct buffer_list *ol); |
|
| 754 |
+void buffer_list_advance (struct buffer_list *ol, int n); |
|
| 755 |
+ |
|
| 756 |
+struct buffer_list *buffer_list_file (const char *fn, int max_line_len); |
|
| 757 |
+ |
|
| 758 |
+#endif |
|
| 759 |
+ |
|
| 726 | 760 |
#endif /* BUFFER_H */ |
| ... | ... |
@@ -1,118 +1,411 @@ |
| 1 |
-# Valgrind suppressions file for OpenVPN. |
|
| 2 |
-# |
|
| 3 |
-# Mostly deal with uninitialized data warnings |
|
| 4 |
-# in OpenSSL. |
|
| 1 |
+{
|
|
| 2 |
+ <insert a suppression name here> |
|
| 3 |
+ Memcheck:Addr8 |
|
| 4 |
+ obj:/lib/ld-2.5.so |
|
| 5 |
+ obj:/lib/ld-2.5.so |
|
| 6 |
+ obj:/lib/ld-2.5.so |
|
| 7 |
+ obj:/lib/ld-2.5.so |
|
| 8 |
+ obj:/lib/ld-2.5.so |
|
| 9 |
+ obj:/lib/ld-2.5.so |
|
| 10 |
+ obj:/lib/ld-2.5.so |
|
| 11 |
+ obj:/lib/ld-2.5.so |
|
| 12 |
+ obj:/lib/ld-2.5.so |
|
| 13 |
+ obj:/lib/ld-2.5.so |
|
| 14 |
+ obj:/lib/libc-2.5.so |
|
| 15 |
+ obj:/lib/ld-2.5.so |
|
| 16 |
+ fun:__libc_dlopen_mode |
|
| 17 |
+ fun:__nss_lookup_function |
|
| 18 |
+ obj:/lib/libc-2.5.so |
|
| 19 |
+ fun:getgrnam_r |
|
| 20 |
+ fun:getgrnam |
|
| 21 |
+ fun:get_group |
|
| 22 |
+ fun:do_init_first_time |
|
| 23 |
+ fun:init_instance |
|
| 24 |
+ fun:init_instance_handle_signals |
|
| 25 |
+ fun:tunnel_server_tcp |
|
| 26 |
+ fun:main |
|
| 27 |
+} |
|
| 5 | 28 |
|
| 6 | 29 |
{
|
| 7 |
- cond_BN |
|
| 8 |
- Memcheck:Cond |
|
| 9 |
- fun:BN_* |
|
| 30 |
+ <insert a suppression name here> |
|
| 31 |
+ Memcheck:Addr8 |
|
| 32 |
+ obj:/lib/ld-2.5.so |
|
| 33 |
+ obj:/lib/ld-2.5.so |
|
| 34 |
+ obj:/lib/ld-2.5.so |
|
| 35 |
+ obj:/lib/ld-2.5.so |
|
| 36 |
+ obj:/lib/ld-2.5.so |
|
| 37 |
+ obj:/lib/ld-2.5.so |
|
| 38 |
+ obj:/lib/ld-2.5.so |
|
| 39 |
+ obj:/lib/libc-2.5.so |
|
| 40 |
+ obj:/lib/ld-2.5.so |
|
| 41 |
+ fun:__libc_dlopen_mode |
|
| 42 |
+ fun:__nss_lookup_function |
|
| 43 |
+ fun:__nss_next |
|
| 44 |
+ fun:gethostbyname_r |
|
| 45 |
+ fun:gethostbyname |
|
| 46 |
+ fun:getaddr |
|
| 47 |
+ fun:resolve_remote |
|
| 48 |
+ fun:link_socket_init_phase1 |
|
| 49 |
+ fun:init_instance |
|
| 50 |
+ fun:init_instance_handle_signals |
|
| 51 |
+ fun:main |
|
| 10 | 52 |
} |
| 11 | 53 |
|
| 12 | 54 |
{
|
| 13 |
- value4_BN |
|
| 14 |
- Memcheck:Value4 |
|
| 15 |
- fun:BN_* |
|
| 55 |
+ <insert a suppression name here> |
|
| 56 |
+ Memcheck:Addr8 |
|
| 57 |
+ obj:/lib/ld-2.5.so |
|
| 58 |
+ obj:/lib/ld-2.5.so |
|
| 59 |
+ obj:/lib/ld-2.5.so |
|
| 60 |
+ obj:/lib/ld-2.5.so |
|
| 61 |
+ obj:/lib/ld-2.5.so |
|
| 62 |
+ obj:/lib/ld-2.5.so |
|
| 63 |
+ obj:/lib/ld-2.5.so |
|
| 64 |
+ obj:/lib/libc-2.5.so |
|
| 65 |
+ obj:/lib/ld-2.5.so |
|
| 66 |
+ fun:__libc_dlopen_mode |
|
| 67 |
+ fun:__nss_lookup_function |
|
| 68 |
+ obj:/lib/libc-2.5.so |
|
| 69 |
+ fun:gethostbyname_r |
|
| 70 |
+ fun:gethostbyname |
|
| 71 |
+ fun:getaddr |
|
| 72 |
+ fun:resolve_remote |
|
| 73 |
+ fun:link_socket_init_phase1 |
|
| 74 |
+ fun:init_instance |
|
| 75 |
+ fun:init_instance_handle_signals |
|
| 76 |
+ fun:main |
|
| 16 | 77 |
} |
| 17 | 78 |
|
| 18 | 79 |
{
|
| 19 |
- cond_bn |
|
| 20 |
- Memcheck:Cond |
|
| 21 |
- fun:bn_* |
|
| 80 |
+ <insert a suppression name here> |
|
| 81 |
+ Memcheck:Addr8 |
|
| 82 |
+ obj:/lib/ld-2.5.so |
|
| 83 |
+ obj:/lib/ld-2.5.so |
|
| 84 |
+ obj:/lib/ld-2.5.so |
|
| 85 |
+ obj:/lib/ld-2.5.so |
|
| 86 |
+ obj:/lib/ld-2.5.so |
|
| 87 |
+ obj:/lib/ld-2.5.so |
|
| 88 |
+ obj:/lib/ld-2.5.so |
|
| 89 |
+ obj:/lib/libdl-2.5.so |
|
| 90 |
+ obj:/lib/ld-2.5.so |
|
| 91 |
+ obj:/lib/libdl-2.5.so |
|
| 92 |
+ fun:dlopen |
|
| 93 |
+ fun:plugin_list_init |
|
| 94 |
+ fun:init_plugins |
|
| 95 |
+ fun:main |
|
| 22 | 96 |
} |
| 23 | 97 |
|
| 24 | 98 |
{
|
| 25 |
- value4_bn |
|
| 26 |
- Memcheck:Value4 |
|
| 27 |
- fun:bn_* |
|
| 99 |
+ <insert a suppression name here> |
|
| 100 |
+ Memcheck:Addr8 |
|
| 101 |
+ obj:/lib/ld-2.5.so |
|
| 102 |
+ obj:/lib/ld-2.5.so |
|
| 103 |
+ obj:/lib/ld-2.5.so |
|
| 104 |
+ obj:/lib/ld-2.5.so |
|
| 105 |
+ obj:/lib/ld-2.5.so |
|
| 106 |
+ obj:/lib/ld-2.5.so |
|
| 107 |
+ obj:/lib/libdl-2.5.so |
|
| 108 |
+ obj:/lib/ld-2.5.so |
|
| 109 |
+ obj:/lib/libdl-2.5.so |
|
| 110 |
+ fun:dlopen |
|
| 111 |
+ fun:plugin_list_init |
|
| 112 |
+ fun:init_plugins |
|
| 113 |
+ fun:main |
|
| 28 | 114 |
} |
| 29 | 115 |
|
| 30 | 116 |
{
|
| 31 |
- cond_SHA1_Update |
|
| 32 |
- Memcheck:Cond |
|
| 33 |
- fun:SHA1_Update |
|
| 117 |
+ <insert a suppression name here> |
|
| 118 |
+ Memcheck:Addr8 |
|
| 119 |
+ obj:/lib/ld-2.5.so |
|
| 120 |
+ obj:/lib/ld-2.5.so |
|
| 121 |
+ obj:/lib/ld-2.5.so |
|
| 122 |
+ obj:/lib/ld-2.5.so |
|
| 123 |
+ obj:/lib/libc-2.5.so |
|
| 124 |
+ obj:/lib/libdl-2.5.so |
|
| 125 |
+ obj:/lib/ld-2.5.so |
|
| 126 |
+ obj:/lib/libdl-2.5.so |
|
| 127 |
+ fun:dlsym |
|
| 128 |
+ fun:libdl_resolve_symbol |
|
| 129 |
+ fun:plugin_list_init |
|
| 130 |
+ fun:init_plugins |
|
| 131 |
+ fun:main |
|
| 34 | 132 |
} |
| 35 | 133 |
|
| 36 | 134 |
{
|
| 37 |
- value4_SHA1_Update |
|
| 38 |
- Memcheck:Value4 |
|
| 39 |
- fun:SHA1_Update |
|
| 135 |
+ <insert a suppression name here> |
|
| 136 |
+ Memcheck:Addr8 |
|
| 137 |
+ obj:/lib/ld-2.5.so |
|
| 138 |
+ obj:/lib/ld-2.5.so |
|
| 139 |
+ obj:/lib/ld-2.5.so |
|
| 140 |
+ obj:/lib/ld-2.5.so |
|
| 141 |
+ obj:/lib/libdl-2.5.so |
|
| 142 |
+ obj:/lib/ld-2.5.so |
|
| 143 |
+ obj:/lib/libdl-2.5.so |
|
| 144 |
+ fun:dlopen |
|
| 145 |
+ fun:plugin_list_init |
|
| 146 |
+ fun:init_plugins |
|
| 147 |
+ fun:main |
|
| 40 | 148 |
} |
| 41 | 149 |
|
| 42 | 150 |
{
|
| 43 |
- cond_ssl3_read_bytes |
|
| 151 |
+ <insert a suppression name here> |
|
| 44 | 152 |
Memcheck:Cond |
| 45 |
- fun:ssl3_read_bytes |
|
| 153 |
+ obj:/lib/ld-2.5.so |
|
| 154 |
+ obj:/lib/ld-2.5.so |
|
| 155 |
+ obj:/lib/ld-2.5.so |
|
| 156 |
+ obj:/lib/ld-2.5.so |
|
| 157 |
+ obj:/lib/ld-2.5.so |
|
| 158 |
+ obj:* |
|
| 159 |
+ obj:* |
|
| 160 |
+ obj:* |
|
| 46 | 161 |
} |
| 47 | 162 |
|
| 48 | 163 |
{
|
| 49 |
- cond_crypto |
|
| 164 |
+ <insert a suppression name here> |
|
| 50 | 165 |
Memcheck:Cond |
| 51 |
- obj:/lib/libcrypto.so.* |
|
| 166 |
+ obj:/lib/ld-2.5.so |
|
| 167 |
+ obj:/lib/ld-2.5.so |
|
| 168 |
+ obj:/lib/ld-2.5.so |
|
| 169 |
+ obj:/lib/ld-2.5.so |
|
| 170 |
+ obj:/lib/ld-2.5.so |
|
| 171 |
+ obj:/lib/ld-2.5.so |
|
| 172 |
+ obj:/lib/ld-2.5.so |
|
| 173 |
+ obj:/lib/libc-2.5.so |
|
| 174 |
+ obj:/lib/ld-2.5.so |
|
| 175 |
+ fun:__libc_dlopen_mode |
|
| 176 |
+ fun:__nss_lookup_function |
|
| 177 |
+ fun:__nss_next |
|
| 178 |
+ fun:gethostbyname_r |
|
| 179 |
+ fun:gethostbyname |
|
| 180 |
+ fun:getaddr |
|
| 181 |
+ fun:resolve_remote |
|
| 182 |
+ fun:link_socket_init_phase1 |
|
| 183 |
+ fun:init_instance |
|
| 184 |
+ fun:init_instance_handle_signals |
|
| 185 |
+ fun:main |
|
| 52 | 186 |
} |
| 53 | 187 |
|
| 54 | 188 |
{
|
| 55 |
- value4_crypto |
|
| 56 |
- Memcheck:Value4 |
|
| 57 |
- obj:/lib/libcrypto.so.* |
|
| 189 |
+ <insert a suppression name here> |
|
| 190 |
+ Memcheck:Cond |
|
| 191 |
+ obj:/lib/ld-2.5.so |
|
| 192 |
+ obj:/lib/ld-2.5.so |
|
| 193 |
+ obj:/lib/ld-2.5.so |
|
| 194 |
+ obj:/lib/ld-2.5.so |
|
| 195 |
+ obj:/lib/ld-2.5.so |
|
| 196 |
+ obj:/lib/ld-2.5.so |
|
| 197 |
+ obj:/lib/ld-2.5.so |
|
| 198 |
+ obj:/lib/libc-2.5.so |
|
| 199 |
+ obj:/lib/ld-2.5.so |
|
| 200 |
+ fun:__libc_dlopen_mode |
|
| 201 |
+ fun:__nss_lookup_function |
|
| 202 |
+ obj:/lib/libc-2.5.so |
|
| 203 |
+ fun:getgrnam_r |
|
| 204 |
+ fun:getgrnam |
|
| 205 |
+ fun:get_group |
|
| 206 |
+ fun:do_init_first_time |
|
| 207 |
+ fun:init_instance |
|
| 208 |
+ fun:init_instance_handle_signals |
|
| 209 |
+ fun:tunnel_server_tcp |
|
| 210 |
+ fun:main |
|
| 58 | 211 |
} |
| 59 | 212 |
|
| 60 | 213 |
{
|
| 61 |
- cond_ssl |
|
| 214 |
+ <insert a suppression name here> |
|
| 62 | 215 |
Memcheck:Cond |
| 63 |
- obj:/lib/libssl.so.* |
|
| 216 |
+ obj:/lib/ld-2.5.so |
|
| 217 |
+ obj:/lib/ld-2.5.so |
|
| 218 |
+ obj:/lib/ld-2.5.so |
|
| 219 |
+ obj:/lib/ld-2.5.so |
|
| 220 |
+ obj:/lib/ld-2.5.so |
|
| 221 |
+ obj:/lib/ld-2.5.so |
|
| 222 |
+ obj:/lib/ld-2.5.so |
|
| 223 |
+ obj:/lib/libc-2.5.so |
|
| 224 |
+ obj:/lib/ld-2.5.so |
|
| 225 |
+ fun:__libc_dlopen_mode |
|
| 226 |
+ fun:__nss_lookup_function |
|
| 227 |
+ obj:/lib/libc-2.5.so |
|
| 228 |
+ fun:gethostbyname_r |
|
| 229 |
+ fun:gethostbyname |
|
| 230 |
+ fun:getaddr |
|
| 231 |
+ fun:resolve_remote |
|
| 232 |
+ fun:link_socket_init_phase1 |
|
| 233 |
+ fun:init_instance |
|
| 234 |
+ fun:init_instance_handle_signals |
|
| 235 |
+ fun:main |
|
| 64 | 236 |
} |
| 65 | 237 |
|
| 66 | 238 |
{
|
| 67 |
- value4_ssl |
|
| 68 |
- Memcheck:Value4 |
|
| 69 |
- obj:/lib/libssl.so.* |
|
| 239 |
+ <insert a suppression name here> |
|
| 240 |
+ Memcheck:Cond |
|
| 241 |
+ obj:/lib/ld-2.5.so |
|
| 242 |
+ obj:/lib/ld-2.5.so |
|
| 243 |
+ obj:/lib/ld-2.5.so |
|
| 244 |
+ obj:/lib/ld-2.5.so |
|
| 245 |
+ obj:/lib/ld-2.5.so |
|
| 246 |
+ obj:/lib/libc-2.5.so |
|
| 247 |
+ obj:/lib/ld-2.5.so |
|
| 248 |
+ fun:__libc_dlopen_mode |
|
| 249 |
+ fun:__nss_lookup_function |
|
| 250 |
+ fun:__nss_next |
|
| 251 |
+ fun:gethostbyname_r |
|
| 252 |
+ fun:gethostbyname |
|
| 253 |
+ fun:getaddr |
|
| 254 |
+ fun:resolve_remote |
|
| 255 |
+ fun:link_socket_init_phase1 |
|
| 256 |
+ fun:init_instance |
|
| 257 |
+ fun:init_instance_handle_signals |
|
| 258 |
+ fun:main |
|
| 70 | 259 |
} |
| 71 | 260 |
|
| 72 | 261 |
{
|
| 73 |
- addr4_AES_cbc_encrypt |
|
| 74 |
- Memcheck:Addr4 |
|
| 75 |
- fun:AES_cbc_encrypt |
|
| 262 |
+ <insert a suppression name here> |
|
| 263 |
+ Memcheck:Cond |
|
| 264 |
+ obj:/lib/ld-2.5.so |
|
| 265 |
+ obj:/lib/ld-2.5.so |
|
| 266 |
+ obj:/lib/ld-2.5.so |
|
| 267 |
+ obj:/lib/ld-2.5.so |
|
| 268 |
+ obj:/lib/ld-2.5.so |
|
| 269 |
+ obj:/lib/libc-2.5.so |
|
| 270 |
+ obj:/lib/ld-2.5.so |
|
| 271 |
+ fun:__libc_dlopen_mode |
|
| 272 |
+ fun:__nss_lookup_function |
|
| 273 |
+ obj:/lib/libc-2.5.so |
|
| 274 |
+ fun:getgrnam_r |
|
| 275 |
+ fun:getgrnam |
|
| 276 |
+ fun:get_group |
|
| 277 |
+ fun:do_init_first_time |
|
| 278 |
+ fun:init_instance |
|
| 279 |
+ fun:init_instance_handle_signals |
|
| 280 |
+ fun:tunnel_server_tcp |
|
| 281 |
+ fun:main |
|
| 76 | 282 |
} |
| 77 | 283 |
|
| 78 | 284 |
{
|
| 79 |
- cond_memcpy_ssl3_read_bytes |
|
| 285 |
+ <insert a suppression name here> |
|
| 80 | 286 |
Memcheck:Cond |
| 81 |
- fun:memcpy |
|
| 82 |
- fun:ssl3_read_bytes |
|
| 287 |
+ obj:/lib/ld-2.5.so |
|
| 288 |
+ obj:/lib/ld-2.5.so |
|
| 289 |
+ obj:/lib/ld-2.5.so |
|
| 290 |
+ obj:/lib/ld-2.5.so |
|
| 291 |
+ obj:/lib/ld-2.5.so |
|
| 292 |
+ obj:/lib/libc-2.5.so |
|
| 293 |
+ obj:/lib/ld-2.5.so |
|
| 294 |
+ fun:__libc_dlopen_mode |
|
| 295 |
+ fun:__nss_lookup_function |
|
| 296 |
+ obj:/lib/libc-2.5.so |
|
| 297 |
+ fun:gethostbyname_r |
|
| 298 |
+ fun:gethostbyname |
|
| 299 |
+ fun:getaddr |
|
| 300 |
+ fun:resolve_remote |
|
| 301 |
+ fun:link_socket_init_phase1 |
|
| 302 |
+ fun:init_instance |
|
| 303 |
+ fun:init_instance_handle_signals |
|
| 304 |
+ fun:main |
|
| 83 | 305 |
} |
| 84 | 306 |
|
| 85 | 307 |
{
|
| 86 |
- value4_memcpy_ssl3_read_bytes |
|
| 87 |
- Memcheck:Value4 |
|
| 88 |
- fun:memcpy |
|
| 89 |
- fun:ssl3_read_bytes |
|
| 308 |
+ <insert a suppression name here> |
|
| 309 |
+ Memcheck:Cond |
|
| 310 |
+ obj:/lib/ld-2.5.so |
|
| 311 |
+ obj:/lib/ld-2.5.so |
|
| 312 |
+ obj:/lib/ld-2.5.so |
|
| 313 |
+ obj:/lib/ld-2.5.so |
|
| 314 |
+ obj:/lib/libc-2.5.so |
|
| 315 |
+ obj:/lib/ld-2.5.so |
|
| 316 |
+ fun:__libc_dlopen_mode |
|
| 317 |
+ fun:__nss_lookup_function |
|
| 318 |
+ fun:__nss_next |
|
| 319 |
+ fun:gethostbyname_r |
|
| 320 |
+ fun:gethostbyname |
|
| 321 |
+ fun:getaddr |
|
| 322 |
+ fun:resolve_remote |
|
| 323 |
+ fun:link_socket_init_phase1 |
|
| 324 |
+ fun:init_instance |
|
| 325 |
+ fun:init_instance_handle_signals |
|
| 326 |
+ fun:main |
|
| 90 | 327 |
} |
| 91 | 328 |
|
| 92 | 329 |
{
|
| 93 |
- cond_memset_BUF_MEM_grow_clean |
|
| 330 |
+ <insert a suppression name here> |
|
| 94 | 331 |
Memcheck:Cond |
| 95 |
- fun:memset |
|
| 96 |
- fun:BUF_MEM_grow_clean |
|
| 332 |
+ obj:/lib/ld-2.5.so |
|
| 333 |
+ obj:/lib/ld-2.5.so |
|
| 334 |
+ obj:/lib/ld-2.5.so |
|
| 335 |
+ obj:/lib/ld-2.5.so |
|
| 336 |
+ obj:/lib/libc-2.5.so |
|
| 337 |
+ obj:/lib/ld-2.5.so |
|
| 338 |
+ fun:__libc_dlopen_mode |
|
| 339 |
+ fun:__nss_lookup_function |
|
| 340 |
+ obj:/lib/libc-2.5.so |
|
| 341 |
+ fun:getgrnam_r |
|
| 342 |
+ fun:getgrnam |
|
| 343 |
+ fun:get_group |
|
| 344 |
+ fun:do_init_first_time |
|
| 345 |
+ fun:init_instance |
|
| 346 |
+ fun:init_instance_handle_signals |
|
| 347 |
+ fun:tunnel_server_tcp |
|
| 348 |
+ fun:main |
|
| 97 | 349 |
} |
| 98 | 350 |
|
| 99 | 351 |
{
|
| 100 |
- value4_memset_BUF_MEM_grow_clean |
|
| 101 |
- Memcheck:Value4 |
|
| 102 |
- fun:memset |
|
| 103 |
- fun:BUF_MEM_grow_clean |
|
| 352 |
+ <insert a suppression name here> |
|
| 353 |
+ Memcheck:Cond |
|
| 354 |
+ obj:/lib/ld-2.5.so |
|
| 355 |
+ obj:/lib/ld-2.5.so |
|
| 356 |
+ obj:/lib/ld-2.5.so |
|
| 357 |
+ obj:/lib/ld-2.5.so |
|
| 358 |
+ obj:/lib/libc-2.5.so |
|
| 359 |
+ obj:/lib/ld-2.5.so |
|
| 360 |
+ fun:__libc_dlopen_mode |
|
| 361 |
+ fun:__nss_lookup_function |
|
| 362 |
+ obj:/lib/libc-2.5.so |
|
| 363 |
+ fun:getgrnam_r |
|
| 364 |
+ fun:getgrnam |
|
| 365 |
+ fun:get_group |
|
| 366 |
+ fun:do_init_first_time |
|
| 367 |
+ fun:init_instance |
|
| 368 |
+ fun:init_instance_handle_signals |
|
| 369 |
+ fun:tunnel_server_udp |
|
| 370 |
+ fun:main |
|
| 104 | 371 |
} |
| 105 | 372 |
|
| 106 | 373 |
{
|
| 107 | 374 |
<insert a suppression name here> |
| 108 |
- Memcheck:Addr8 |
|
| 375 |
+ Memcheck:Cond |
|
| 376 |
+ obj:/lib/ld-2.5.so |
|
| 109 | 377 |
obj:/lib/ld-2.5.so |
| 378 |
+ obj:/lib/ld-2.5.so |
|
| 379 |
+ obj:/lib/ld-2.5.so |
|
| 380 |
+ obj:/lib/libc-2.5.so |
|
| 381 |
+ obj:/lib/ld-2.5.so |
|
| 382 |
+ fun:__libc_dlopen_mode |
|
| 383 |
+ fun:__nss_lookup_function |
|
| 384 |
+ obj:/lib/libc-2.5.so |
|
| 385 |
+ fun:gethostbyname_r |
|
| 386 |
+ fun:gethostbyname |
|
| 387 |
+ fun:getaddr |
|
| 388 |
+ fun:resolve_remote |
|
| 389 |
+ fun:link_socket_init_phase1 |
|
| 390 |
+ fun:init_instance |
|
| 391 |
+ fun:init_instance_handle_signals |
|
| 392 |
+ fun:main |
|
| 110 | 393 |
} |
| 111 | 394 |
|
| 112 | 395 |
{
|
| 113 | 396 |
<insert a suppression name here> |
| 114 | 397 |
Memcheck:Cond |
| 115 | 398 |
obj:/lib/ld-2.5.so |
| 399 |
+ obj:/lib/ld-2.5.so |
|
| 400 |
+ obj:/lib/ld-2.5.so |
|
| 401 |
+ obj:/lib/ld-2.5.so |
|
| 402 |
+ obj:/lib/libdl-2.5.so |
|
| 403 |
+ obj:/lib/ld-2.5.so |
|
| 404 |
+ obj:/lib/libdl-2.5.so |
|
| 405 |
+ fun:dlopen |
|
| 406 |
+ fun:plugin_list_init |
|
| 407 |
+ fun:init_plugins |
|
| 408 |
+ fun:main |
|
| 116 | 409 |
} |
| 117 | 410 |
|
| 118 | 411 |
{
|
| ... | ... |
@@ -128,3 +421,172 @@ |
| 128 | 128 |
fun:init_static |
| 129 | 129 |
fun:main |
| 130 | 130 |
} |
| 131 |
+ |
|
| 132 |
+{
|
|
| 133 |
+ <insert a suppression name here> |
|
| 134 |
+ Memcheck:Leak |
|
| 135 |
+ fun:malloc |
|
| 136 |
+ fun:__nss_lookup_function |
|
| 137 |
+ obj:* |
|
| 138 |
+ obj:* |
|
| 139 |
+ fun:getgrnam_r |
|
| 140 |
+ fun:getgrnam |
|
| 141 |
+ fun:get_group |
|
| 142 |
+ fun:do_init_first_time |
|
| 143 |
+ fun:init_instance |
|
| 144 |
+ fun:init_instance_handle_signals |
|
| 145 |
+ fun:main |
|
| 146 |
+} |
|
| 147 |
+ |
|
| 148 |
+{
|
|
| 149 |
+ <insert a suppression name here> |
|
| 150 |
+ Memcheck:Leak |
|
| 151 |
+ fun:malloc |
|
| 152 |
+ fun:__nss_lookup_function |
|
| 153 |
+ obj:* |
|
| 154 |
+ obj:* |
|
| 155 |
+ fun:getgrnam_r |
|
| 156 |
+ fun:getgrnam |
|
| 157 |
+ fun:get_group |
|
| 158 |
+ fun:do_init_first_time |
|
| 159 |
+ fun:init_instance |
|
| 160 |
+ fun:init_instance_handle_signals |
|
| 161 |
+ fun:tunnel_server_tcp |
|
| 162 |
+ fun:main |
|
| 163 |
+} |
|
| 164 |
+ |
|
| 165 |
+{
|
|
| 166 |
+ <insert a suppression name here> |
|
| 167 |
+ Memcheck:Leak |
|
| 168 |
+ fun:malloc |
|
| 169 |
+ fun:__nss_lookup_function |
|
| 170 |
+ obj:* |
|
| 171 |
+ obj:* |
|
| 172 |
+ fun:getgrnam_r |
|
| 173 |
+ fun:getgrnam |
|
| 174 |
+ fun:get_group |
|
| 175 |
+ fun:do_init_first_time |
|
| 176 |
+ fun:init_instance |
|
| 177 |
+ fun:init_instance_handle_signals |
|
| 178 |
+ fun:tunnel_server_udp |
|
| 179 |
+ fun:main |
|
| 180 |
+} |
|
| 181 |
+ |
|
| 182 |
+{
|
|
| 183 |
+ <insert a suppression name here> |
|
| 184 |
+ Memcheck:Leak |
|
| 185 |
+ fun:malloc |
|
| 186 |
+ fun:getdelim |
|
| 187 |
+ fun:getpass |
|
| 188 |
+ fun:get_console_input |
|
| 189 |
+ fun:get_user_pass |
|
| 190 |
+ fun:context_init_1 |
|
| 191 |
+ fun:main |
|
| 192 |
+} |
|
| 193 |
+ |
|
| 194 |
+{
|
|
| 195 |
+ <insert a suppression name here> |
|
| 196 |
+ Memcheck:Leak |
|
| 197 |
+ fun:malloc |
|
| 198 |
+ fun:tsearch |
|
| 199 |
+ fun:__nss_lookup_function |
|
| 200 |
+ obj:* |
|
| 201 |
+ obj:* |
|
| 202 |
+ fun:getgrnam_r |
|
| 203 |
+ fun:getgrnam |
|
| 204 |
+ fun:get_group |
|
| 205 |
+ fun:do_init_first_time |
|
| 206 |
+ fun:init_instance |
|
| 207 |
+ fun:init_instance_handle_signals |
|
| 208 |
+ fun:main |
|
| 209 |
+} |
|
| 210 |
+ |
|
| 211 |
+{
|
|
| 212 |
+ <insert a suppression name here> |
|
| 213 |
+ Memcheck:Leak |
|
| 214 |
+ fun:malloc |
|
| 215 |
+ fun:tsearch |
|
| 216 |
+ fun:__nss_lookup_function |
|
| 217 |
+ obj:* |
|
| 218 |
+ obj:* |
|
| 219 |
+ fun:getgrnam_r |
|
| 220 |
+ fun:getgrnam |
|
| 221 |
+ fun:get_group |
|
| 222 |
+ fun:do_init_first_time |
|
| 223 |
+ fun:init_instance |
|
| 224 |
+ fun:init_instance_handle_signals |
|
| 225 |
+ fun:tunnel_server_tcp |
|
| 226 |
+ fun:main |
|
| 227 |
+} |
|
| 228 |
+ |
|
| 229 |
+{
|
|
| 230 |
+ <insert a suppression name here> |
|
| 231 |
+ Memcheck:Leak |
|
| 232 |
+ fun:malloc |
|
| 233 |
+ fun:tsearch |
|
| 234 |
+ fun:__nss_lookup_function |
|
| 235 |
+ obj:* |
|
| 236 |
+ obj:* |
|
| 237 |
+ fun:getgrnam_r |
|
| 238 |
+ fun:getgrnam |
|
| 239 |
+ fun:get_group |
|
| 240 |
+ fun:do_init_first_time |
|
| 241 |
+ fun:init_instance |
|
| 242 |
+ fun:init_instance_handle_signals |
|
| 243 |
+ fun:tunnel_server_udp |
|
| 244 |
+ fun:main |
|
| 245 |
+} |
|
| 246 |
+ |
|
| 247 |
+{
|
|
| 248 |
+ <insert a suppression name here> |
|
| 249 |
+ Memcheck:Leak |
|
| 250 |
+ fun:malloc |
|
| 251 |
+ obj:/lib/libc-2.5.so |
|
| 252 |
+ fun:__nss_database_lookup |
|
| 253 |
+ obj:* |
|
| 254 |
+ obj:* |
|
| 255 |
+ fun:getgrnam_r |
|
| 256 |
+ fun:getgrnam |
|
| 257 |
+ fun:get_group |
|
| 258 |
+ fun:do_init_first_time |
|
| 259 |
+ fun:init_instance |
|
| 260 |
+ fun:init_instance_handle_signals |
|
| 261 |
+ fun:main |
|
| 262 |
+} |
|
| 263 |
+ |
|
| 264 |
+{
|
|
| 265 |
+ <insert a suppression name here> |
|
| 266 |
+ Memcheck:Leak |
|
| 267 |
+ fun:malloc |
|
| 268 |
+ obj:/lib/libc-2.5.so |
|
| 269 |
+ fun:__nss_database_lookup |
|
| 270 |
+ obj:* |
|
| 271 |
+ obj:* |
|
| 272 |
+ fun:getgrnam_r |
|
| 273 |
+ fun:getgrnam |
|
| 274 |
+ fun:get_group |
|
| 275 |
+ fun:do_init_first_time |
|
| 276 |
+ fun:init_instance |
|
| 277 |
+ fun:init_instance_handle_signals |
|
| 278 |
+ fun:tunnel_server_tcp |
|
| 279 |
+ fun:main |
|
| 280 |
+} |
|
| 281 |
+ |
|
| 282 |
+{
|
|
| 283 |
+ <insert a suppression name here> |
|
| 284 |
+ Memcheck:Leak |
|
| 285 |
+ fun:malloc |
|
| 286 |
+ obj:/lib/libc-2.5.so |
|
| 287 |
+ fun:__nss_database_lookup |
|
| 288 |
+ obj:* |
|
| 289 |
+ obj:* |
|
| 290 |
+ fun:getgrnam_r |
|
| 291 |
+ fun:getgrnam |
|
| 292 |
+ fun:get_group |
|
| 293 |
+ fun:do_init_first_time |
|
| 294 |
+ fun:init_instance |
|
| 295 |
+ fun:init_instance_handle_signals |
|
| 296 |
+ fun:tunnel_server_udp |
|
| 297 |
+ fun:main |
|
| 298 |
+} |
|
| 299 |
+ |
| ... | ... |
@@ -94,7 +94,7 @@ |
| 94 | 94 |
#define D_ROUTE_QUOTA LOGLEV(3, 43, 0) /* show route quota exceeded messages */ |
| 95 | 95 |
#define D_OSBUF LOGLEV(3, 44, 0) /* show socket/tun/tap buffer sizes */ |
| 96 | 96 |
#define D_PS_PROXY LOGLEV(3, 45, 0) /* messages related to --port-share option */ |
| 97 |
-#define D_PF LOGLEV(3, 46, 0) /* messages related to packet filter */ |
|
| 97 |
+#define D_PF_INFO LOGLEV(3, 46, 0) /* packet filter informational messages */ |
|
| 98 | 98 |
|
| 99 | 99 |
#define D_SHOW_PARMS LOGLEV(4, 50, 0) /* show all parameters on program initiation */ |
| 100 | 100 |
#define D_SHOW_OCC LOGLEV(4, 51, 0) /* show options compatibility string */ |
| ... | ... |
@@ -102,6 +102,7 @@ |
| 102 | 102 |
#define D_DHCP_OPT LOGLEV(4, 53, 0) /* show DHCP options binary string */ |
| 103 | 103 |
#define D_MBUF LOGLEV(4, 54, 0) /* mbuf.[ch] routines */ |
| 104 | 104 |
#define D_PACKET_TRUNC_ERR LOGLEV(4, 55, 0) /* PACKET_TRUNCATION_CHECK */ |
| 105 |
+#define D_PF_DROPPED LOGLEV(4, 56, 0) /* packet filter dropped a packet */ |
|
| 105 | 106 |
|
| 106 | 107 |
#define D_LOG_RW LOGLEV(5, 0, 0) /* Print 'R' or 'W' to stdout for read/write */ |
| 107 | 108 |
|
| ... | ... |
@@ -136,6 +137,8 @@ |
| 136 | 136 |
#define D_PING LOGLEV(7, 70, M_DEBUG) /* PING send/receive messages */ |
| 137 | 137 |
#define D_PS_PROXY_DEBUG LOGLEV(7, 70, M_DEBUG) /* port share proxy debug */ |
| 138 | 138 |
#define D_AUTO_USERID LOGLEV(7, 70, M_DEBUG) /* AUTO_USERID debugging */ |
| 139 |
+#define D_PF_DROPPED_BCAST LOGLEV(7, 71, M_DEBUG) /* packet filter dropped a broadcast packet */ |
|
| 140 |
+#define D_PF_DEBUG LOGLEV(7, 72, M_DEBUG) /* packet filter debugging, must also define PF_DEBUG in pf.h */ |
|
| 139 | 141 |
|
| 140 | 142 |
#define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show detailed description of each handshake */ |
| 141 | 143 |
#define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG) /* limited info from tls_session routines */ |
| ... | ... |
@@ -268,7 +268,10 @@ void x_msg (const unsigned int flags, const char *format, ...) |
| 268 | 268 |
#endif |
| 269 | 269 |
|
| 270 | 270 |
/* set up client prefix */ |
| 271 |
- prefix = msg_get_prefix (); |
|
| 271 |
+ if (flags & M_NOIPREFIX) |
|
| 272 |
+ prefix = NULL; |
|
| 273 |
+ else |
|
| 274 |
+ prefix = msg_get_prefix (); |
|
| 272 | 275 |
prefix_sep = " "; |
| 273 | 276 |
if (!prefix) |
| 274 | 277 |
prefix_sep = prefix = ""; |
| ... | ... |
@@ -102,13 +102,14 @@ extern int x_msg_line_num; |
| 102 | 102 |
#define M_MSG_VIRT_OUT (1<<14) /* output message through msg_status_output callback */ |
| 103 | 103 |
#define M_OPTERR (1<<15) /* print "Options error:" prefix */ |
| 104 | 104 |
#define M_NOLF (1<<16) /* don't print new line */ |
| 105 |
+#define M_NOIPREFIX (1<<17) /* don't print instance prefix */ |
|
| 105 | 106 |
|
| 106 | 107 |
/* flag combinations which are frequently used */ |
| 107 | 108 |
#define M_ERR (M_FATAL | M_ERRNO) |
| 108 | 109 |
#define M_SOCKERR (M_FATAL | M_ERRNO_SOCK) |
| 109 | 110 |
#define M_SSLERR (M_FATAL | M_SSL) |
| 110 | 111 |
#define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR) |
| 111 |
-#define M_CLIENT (M_MSG_VIRT_OUT|M_NOMUTE) |
|
| 112 |
+#define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX) |
|
| 112 | 113 |
|
| 113 | 114 |
/* |
| 114 | 115 |
* Mute levels are designed to avoid large numbers of |
| ... | ... |
@@ -126,6 +127,11 @@ extern int x_msg_line_num; |
| 126 | 126 |
* log_level: verbosity level n (--verb n) must be >= log_level to print. |
| 127 | 127 |
* mute_level: don't print more than n (--mute n) consecutive messages at |
| 128 | 128 |
* a given mute level, or if 0 disable muting and print everything. |
| 129 |
+ * |
|
| 130 |
+ * Mask map: |
|
| 131 |
+ * Bits 0-3: log level |
|
| 132 |
+ * Bits 4-23: M_x flags |
|
| 133 |
+ * Bits 24-31: mute level |
|
| 129 | 134 |
*/ |
| 130 | 135 |
#define LOGLEV(log_level, mute_level, other) ((log_level) | ENCODE_MUTE_LEVEL(mute_level) | other) |
| 131 | 136 |
|
| ... | ... |
@@ -1558,6 +1558,10 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) |
| 1558 | 1558 |
|
| 1559 | 1559 |
to.plugins = c->plugins; |
| 1560 | 1560 |
|
| 1561 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1562 |
+ to.mda_context = &c->c2.mda_context; |
|
| 1563 |
+#endif |
|
| 1564 |
+ |
|
| 1561 | 1565 |
#if P2MP_SERVER |
| 1562 | 1566 |
to.auth_user_pass_verify_script = options->auth_user_pass_verify_script; |
| 1563 | 1567 |
to.auth_user_pass_verify_script_via_file = options->auth_user_pass_verify_script_via_file; |
| ... | ... |
@@ -2356,7 +2360,7 @@ open_plugins (struct context *c, const bool import_options, int init_point) |
| 2356 | 2356 |
{
|
| 2357 | 2357 |
unsigned int option_types_found = 0; |
| 2358 | 2358 |
if (config.list[i] && config.list[i]->value) |
| 2359 |
- options_plugin_import (&c->options, |
|
| 2359 |
+ options_string_import (&c->options, |
|
| 2360 | 2360 |
config.list[i]->value, |
| 2361 | 2361 |
D_IMPORT_ERRORS|M_OPTERR, |
| 2362 | 2362 |
OPT_P_DEFAULT & ~OPT_P_PLUGIN, |
| ... | ... |
@@ -2452,21 +2456,19 @@ open_management (struct context *c) |
| 2452 | 2452 |
{
|
| 2453 | 2453 |
if (c->options.management_addr) |
| 2454 | 2454 |
{
|
| 2455 |
+ unsigned int flags = c->options.management_flags; |
|
| 2456 |
+ if (c->options.mode == MODE_SERVER) |
|
| 2457 |
+ flags |= MF_SERVER; |
|
| 2455 | 2458 |
if (management_open (management, |
| 2456 | 2459 |
c->options.management_addr, |
| 2457 | 2460 |
c->options.management_port, |
| 2458 | 2461 |
c->options.management_user_pass, |
| 2459 |
- c->options.mode == MODE_SERVER, |
|
| 2460 |
- c->options.management_query_passwords, |
|
| 2461 | 2462 |
c->options.management_log_history_cache, |
| 2462 | 2463 |
c->options.management_echo_buffer_size, |
| 2463 | 2464 |
c->options.management_state_buffer_size, |
| 2464 |
- c->options.management_hold, |
|
| 2465 |
- c->options.management_signal, |
|
| 2466 |
- c->options.management_forget_disconnect, |
|
| 2467 |
- c->options.management_client, |
|
| 2468 | 2465 |
c->options.management_write_peer_info_file, |
| 2469 |
- c->options.remap_sigusr1)) |
|
| 2466 |
+ c->options.remap_sigusr1, |
|
| 2467 |
+ flags)) |
|
| 2470 | 2468 |
{
|
| 2471 | 2469 |
management_set_state (management, |
| 2472 | 2470 |
OPENVPN_STATE_CONNECTING, |
| ... | ... |
@@ -2792,6 +2794,11 @@ close_instance (struct context *c) |
| 2792 | 2792 |
/* close TUN/TAP device */ |
| 2793 | 2793 |
do_close_tun (c, false); |
| 2794 | 2794 |
|
| 2795 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 2796 |
+ if (management) |
|
| 2797 |
+ management_notify_client_close (management, &c->c2.mda_context, NULL); |
|
| 2798 |
+#endif |
|
| 2799 |
+ |
|
| 2795 | 2800 |
#ifdef ENABLE_PF |
| 2796 | 2801 |
pf_destroy_context (&c->c2.pf); |
| 2797 | 2802 |
#endif |
| ... | ... |
@@ -88,6 +88,15 @@ man_help () |
| 88 | 88 |
msg (M_CLIENT, "pkcs11-id-count : Get number of available PKCS#11 identities."); |
| 89 | 89 |
msg (M_CLIENT, "pkcs11-id-get index : Get PKCS#11 identity at index."); |
| 90 | 90 |
#endif |
| 91 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 92 |
+ msg (M_CLIENT, "client-auth CID KID : Authenticate client-id/key-id CID/KID (MULTILINE)"); |
|
| 93 |
+ msg (M_CLIENT, "client-auth-nt CID KID : Authenticate client-id/key-id CID/KID"); |
|
| 94 |
+ msg (M_CLIENT, "client-deny CID KID R : Deny auth client-id/key-id CID/KID with reason text R"); |
|
| 95 |
+ msg (M_CLIENT, "client-kill CID : Kill client instance CID"); |
|
| 96 |
+#ifdef MANAGEMENT_PF |
|
| 97 |
+ msg (M_CLIENT, "client-pf CID : Define packet filter for client CID (MULTILINE)"); |
|
| 98 |
+#endif |
|
| 99 |
+#endif |
|
| 91 | 100 |
msg (M_CLIENT, "signal s : Send signal s to daemon,"); |
| 92 | 101 |
msg (M_CLIENT, " s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2."); |
| 93 | 102 |
msg (M_CLIENT, "state [on|off] [N|all] : Like log, but show state history."); |
| ... | ... |
@@ -178,7 +187,7 @@ man_update_io_state (struct management *man) |
| 178 | 178 |
{
|
| 179 | 179 |
if (socket_defined (man->connection.sd_cli)) |
| 180 | 180 |
{
|
| 181 |
- if (output_list_defined (man->connection.out)) |
|
| 181 |
+ if (buffer_list_defined (man->connection.out)) |
|
| 182 | 182 |
{
|
| 183 | 183 |
man->connection.state = MS_CC_WAIT_WRITE; |
| 184 | 184 |
} |
| ... | ... |
@@ -195,7 +204,7 @@ man_output_list_push (struct management *man, const char *str) |
| 195 | 195 |
if (management_connected (man)) |
| 196 | 196 |
{
|
| 197 | 197 |
if (str) |
| 198 |
- output_list_push (man->connection.out, (const unsigned char *) str); |
|
| 198 |
+ buffer_list_push (man->connection.out, (const unsigned char *) str); |
|
| 199 | 199 |
man_update_io_state (man); |
| 200 | 200 |
if (!man->persist.standalone_disabled) |
| 201 | 201 |
{
|
| ... | ... |
@@ -672,12 +681,12 @@ man_hold (struct management *man, const char *cmd) |
| 672 | 672 |
{
|
| 673 | 673 |
if (streq (cmd, "on")) |
| 674 | 674 |
{
|
| 675 |
- man->settings.hold = true; |
|
| 675 |
+ man->settings.flags |= MF_HOLD; |
|
| 676 | 676 |
msg (M_CLIENT, "SUCCESS: hold flag set to ON"); |
| 677 | 677 |
} |
| 678 | 678 |
else if (streq (cmd, "off")) |
| 679 | 679 |
{
|
| 680 |
- man->settings.hold = false; |
|
| 680 |
+ man->settings.flags &= ~MF_HOLD; |
|
| 681 | 681 |
msg (M_CLIENT, "SUCCESS: hold flag set to OFF"); |
| 682 | 682 |
} |
| 683 | 683 |
else if (streq (cmd, "release")) |
| ... | ... |
@@ -691,9 +700,205 @@ man_hold (struct management *man, const char *cmd) |
| 691 | 691 |
} |
| 692 | 692 |
} |
| 693 | 693 |
else |
| 694 |
- msg (M_CLIENT, "SUCCESS: hold=%d", (int) man->settings.hold); |
|
| 694 |
+ msg (M_CLIENT, "SUCCESS: hold=%d", BOOL_CAST(man->settings.flags & MF_HOLD)); |
|
| 695 |
+} |
|
| 696 |
+ |
|
| 697 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 698 |
+ |
|
| 699 |
+static bool |
|
| 700 |
+parse_cid (const char *str, unsigned long *cid) |
|
| 701 |
+{
|
|
| 702 |
+ if (sscanf (str, "%lu", cid) == 1) |
|
| 703 |
+ return true; |
|
| 704 |
+ else |
|
| 705 |
+ {
|
|
| 706 |
+ msg (M_CLIENT, "ERROR: cannot parse CID"); |
|
| 707 |
+ return false; |
|
| 708 |
+ } |
|
| 709 |
+} |
|
| 710 |
+ |
|
| 711 |
+static bool |
|
| 712 |
+parse_kid (const char *str, unsigned int *kid) |
|
| 713 |
+{
|
|
| 714 |
+ if (sscanf (str, "%u", kid) == 1) |
|
| 715 |
+ return true; |
|
| 716 |
+ else |
|
| 717 |
+ {
|
|
| 718 |
+ msg (M_CLIENT, "ERROR: cannot parse KID"); |
|
| 719 |
+ return false; |
|
| 720 |
+ } |
|
| 721 |
+} |
|
| 722 |
+ |
|
| 723 |
+static void |
|
| 724 |
+in_extra_reset (struct man_connection *mc, const bool new) |
|
| 725 |
+{
|
|
| 726 |
+ if (mc) |
|
| 727 |
+ {
|
|
| 728 |
+ if (!new) |
|
| 729 |
+ {
|
|
| 730 |
+ mc->in_extra_cmd = IEC_UNDEF; |
|
| 731 |
+ mc->in_extra_cid = 0; |
|
| 732 |
+ mc->in_extra_kid = 0; |
|
| 733 |
+ } |
|
| 734 |
+ if (mc->in_extra) |
|
| 735 |
+ {
|
|
| 736 |
+ buffer_list_free (mc->in_extra); |
|
| 737 |
+ mc->in_extra = NULL; |
|
| 738 |
+ } |
|
| 739 |
+ if (new) |
|
| 740 |
+ mc->in_extra = buffer_list_new (0); |
|
| 741 |
+ } |
|
| 742 |
+} |
|
| 743 |
+ |
|
| 744 |
+static void |
|
| 745 |
+in_extra_dispatch (struct management *man) |
|
| 746 |
+{
|
|
| 747 |
+ switch (man->connection.in_extra_cmd) |
|
| 748 |
+ {
|
|
| 749 |
+ case IEC_CLIENT_AUTH: |
|
| 750 |
+ if (man->persist.callback.client_auth) |
|
| 751 |
+ {
|
|
| 752 |
+ const bool status = (*man->persist.callback.client_auth) |
|
| 753 |
+ (man->persist.callback.arg, |
|
| 754 |
+ man->connection.in_extra_cid, |
|
| 755 |
+ man->connection.in_extra_kid, |
|
| 756 |
+ true, |
|
| 757 |
+ NULL, |
|
| 758 |
+ man->connection.in_extra); |
|
| 759 |
+ man->connection.in_extra = NULL; |
|
| 760 |
+ if (status) |
|
| 761 |
+ {
|
|
| 762 |
+ msg (M_CLIENT, "SUCCESS: client-auth command succeeded"); |
|
| 763 |
+ } |
|
| 764 |
+ else |
|
| 765 |
+ {
|
|
| 766 |
+ msg (M_CLIENT, "ERROR: client-auth command failed"); |
|
| 767 |
+ } |
|
| 768 |
+ } |
|
| 769 |
+ else |
|
| 770 |
+ {
|
|
| 771 |
+ msg (M_CLIENT, "ERROR: The client-auth command is not supported by the current daemon mode"); |
|
| 772 |
+ } |
|
| 773 |
+ break; |
|
| 774 |
+#ifdef MANAGEMENT_PF |
|
| 775 |
+ case IEC_CLIENT_PF: |
|
| 776 |
+ if (man->persist.callback.client_pf) |
|
| 777 |
+ {
|
|
| 778 |
+ const bool status = (*man->persist.callback.client_pf) |
|
| 779 |
+ (man->persist.callback.arg, |
|
| 780 |
+ man->connection.in_extra_cid, |
|
| 781 |
+ man->connection.in_extra); |
|
| 782 |
+ man->connection.in_extra = NULL; |
|
| 783 |
+ if (status) |
|
| 784 |
+ {
|
|
| 785 |
+ msg (M_CLIENT, "SUCCESS: client-pf command succeeded"); |
|
| 786 |
+ } |
|
| 787 |
+ else |
|
| 788 |
+ {
|
|
| 789 |
+ msg (M_CLIENT, "ERROR: client-pf command failed"); |
|
| 790 |
+ } |
|
| 791 |
+ } |
|
| 792 |
+ else |
|
| 793 |
+ {
|
|
| 794 |
+ msg (M_CLIENT, "ERROR: The client-pf command is not supported by the current daemon mode"); |
|
| 795 |
+ } |
|
| 796 |
+ break; |
|
| 797 |
+#endif |
|
| 798 |
+ } |
|
| 799 |
+ in_extra_reset (&man->connection, false); |
|
| 695 | 800 |
} |
| 696 | 801 |
|
| 802 |
+static void |
|
| 803 |
+man_client_auth (struct management *man, const char *cid_str, const char *kid_str, const bool extra) |
|
| 804 |
+{
|
|
| 805 |
+ struct man_connection *mc = &man->connection; |
|
| 806 |
+ mc->in_extra_cid = 0; |
|
| 807 |
+ mc->in_extra_kid = 0; |
|
| 808 |
+ if (parse_cid (cid_str, &mc->in_extra_cid) |
|
| 809 |
+ && parse_kid (kid_str, &mc->in_extra_kid)) |
|
| 810 |
+ {
|
|
| 811 |
+ mc->in_extra_cmd = IEC_CLIENT_AUTH; |
|
| 812 |
+ in_extra_reset (mc, true); |
|
| 813 |
+ if (!extra) |
|
| 814 |
+ in_extra_dispatch (man); |
|
| 815 |
+ } |
|
| 816 |
+} |
|
| 817 |
+ |
|
| 818 |
+static void |
|
| 819 |
+man_client_deny (struct management *man, const char *cid_str, const char *kid_str, const char *reason) |
|
| 820 |
+{
|
|
| 821 |
+ unsigned long cid = 0; |
|
| 822 |
+ unsigned int kid = 0; |
|
| 823 |
+ if (parse_cid (cid_str, &cid) && parse_kid (kid_str, &kid)) |
|
| 824 |
+ {
|
|
| 825 |
+ if (man->persist.callback.client_auth) |
|
| 826 |
+ {
|
|
| 827 |
+ const bool status = (*man->persist.callback.client_auth) |
|
| 828 |
+ (man->persist.callback.arg, |
|
| 829 |
+ cid, |
|
| 830 |
+ kid, |
|
| 831 |
+ false, |
|
| 832 |
+ reason, |
|
| 833 |
+ NULL); |
|
| 834 |
+ if (status) |
|
| 835 |
+ {
|
|
| 836 |
+ msg (M_CLIENT, "SUCCESS: client-deny command succeeded"); |
|
| 837 |
+ } |
|
| 838 |
+ else |
|
| 839 |
+ {
|
|
| 840 |
+ msg (M_CLIENT, "ERROR: client-deny command failed"); |
|
| 841 |
+ } |
|
| 842 |
+ } |
|
| 843 |
+ else |
|
| 844 |
+ {
|
|
| 845 |
+ msg (M_CLIENT, "ERROR: The client-deny command is not supported by the current daemon mode"); |
|
| 846 |
+ } |
|
| 847 |
+ } |
|
| 848 |
+} |
|
| 849 |
+ |
|
| 850 |
+static void |
|
| 851 |
+man_client_kill (struct management *man, const char *cid_str) |
|
| 852 |
+{
|
|
| 853 |
+ unsigned long cid = 0; |
|
| 854 |
+ if (parse_cid (cid_str, &cid)) |
|
| 855 |
+ {
|
|
| 856 |
+ if (man->persist.callback.kill_by_cid) |
|
| 857 |
+ {
|
|
| 858 |
+ const bool status = (*man->persist.callback.kill_by_cid) (man->persist.callback.arg, cid); |
|
| 859 |
+ if (status) |
|
| 860 |
+ {
|
|
| 861 |
+ msg (M_CLIENT, "SUCCESS: client-kill command succeeded"); |
|
| 862 |
+ } |
|
| 863 |
+ else |
|
| 864 |
+ {
|
|
| 865 |
+ msg (M_CLIENT, "ERROR: client-kill command failed"); |
|
| 866 |
+ } |
|
| 867 |
+ } |
|
| 868 |
+ else |
|
| 869 |
+ {
|
|
| 870 |
+ msg (M_CLIENT, "ERROR: The client-kill command is not supported by the current daemon mode"); |
|
| 871 |
+ } |
|
| 872 |
+ } |
|
| 873 |
+} |
|
| 874 |
+ |
|
| 875 |
+#ifdef MANAGEMENT_PF |
|
| 876 |
+ |
|
| 877 |
+static void |
|
| 878 |
+man_client_pf (struct management *man, const char *cid_str) |
|
| 879 |
+{
|
|
| 880 |
+ struct man_connection *mc = &man->connection; |
|
| 881 |
+ mc->in_extra_cid = 0; |
|
| 882 |
+ mc->in_extra_kid = 0; |
|
| 883 |
+ if (parse_cid (cid_str, &mc->in_extra_cid)) |
|
| 884 |
+ {
|
|
| 885 |
+ mc->in_extra_cmd = IEC_CLIENT_PF; |
|
| 886 |
+ in_extra_reset (mc, true); |
|
| 887 |
+ } |
|
| 888 |
+} |
|
| 889 |
+ |
|
| 890 |
+#endif |
|
| 891 |
+#endif |
|
| 892 |
+ |
|
| 697 | 893 |
#define MN_AT_LEAST (1<<0) |
| 698 | 894 |
|
| 699 | 895 |
static bool |
| ... | ... |
@@ -867,6 +1072,35 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch |
| 867 | 867 |
if (man_need (man, p, 1, 0)) |
| 868 | 868 |
man_bytecount (man, atoi(p[1])); |
| 869 | 869 |
} |
| 870 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 871 |
+ else if (streq (p[0], "client-kill")) |
|
| 872 |
+ {
|
|
| 873 |
+ if (man_need (man, p, 1, 0)) |
|
| 874 |
+ man_client_kill (man, p[1]); |
|
| 875 |
+ } |
|
| 876 |
+ else if (streq (p[0], "client-deny")) |
|
| 877 |
+ {
|
|
| 878 |
+ if (man_need (man, p, 3, 0)) |
|
| 879 |
+ man_client_deny (man, p[1], p[2], p[3]); |
|
| 880 |
+ } |
|
| 881 |
+ else if (streq (p[0], "client-auth-nt")) |
|
| 882 |
+ {
|
|
| 883 |
+ if (man_need (man, p, 2, 0)) |
|
| 884 |
+ man_client_auth (man, p[1], p[2], false); |
|
| 885 |
+ } |
|
| 886 |
+ else if (streq (p[0], "client-auth")) |
|
| 887 |
+ {
|
|
| 888 |
+ if (man_need (man, p, 2, 0)) |
|
| 889 |
+ man_client_auth (man, p[1], p[2], true); |
|
| 890 |
+ } |
|
| 891 |
+#ifdef MANAGEMENT_PF |
|
| 892 |
+ else if (streq (p[0], "client-pf")) |
|
| 893 |
+ {
|
|
| 894 |
+ if (man_need (man, p, 1, 0)) |
|
| 895 |
+ man_client_pf (man, p[1]); |
|
| 896 |
+ } |
|
| 897 |
+#endif |
|
| 898 |
+#endif |
|
| 870 | 899 |
#ifdef ENABLE_PKCS11 |
| 871 | 900 |
else if (streq (p[0], "pkcs11-id-count")) |
| 872 | 901 |
{
|
| ... | ... |
@@ -999,7 +1233,7 @@ man_new_connection_post (struct management *man, const char *description) |
| 999 | 999 |
description, |
| 1000 | 1000 |
print_sockaddr (&man->settings.local, &gc)); |
| 1001 | 1001 |
|
| 1002 |
- output_list_reset (man->connection.out); |
|
| 1002 |
+ buffer_list_reset (man->connection.out); |
|
| 1003 | 1003 |
|
| 1004 | 1004 |
if (!man_password_needed (man)) |
| 1005 | 1005 |
man_welcome (man); |
| ... | ... |
@@ -1134,14 +1368,17 @@ man_reset_client_socket (struct management *man, const bool exiting) |
| 1134 | 1134 |
man_close_socket (man, man->connection.sd_cli); |
| 1135 | 1135 |
man->connection.sd_cli = SOCKET_UNDEFINED; |
| 1136 | 1136 |
command_line_reset (man->connection.in); |
| 1137 |
- output_list_reset (man->connection.out); |
|
| 1137 |
+ buffer_list_reset (man->connection.out); |
|
| 1138 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1139 |
+ in_extra_reset (&man->connection, false); |
|
| 1140 |
+#endif |
|
| 1138 | 1141 |
} |
| 1139 | 1142 |
if (!exiting) |
| 1140 | 1143 |
{
|
| 1141 |
- if (man->settings.management_forget_disconnect) |
|
| 1144 |
+ if (man->settings.flags & MF_FORGET_DISCONNECT) |
|
| 1142 | 1145 |
ssl_purge_auth (); |
| 1143 | 1146 |
|
| 1144 |
- if (man->settings.signal_on_disconnect) {
|
|
| 1147 |
+ if (man->settings.flags & MF_SIGNAL) {
|
|
| 1145 | 1148 |
int mysig = man_mod_signal (man, SIGUSR1); |
| 1146 | 1149 |
if (mysig >= 0) |
| 1147 | 1150 |
{
|
| ... | ... |
@@ -1150,7 +1387,7 @@ man_reset_client_socket (struct management *man, const bool exiting) |
| 1150 | 1150 |
} |
| 1151 | 1151 |
} |
| 1152 | 1152 |
|
| 1153 |
- if (man->settings.connect_as_client) |
|
| 1153 |
+ if (man->settings.flags & MF_CONNECT_AS_CLIENT) |
|
| 1154 | 1154 |
{
|
| 1155 | 1155 |
msg (D_MANAGEMENT, "MANAGEMENT: Triggering management exit"); |
| 1156 | 1156 |
throw_signal_soft (SIGTERM, "management-exit"); |
| ... | ... |
@@ -1170,6 +1407,9 @@ man_process_command (struct management *man, const char *line) |
| 1170 | 1170 |
|
| 1171 | 1171 |
CLEAR (parms); |
| 1172 | 1172 |
so = status_open (NULL, 0, -1, &man->persist.vout, 0); |
| 1173 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1174 |
+ in_extra_reset (&man->connection, false); |
|
| 1175 |
+#endif |
|
| 1173 | 1176 |
|
| 1174 | 1177 |
if (man_password_needed (man)) |
| 1175 | 1178 |
{
|
| ... | ... |
@@ -1243,7 +1483,7 @@ man_read (struct management *man) |
| 1243 | 1243 |
/* |
| 1244 | 1244 |
* Reset output object |
| 1245 | 1245 |
*/ |
| 1246 |
- output_list_reset (man->connection.out); |
|
| 1246 |
+ buffer_list_reset (man->connection.out); |
|
| 1247 | 1247 |
|
| 1248 | 1248 |
/* |
| 1249 | 1249 |
* process command line if complete |
| ... | ... |
@@ -1252,7 +1492,22 @@ man_read (struct management *man) |
| 1252 | 1252 |
const unsigned char *line; |
| 1253 | 1253 |
while ((line = command_line_get (man->connection.in))) |
| 1254 | 1254 |
{
|
| 1255 |
- man_process_command (man, (char *) line); |
|
| 1255 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1256 |
+ if (man->connection.in_extra) |
|
| 1257 |
+ {
|
|
| 1258 |
+ if (!strcmp ((char *)line, "END")) |
|
| 1259 |
+ {
|
|
| 1260 |
+ in_extra_dispatch (man); |
|
| 1261 |
+ in_extra_reset (&man->connection, false); |
|
| 1262 |
+ } |
|
| 1263 |
+ else |
|
| 1264 |
+ {
|
|
| 1265 |
+ buffer_list_push (man->connection.in_extra, line); |
|
| 1266 |
+ } |
|
| 1267 |
+ } |
|
| 1268 |
+ else |
|
| 1269 |
+#endif |
|
| 1270 |
+ man_process_command (man, (char *) line); |
|
| 1256 | 1271 |
if (man->connection.halt) |
| 1257 | 1272 |
break; |
| 1258 | 1273 |
command_line_next (man->connection.in); |
| ... | ... |
@@ -1289,14 +1544,14 @@ man_write (struct management *man) |
| 1289 | 1289 |
const int max_send = 256; |
| 1290 | 1290 |
int sent = 0; |
| 1291 | 1291 |
|
| 1292 |
- const struct buffer *buf = output_list_peek (man->connection.out); |
|
| 1292 |
+ const struct buffer *buf = buffer_list_peek (man->connection.out); |
|
| 1293 | 1293 |
if (buf && BLEN (buf)) |
| 1294 | 1294 |
{
|
| 1295 | 1295 |
const int len = min_int (max_send, BLEN (buf)); |
| 1296 | 1296 |
sent = send (man->connection.sd_cli, BPTR (buf), len, MSG_NOSIGNAL); |
| 1297 | 1297 |
if (sent >= 0) |
| 1298 | 1298 |
{
|
| 1299 |
- output_list_advance (man->connection.out, sent); |
|
| 1299 |
+ buffer_list_advance (man->connection.out, sent); |
|
| 1300 | 1300 |
} |
| 1301 | 1301 |
else if (sent < 0) |
| 1302 | 1302 |
{
|
| ... | ... |
@@ -1387,27 +1642,18 @@ man_settings_init (struct man_settings *ms, |
| 1387 | 1387 |
const char *addr, |
| 1388 | 1388 |
const int port, |
| 1389 | 1389 |
const char *pass_file, |
| 1390 |
- const bool server, |
|
| 1391 |
- const bool query_passwords, |
|
| 1392 | 1390 |
const int log_history_cache, |
| 1393 | 1391 |
const int echo_buffer_size, |
| 1394 | 1392 |
const int state_buffer_size, |
| 1395 |
- const bool hold, |
|
| 1396 |
- const bool signal_on_disconnect, |
|
| 1397 |
- const bool management_forget_disconnect, |
|
| 1398 |
- const bool connect_as_client, |
|
| 1399 | 1393 |
const char *write_peer_info_file, |
| 1400 |
- const int remap_sigusr1) |
|
| 1394 |
+ const int remap_sigusr1, |
|
| 1395 |
+ const unsigned int flags) |
|
| 1401 | 1396 |
{
|
| 1402 | 1397 |
if (!ms->defined) |
| 1403 | 1398 |
{
|
| 1404 | 1399 |
CLEAR (*ms); |
| 1405 | 1400 |
|
| 1406 |
- /* |
|
| 1407 |
- * Are we a server? If so, it will influence |
|
| 1408 |
- * the way we handle state transitions. |
|
| 1409 |
- */ |
|
| 1410 |
- ms->server = server; |
|
| 1401 |
+ ms->flags = flags; |
|
| 1411 | 1402 |
|
| 1412 | 1403 |
/* |
| 1413 | 1404 |
* Get username/password |
| ... | ... |
@@ -1415,34 +1661,6 @@ man_settings_init (struct man_settings *ms, |
| 1415 | 1415 |
if (pass_file) |
| 1416 | 1416 |
get_user_pass (&ms->up, pass_file, "Management", GET_USER_PASS_PASSWORD_ONLY); |
| 1417 | 1417 |
|
| 1418 |
- /* |
|
| 1419 |
- * Should OpenVPN query the management layer for |
|
| 1420 |
- * passwords? |
|
| 1421 |
- */ |
|
| 1422 |
- ms->up_query_passwords = query_passwords; |
|
| 1423 |
- |
|
| 1424 |
- /* |
|
| 1425 |
- * Should OpenVPN hibernate on startup? |
|
| 1426 |
- */ |
|
| 1427 |
- ms->hold = hold; |
|
| 1428 |
- |
|
| 1429 |
- /* |
|
| 1430 |
- * Should OpenVPN be signaled if management |
|
| 1431 |
- * disconnects? |
|
| 1432 |
- */ |
|
| 1433 |
- ms->signal_on_disconnect = signal_on_disconnect; |
|
| 1434 |
- |
|
| 1435 |
- /* |
|
| 1436 |
- * Should OpenVPN forget passwords when managmenet |
|
| 1437 |
- * session disconnects? |
|
| 1438 |
- */ |
|
| 1439 |
- ms->management_forget_disconnect = management_forget_disconnect; |
|
| 1440 |
- |
|
| 1441 |
- /* |
|
| 1442 |
- * Should OpenVPN connect to management interface as a client |
|
| 1443 |
- * rather than a server? |
|
| 1444 |
- */ |
|
| 1445 |
- ms->connect_as_client = connect_as_client; |
|
| 1446 | 1418 |
ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL); |
| 1447 | 1419 |
|
| 1448 | 1420 |
/* |
| ... | ... |
@@ -1456,7 +1674,7 @@ man_settings_init (struct man_settings *ms, |
| 1456 | 1456 |
* Run management over tunnel, or |
| 1457 | 1457 |
* separate channel? |
| 1458 | 1458 |
*/ |
| 1459 |
- if (streq (addr, "tunnel") && !connect_as_client) |
|
| 1459 |
+ if (streq (addr, "tunnel") && !(flags & MF_CONNECT_AS_CLIENT)) |
|
| 1460 | 1460 |
{
|
| 1461 | 1461 |
ms->management_over_tunnel = true; |
| 1462 | 1462 |
} |
| ... | ... |
@@ -1511,7 +1729,7 @@ man_connection_init (struct management *man) |
| 1511 | 1511 |
* command output from/to the socket. |
| 1512 | 1512 |
*/ |
| 1513 | 1513 |
man->connection.in = command_line_new (256); |
| 1514 |
- man->connection.out = output_list_new (0); |
|
| 1514 |
+ man->connection.out = buffer_list_new (0); |
|
| 1515 | 1515 |
|
| 1516 | 1516 |
/* |
| 1517 | 1517 |
* Initialize event set for standalone usage, when we are |
| ... | ... |
@@ -1525,7 +1743,7 @@ man_connection_init (struct management *man) |
| 1525 | 1525 |
/* |
| 1526 | 1526 |
* Listen/connect socket |
| 1527 | 1527 |
*/ |
| 1528 |
- if (man->settings.connect_as_client) |
|
| 1528 |
+ if (man->settings.flags & MF_CONNECT_AS_CLIENT) |
|
| 1529 | 1529 |
man_connect (man); |
| 1530 | 1530 |
else |
| 1531 | 1531 |
man_listen (man); |
| ... | ... |
@@ -1549,7 +1767,10 @@ man_connection_close (struct management *man) |
| 1549 | 1549 |
if (mc->in) |
| 1550 | 1550 |
command_line_free (mc->in); |
| 1551 | 1551 |
if (mc->out) |
| 1552 |
- output_list_free (mc->out); |
|
| 1552 |
+ buffer_list_free (mc->out); |
|
| 1553 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1554 |
+ in_extra_reset (&man->connection, false); |
|
| 1555 |
+#endif |
|
| 1553 | 1556 |
man_connection_clear (mc); |
| 1554 | 1557 |
} |
| 1555 | 1558 |
|
| ... | ... |
@@ -1574,17 +1795,12 @@ management_open (struct management *man, |
| 1574 | 1574 |
const char *addr, |
| 1575 | 1575 |
const int port, |
| 1576 | 1576 |
const char *pass_file, |
| 1577 |
- const bool server, |
|
| 1578 |
- const bool query_passwords, |
|
| 1579 | 1577 |
const int log_history_cache, |
| 1580 | 1578 |
const int echo_buffer_size, |
| 1581 | 1579 |
const int state_buffer_size, |
| 1582 |
- const bool hold, |
|
| 1583 |
- const bool signal_on_disconnect, |
|
| 1584 |
- const bool management_forget_disconnect, |
|
| 1585 |
- const bool connect_as_client, |
|
| 1586 | 1580 |
const char *write_peer_info_file, |
| 1587 |
- const int remap_sigusr1) |
|
| 1581 |
+ const int remap_sigusr1, |
|
| 1582 |
+ const unsigned int flags) |
|
| 1588 | 1583 |
{
|
| 1589 | 1584 |
bool ret = false; |
| 1590 | 1585 |
|
| ... | ... |
@@ -1596,17 +1812,12 @@ management_open (struct management *man, |
| 1596 | 1596 |
addr, |
| 1597 | 1597 |
port, |
| 1598 | 1598 |
pass_file, |
| 1599 |
- server, |
|
| 1600 |
- query_passwords, |
|
| 1601 | 1599 |
log_history_cache, |
| 1602 | 1600 |
echo_buffer_size, |
| 1603 | 1601 |
state_buffer_size, |
| 1604 |
- hold, |
|
| 1605 |
- signal_on_disconnect, |
|
| 1606 |
- management_forget_disconnect, |
|
| 1607 |
- connect_as_client, |
|
| 1608 | 1602 |
write_peer_info_file, |
| 1609 |
- remap_sigusr1); |
|
| 1603 |
+ remap_sigusr1, |
|
| 1604 |
+ flags); |
|
| 1610 | 1605 |
|
| 1611 | 1606 |
/* |
| 1612 | 1607 |
* The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE, |
| ... | ... |
@@ -1665,7 +1876,7 @@ management_set_state (struct management *man, |
| 1665 | 1665 |
const in_addr_t tun_local_ip, |
| 1666 | 1666 |
const in_addr_t tun_remote_ip) |
| 1667 | 1667 |
{
|
| 1668 |
- if (man->persist.state && (!man->settings.server || state < OPENVPN_STATE_CLIENT_BASE)) |
|
| 1668 |
+ if (man->persist.state && (!(man->settings.flags & MF_SERVER) || state < OPENVPN_STATE_CLIENT_BASE)) |
|
| 1669 | 1669 |
{
|
| 1670 | 1670 |
struct gc_arena gc = gc_new (); |
| 1671 | 1671 |
struct log_entry e; |
| ... | ... |
@@ -1697,6 +1908,79 @@ management_set_state (struct management *man, |
| 1697 | 1697 |
} |
| 1698 | 1698 |
} |
| 1699 | 1699 |
|
| 1700 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1701 |
+ |
|
| 1702 |
+static void |
|
| 1703 |
+man_output_env (const struct env_set *es) |
|
| 1704 |
+{
|
|
| 1705 |
+ if (es) |
|
| 1706 |
+ {
|
|
| 1707 |
+ struct env_item *e; |
|
| 1708 |
+ for (e = es->list; e != NULL; e = e->next) |
|
| 1709 |
+ {
|
|
| 1710 |
+ if (e->string) |
|
| 1711 |
+ msg (M_CLIENT, ">CLIENT:ENV,%s", e->string); |
|
| 1712 |
+ } |
|
| 1713 |
+ } |
|
| 1714 |
+ msg (M_CLIENT, ">CLIENT:ENV,END"); |
|
| 1715 |
+} |
|
| 1716 |
+ |
|
| 1717 |
+void |
|
| 1718 |
+management_notify_client_needing_auth (struct management *management, |
|
| 1719 |
+ const unsigned int mda_key_id, |
|
| 1720 |
+ struct man_def_auth_context *mdac, |
|
| 1721 |
+ const struct env_set *es) |
|
| 1722 |
+{
|
|
| 1723 |
+ if (!(mdac->flags & DAF_CONNECTION_CLOSED)) |
|
| 1724 |
+ {
|
|
| 1725 |
+ const char *mode = "CONNECT"; |
|
| 1726 |
+ if (mdac->flags & DAF_CONNECTION_ESTABLISHED) |
|
| 1727 |
+ mode = "REAUTH"; |
|
| 1728 |
+ msg (M_CLIENT, ">CLIENT:%s,%lu,%u", mode, mdac->cid, mda_key_id); |
|
| 1729 |
+ man_output_env (es); |
|
| 1730 |
+ mdac->flags |= DAF_INITIAL_AUTH; |
|
| 1731 |
+ } |
|
| 1732 |
+} |
|
| 1733 |
+ |
|
| 1734 |
+void |
|
| 1735 |
+management_connection_established (struct management *management, |
|
| 1736 |
+ struct man_def_auth_context *mdac) |
|
| 1737 |
+{
|
|
| 1738 |
+ mdac->flags |= DAF_CONNECTION_ESTABLISHED; |
|
| 1739 |
+} |
|
| 1740 |
+ |
|
| 1741 |
+void |
|
| 1742 |
+management_notify_client_close (struct management *management, |
|
| 1743 |
+ struct man_def_auth_context *mdac, |
|
| 1744 |
+ const struct env_set *es) |
|
| 1745 |
+{
|
|
| 1746 |
+ if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED)) |
|
| 1747 |
+ {
|
|
| 1748 |
+ msg (M_CLIENT, ">CLIENT:DISCONNECT,%lu", mdac->cid); |
|
| 1749 |
+ man_output_env (es); |
|
| 1750 |
+ mdac->flags |= DAF_CONNECTION_CLOSED; |
|
| 1751 |
+ } |
|
| 1752 |
+} |
|
| 1753 |
+ |
|
| 1754 |
+void |
|
| 1755 |
+management_learn_addr (struct management *management, |
|
| 1756 |
+ struct man_def_auth_context *mdac, |
|
| 1757 |
+ const struct mroute_addr *addr, |
|
| 1758 |
+ const bool primary) |
|
| 1759 |
+{
|
|
| 1760 |
+ struct gc_arena gc = gc_new (); |
|
| 1761 |
+ if ((mdac->flags & DAF_INITIAL_AUTH) && !(mdac->flags & DAF_CONNECTION_CLOSED)) |
|
| 1762 |
+ {
|
|
| 1763 |
+ msg (M_CLIENT, ">CLIENT:ADDRESS,%lu,%s,%d", |
|
| 1764 |
+ mdac->cid, |
|
| 1765 |
+ mroute_addr_print_ex (addr, MAPF_SUBNET, &gc), |
|
| 1766 |
+ BOOL_CAST (primary)); |
|
| 1767 |
+ } |
|
| 1768 |
+ gc_free (&gc); |
|
| 1769 |
+} |
|
| 1770 |
+ |
|
| 1771 |
+#endif |
|
| 1772 |
+ |
|
| 1700 | 1773 |
void |
| 1701 | 1774 |
management_echo (struct management *man, const char *string, const bool pull) |
| 1702 | 1775 |
{
|
| ... | ... |
@@ -2178,7 +2462,7 @@ management_query_user_pass (struct management *man, |
| 2178 | 2178 |
bool |
| 2179 | 2179 |
management_would_hold (struct management *man) |
| 2180 | 2180 |
{
|
| 2181 |
- return man->settings.hold && !man->persist.hold_release && man_standalone_ok (man); |
|
| 2181 |
+ return (man->settings.flags & MF_HOLD) && !man->persist.hold_release && man_standalone_ok (man); |
|
| 2182 | 2182 |
} |
| 2183 | 2183 |
|
| 2184 | 2184 |
/* |
| ... | ... |
@@ -2188,7 +2472,7 @@ management_would_hold (struct management *man) |
| 2188 | 2188 |
bool |
| 2189 | 2189 |
management_should_daemonize (struct management *man) |
| 2190 | 2190 |
{
|
| 2191 |
- return management_would_hold (man) || man->settings.up_query_passwords; |
|
| 2191 |
+ return management_would_hold (man) || (man->settings.flags & MF_QUERY_PASSWORDS); |
|
| 2192 | 2192 |
} |
| 2193 | 2193 |
|
| 2194 | 2194 |
/* |
| ... | ... |
@@ -2302,108 +2586,6 @@ command_line_next (struct command_line *cl) |
| 2302 | 2302 |
} |
| 2303 | 2303 |
|
| 2304 | 2304 |
/* |
| 2305 |
- * struct output_list |
|
| 2306 |
- */ |
|
| 2307 |
- |
|
| 2308 |
-struct output_list * |
|
| 2309 |
-output_list_new (const int max_size) |
|
| 2310 |
-{
|
|
| 2311 |
- struct output_list *ret; |
|
| 2312 |
- ALLOC_OBJ_CLEAR (ret, struct output_list); |
|
| 2313 |
- ret->max_size = max_size; |
|
| 2314 |
- ret->size = 0; |
|
| 2315 |
- return ret; |
|
| 2316 |
-} |
|
| 2317 |
- |
|
| 2318 |
-void |
|
| 2319 |
-output_list_free (struct output_list *ol) |
|
| 2320 |
-{
|
|
| 2321 |
- output_list_reset (ol); |
|
| 2322 |
- free (ol); |
|
| 2323 |
-} |
|
| 2324 |
- |
|
| 2325 |
-bool |
|
| 2326 |
-output_list_defined (const struct output_list *ol) |
|
| 2327 |
-{
|
|
| 2328 |
- return ol->head != NULL; |
|
| 2329 |
-} |
|
| 2330 |
- |
|
| 2331 |
-void |
|
| 2332 |
-output_list_reset (struct output_list *ol) |
|
| 2333 |
-{
|
|
| 2334 |
- struct output_entry *e = ol->head; |
|
| 2335 |
- while (e) |
|
| 2336 |
- {
|
|
| 2337 |
- struct output_entry *next = e->next; |
|
| 2338 |
- free_buf (&e->buf); |
|
| 2339 |
- free (e); |
|
| 2340 |
- e = next; |
|
| 2341 |
- } |
|
| 2342 |
- ol->head = ol->tail = NULL; |
|
| 2343 |
- ol->size = 0; |
|
| 2344 |
-} |
|
| 2345 |
- |
|
| 2346 |
-void |
|
| 2347 |
-output_list_push (struct output_list *ol, const unsigned char *str) |
|
| 2348 |
-{
|
|
| 2349 |
- if (!ol->max_size || ol->size < ol->max_size) |
|
| 2350 |
- {
|
|
| 2351 |
- struct output_entry *e; |
|
| 2352 |
- ALLOC_OBJ_CLEAR (e, struct output_entry); |
|
| 2353 |
- |
|
| 2354 |
- ++ol->size; |
|
| 2355 |
- if (ol->tail) |
|
| 2356 |
- {
|
|
| 2357 |
- ASSERT (ol->head); |
|
| 2358 |
- ol->tail->next = e; |
|
| 2359 |
- } |
|
| 2360 |
- else |
|
| 2361 |
- {
|
|
| 2362 |
- ASSERT (!ol->head); |
|
| 2363 |
- ol->head = e; |
|
| 2364 |
- } |
|
| 2365 |
- e->buf = string_alloc_buf ((const char *) str, NULL); |
|
| 2366 |
- ol->tail = e; |
|
| 2367 |
- } |
|
| 2368 |
-} |
|
| 2369 |
- |
|
| 2370 |
-const struct buffer * |
|
| 2371 |
-output_list_peek (struct output_list *ol) |
|
| 2372 |
-{
|
|
| 2373 |
- if (ol->head) |
|
| 2374 |
- return &ol->head->buf; |
|
| 2375 |
- else |
|
| 2376 |
- return NULL; |
|
| 2377 |
-} |
|
| 2378 |
- |
|
| 2379 |
-static void |
|
| 2380 |
-output_list_pop (struct output_list *ol) |
|
| 2381 |
-{
|
|
| 2382 |
- if (ol->head) |
|
| 2383 |
- {
|
|
| 2384 |
- struct output_entry *e = ol->head->next; |
|
| 2385 |
- free_buf (&ol->head->buf); |
|
| 2386 |
- free (ol->head); |
|
| 2387 |
- ol->head = e; |
|
| 2388 |
- --ol->size; |
|
| 2389 |
- if (!e) |
|
| 2390 |
- ol->tail = NULL; |
|
| 2391 |
- } |
|
| 2392 |
-} |
|
| 2393 |
- |
|
| 2394 |
-void |
|
| 2395 |
-output_list_advance (struct output_list *ol, int n) |
|
| 2396 |
-{
|
|
| 2397 |
- if (ol->head) |
|
| 2398 |
- {
|
|
| 2399 |
- struct buffer *buf = &ol->head->buf; |
|
| 2400 |
- ASSERT (buf_advance (buf, n)); |
|
| 2401 |
- if (!BLEN (buf)) |
|
| 2402 |
- output_list_pop (ol); |
|
| 2403 |
- } |
|
| 2404 |
-} |
|
| 2405 |
- |
|
| 2406 |
-/* |
|
| 2407 | 2305 |
* struct log_entry |
| 2408 | 2306 |
*/ |
| 2409 | 2307 |
|
| ... | ... |
@@ -30,6 +30,7 @@ |
| 30 | 30 |
#include "misc.h" |
| 31 | 31 |
#include "event.h" |
| 32 | 32 |
#include "socket.h" |
| 33 |
+#include "mroute.h" |
|
| 33 | 34 |
|
| 34 | 35 |
#define MANAGEMENT_VERSION 1 |
| 35 | 36 |
#define MANAGEMENT_N_PASSWORD_RETRIES 3 |
| ... | ... |
@@ -38,6 +39,22 @@ |
| 38 | 38 |
#define MANAGEMENT_STATE_BUFFER_SIZE 100 |
| 39 | 39 |
|
| 40 | 40 |
/* |
| 41 |
+ * Management-interface-based deferred authentication |
|
| 42 |
+ */ |
|
| 43 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 44 |
+struct man_def_auth_context {
|
|
| 45 |
+ unsigned long cid; |
|
| 46 |
+ |
|
| 47 |
+#define DAF_CONNECTION_ESTABLISHED (1<<0) |
|
| 48 |
+#define DAF_CONNECTION_CLOSED (1<<1) |
|
| 49 |
+#define DAF_INITIAL_AUTH (1<<2) |
|
| 50 |
+ unsigned int flags; |
|
| 51 |
+ |
|
| 52 |
+ unsigned int mda_key_id_counter; |
|
| 53 |
+}; |
|
| 54 |
+#endif |
|
| 55 |
+ |
|
| 56 |
+/* |
|
| 41 | 57 |
* Manage build-up of command line |
| 42 | 58 |
*/ |
| 43 | 59 |
struct command_line |
| ... | ... |
@@ -55,34 +72,6 @@ void command_line_reset (struct command_line *cl); |
| 55 | 55 |
void command_line_next (struct command_line *cl); |
| 56 | 56 |
|
| 57 | 57 |
/* |
| 58 |
- * Manage lists of output strings |
|
| 59 |
- */ |
|
| 60 |
- |
|
| 61 |
-struct output_entry |
|
| 62 |
-{
|
|
| 63 |
- struct buffer buf; |
|
| 64 |
- struct output_entry *next; |
|
| 65 |
-}; |
|
| 66 |
- |
|
| 67 |
-struct output_list |
|
| 68 |
-{
|
|
| 69 |
- struct output_entry *head; /* next item to pop/peek */ |
|
| 70 |
- struct output_entry *tail; /* last item pushed */ |
|
| 71 |
- int size; /* current number of entries */ |
|
| 72 |
- int max_size; /* maximum size list should grow to */ |
|
| 73 |
-}; |
|
| 74 |
- |
|
| 75 |
-struct output_list *output_list_new (const int max_size); |
|
| 76 |
-void output_list_free (struct output_list *ol); |
|
| 77 |
- |
|
| 78 |
-bool output_list_defined (const struct output_list *ol); |
|
| 79 |
-void output_list_reset (struct output_list *ol); |
|
| 80 |
- |
|
| 81 |
-void output_list_push (struct output_list *ol, const unsigned char *str); |
|
| 82 |
-const struct buffer *output_list_peek (struct output_list *ol); |
|
| 83 |
-void output_list_advance (struct output_list *ol, int n); |
|
| 84 |
- |
|
| 85 |
-/* |
|
| 86 | 58 |
* Manage log file history |
| 87 | 59 |
*/ |
| 88 | 60 |
|
| ... | ... |
@@ -148,7 +137,8 @@ log_history_capacity (const struct log_history *h) |
| 148 | 148 |
} |
| 149 | 149 |
|
| 150 | 150 |
/* |
| 151 |
- * Callbacks for 'status' and 'kill' commands |
|
| 151 |
+ * Callbacks for 'status' and 'kill' commands. |
|
| 152 |
+ * Also for management-based deferred authentication and packet filter. |
|
| 152 | 153 |
*/ |
| 153 | 154 |
struct management_callback |
| 154 | 155 |
{
|
| ... | ... |
@@ -158,6 +148,20 @@ struct management_callback |
| 158 | 158 |
int (*kill_by_cn) (void *arg, const char *common_name); |
| 159 | 159 |
int (*kill_by_addr) (void *arg, const in_addr_t addr, const int port); |
| 160 | 160 |
void (*delete_event) (void *arg, event_t event); |
| 161 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 162 |
+ bool (*kill_by_cid) (void *arg, const unsigned long cid); |
|
| 163 |
+ bool (*client_auth) (void *arg, |
|
| 164 |
+ const unsigned long cid, |
|
| 165 |
+ const unsigned int mda_key_id, |
|
| 166 |
+ const bool auth, |
|
| 167 |
+ const char *reason, |
|
| 168 |
+ struct buffer_list *cc_config); /* ownership transferred */ |
|
| 169 |
+#endif |
|
| 170 |
+#ifdef MANAGEMENT_PF |
|
| 171 |
+ bool (*client_pf) (void *arg, |
|
| 172 |
+ const unsigned long cid, |
|
| 173 |
+ struct buffer_list *pf_config); /* ownership transferred */ |
|
| 174 |
+#endif |
|
| 161 | 175 |
}; |
| 162 | 176 |
|
| 163 | 177 |
/* |
| ... | ... |
@@ -196,18 +200,13 @@ struct man_persist {
|
| 196 | 196 |
|
| 197 | 197 |
struct man_settings {
|
| 198 | 198 |
bool defined; |
| 199 |
+ unsigned int flags; /* MF_x flags */ |
|
| 199 | 200 |
struct openvpn_sockaddr local; |
| 200 |
- bool up_query_passwords; |
|
| 201 | 201 |
bool management_over_tunnel; |
| 202 | 202 |
struct user_pass up; |
| 203 | 203 |
int log_history_cache; |
| 204 | 204 |
int echo_buffer_size; |
| 205 | 205 |
int state_buffer_size; |
| 206 |
- bool server; |
|
| 207 |
- bool hold; |
|
| 208 |
- bool signal_on_disconnect; |
|
| 209 |
- bool management_forget_disconnect; |
|
| 210 |
- bool connect_as_client; |
|
| 211 | 206 |
char *write_peer_info_file; |
| 212 | 207 |
|
| 213 | 208 |
/* flags for handling the management interface "signal" command */ |
| ... | ... |
@@ -246,8 +245,17 @@ struct man_connection {
|
| 246 | 246 |
int password_tries; |
| 247 | 247 |
|
| 248 | 248 |
struct command_line *in; |
| 249 |
- struct output_list *out; |
|
| 250 |
- |
|
| 249 |
+ struct buffer_list *out; |
|
| 250 |
+ |
|
| 251 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 252 |
+# define IEC_UNDEF 0 |
|
| 253 |
+# define IEC_CLIENT_AUTH 1 |
|
| 254 |
+# define IEC_CLIENT_PF 2 |
|
| 255 |
+ int in_extra_cmd; |
|
| 256 |
+ unsigned long in_extra_cid; |
|
| 257 |
+ unsigned int in_extra_kid; |
|
| 258 |
+ struct buffer_list *in_extra; |
|
| 259 |
+#endif |
|
| 251 | 260 |
struct event_set *es; |
| 252 | 261 |
|
| 253 | 262 |
bool state_realtime; |
| ... | ... |
@@ -274,21 +282,29 @@ struct user_pass; |
| 274 | 274 |
|
| 275 | 275 |
struct management *management_init (void); |
| 276 | 276 |
|
| 277 |
+/* management_open flags */ |
|
| 278 |
+# define MF_SERVER (1<<0) |
|
| 279 |
+# define MF_QUERY_PASSWORDS (1<<1) |
|
| 280 |
+# define MF_HOLD (1<<2) |
|
| 281 |
+# define MF_SIGNAL (1<<3) |
|
| 282 |
+# define MF_FORGET_DISCONNECT (1<<4) |
|
| 283 |
+# define MF_CONNECT_AS_CLIENT (1<<5) |
|
| 284 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 285 |
+# define MF_CLIENT_AUTH (1<<6) |
|
| 286 |
+#endif |
|
| 287 |
+#ifdef MANAGEMENT_PF |
|
| 288 |
+# define MF_CLIENT_PF (1<<7) |
|
| 289 |
+#endif |
|
| 277 | 290 |
bool management_open (struct management *man, |
| 278 | 291 |
const char *addr, |
| 279 | 292 |
const int port, |
| 280 | 293 |
const char *pass_file, |
| 281 |
- const bool server, |
|
| 282 |
- const bool query_passwords, |
|
| 283 | 294 |
const int log_history_cache, |
| 284 | 295 |
const int echo_buffer_size, |
| 285 | 296 |
const int state_buffer_size, |
| 286 |
- const bool hold, |
|
| 287 |
- const bool signal_on_disconnect, |
|
| 288 |
- const bool management_forget_disconnect, |
|
| 289 |
- const bool connect_as_client, |
|
| 290 | 297 |
const char *write_peer_info_file, |
| 291 |
- const int remap_sigusr1); |
|
| 298 |
+ const int remap_sigusr1, |
|
| 299 |
+ const unsigned int flags); |
|
| 292 | 300 |
|
| 293 | 301 |
void management_close (struct management *man); |
| 294 | 302 |
|
| ... | ... |
@@ -316,6 +332,25 @@ bool management_hold (struct management *man); |
| 316 | 316 |
|
| 317 | 317 |
void management_event_loop_n_seconds (struct management *man, int sec); |
| 318 | 318 |
|
| 319 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 320 |
+void management_notify_client_needing_auth (struct management *management, |
|
| 321 |
+ const unsigned int auth_id, |
|
| 322 |
+ struct man_def_auth_context *mdac, |
|
| 323 |
+ const struct env_set *es); |
|
| 324 |
+ |
|
| 325 |
+void management_connection_established (struct management *management, |
|
| 326 |
+ struct man_def_auth_context *mdac); |
|
| 327 |
+ |
|
| 328 |
+void management_notify_client_close (struct management *management, |
|
| 329 |
+ struct man_def_auth_context *mdac, |
|
| 330 |
+ const struct env_set *es); |
|
| 331 |
+ |
|
| 332 |
+void management_learn_addr (struct management *management, |
|
| 333 |
+ struct man_def_auth_context *mdac, |
|
| 334 |
+ const struct mroute_addr *addr, |
|
| 335 |
+ const bool primary); |
|
| 336 |
+#endif |
|
| 337 |
+ |
|
| 319 | 338 |
static inline bool |
| 320 | 339 |
management_connected (const struct management *man) |
| 321 | 340 |
{
|
| ... | ... |
@@ -325,9 +360,25 @@ management_connected (const struct management *man) |
| 325 | 325 |
static inline bool |
| 326 | 326 |
management_query_user_pass_enabled (const struct management *man) |
| 327 | 327 |
{
|
| 328 |
- return man->settings.up_query_passwords; |
|
| 328 |
+ return BOOL_CAST(man->settings.flags & MF_QUERY_PASSWORDS); |
|
| 329 | 329 |
} |
| 330 | 330 |
|
| 331 |
+#ifdef MANAGEMENT_PF |
|
| 332 |
+static inline bool |
|
| 333 |
+management_enable_pf (const struct management *man) |
|
| 334 |
+{
|
|
| 335 |
+ return man && BOOL_CAST(man->settings.flags & MF_CLIENT_PF); |
|
| 336 |
+} |
|
| 337 |
+#endif |
|
| 338 |
+ |
|
| 339 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 340 |
+static inline bool |
|
| 341 |
+management_enable_def_auth (const struct management *man) |
|
| 342 |
+{
|
|
| 343 |
+ return man && BOOL_CAST(man->settings.flags & MF_CLIENT_AUTH); |
|
| 344 |
+} |
|
| 345 |
+#endif |
|
| 346 |
+ |
|
| 331 | 347 |
/* |
| 332 | 348 |
* OpenVPN tells the management layer what state it's in |
| 333 | 349 |
*/ |
| ... | ... |
@@ -25,13 +25,12 @@ Future versions of the management interface may allow out-of-band |
| 25 | 25 |
connections (i.e. not over the VPN) and secured with SSL/TLS. |
| 26 | 26 |
|
| 27 | 27 |
The management interface is enabled in the OpenVPN |
| 28 |
-configuration file using the following directives: |
|
| 28 |
+configuration file using the following directive: |
|
| 29 | 29 |
|
| 30 | 30 |
--management |
| 31 | 31 |
|
| 32 |
-See the man page for documentation on these directives. |
|
| 32 |
+See the man page for documentation on this and related |
|
| 33 |
+directives. |
|
| 33 | 34 |
|
| 34 | 35 |
Once OpenVPN has started with the management layer enabled, |
| 35 | 36 |
you can telnet to the management port (make sure to use |
| ... | ... |
@@ -444,6 +443,199 @@ Example: |
| 444 | 444 |
pkcs11-id-get 1 |
| 445 | 445 |
PKCS11ID-ENTRY:'1', ID:'<snip>', BLOB:'<snip>' |
| 446 | 446 |
|
| 447 |
+COMMAND -- client-auth (OpenVPN 2.1 or higher) |
|
| 448 |
+----------------------------------------------- |
|
| 449 |
+ |
|
| 450 |
+Authorize a ">CLIENT:CONNECT" or ">CLIENT:REAUTH" request and specify |
|
| 451 |
+"client-connect" configuration directives in a subsequent text block. |
|
| 452 |
+ |
|
| 453 |
+The OpenVPN server should have been started with the |
|
| 454 |
+--management-client-auth directive so that it will ask the management |
|
| 455 |
+interface to approve client connections. |
|
| 456 |
+ |
|
| 457 |
+ |
|
| 458 |
+ client-auth {CID} {KID}
|
|
| 459 |
+ line_1 |
|
| 460 |
+ line_2 |
|
| 461 |
+ ... |
|
| 462 |
+ line_n |
|
| 463 |
+ END |
|
| 464 |
+ |
|
| 465 |
+CID,KID -- client ID and Key ID. See documentation for ">CLIENT:" |
|
| 466 |
+notification for more info. |
|
| 467 |
+ |
|
| 468 |
+line_1 to line_n -- client-connect configuration text block, as would be |
|
| 469 |
+returned by a --client-connect script. The text block may be null, with |
|
| 470 |
+"END" immediately following the "client-auth" line (using a null text |
|
| 471 |
+block is equivalent to using the client-auth-nt command). |
|
| 472 |
+ |
|
| 473 |
+A client-connect configuration text block contains OpenVPN directives |
|
| 474 |
+that will be applied to the client instance object representing a newly |
|
| 475 |
+connected client. |
|
| 476 |
+ |
|
| 477 |
+COMMAND -- client-auth-nt (OpenVPN 2.1 or higher) |
|
| 478 |
+-------------------------------------------------- |
|
| 479 |
+ |
|
| 480 |
+Authorize a ">CLIENT:CONNECT" or ">CLIENT:REAUTH" request without specifying |
|
| 481 |
+client-connect configuration text. |
|
| 482 |
+ |
|
| 483 |
+The OpenVPN server should have been started with the |
|
| 484 |
+--management-client-auth directive so that it will ask the management |
|
| 485 |
+interface to approve client connections. |
|
| 486 |
+ |
|
| 487 |
+ client-auth-nt {CID} {KID}
|
|
| 488 |
+ |
|
| 489 |
+CID,KID -- client ID and Key ID. See documentation for ">CLIENT:" |
|
| 490 |
+notification for more info. |
|
| 491 |
+ |
|
| 492 |
+COMMAND -- client-deny (OpenVPN 2.1 or higher) |
|
| 493 |
+----------------------------------------------- |
|
| 494 |
+ |
|
| 495 |
+Deny a ">CLIENT:CONNECT" or ">CLIENT:REAUTH" request. |
|
| 496 |
+ |
|
| 497 |
+ client-deny {CID} {KID} "reason-text"
|
|
| 498 |
+ |
|
| 499 |
+CID,KID -- client ID and Key ID. See documentation for ">CLIENT:" |
|
| 500 |
+notification for more info. |
|
| 501 |
+ |
|
| 502 |
+reason-text: a human-readable message explaining why the authentication |
|
| 503 |
+request was denied. This message will be output to the OpenVPN log |
|
| 504 |
+file or syslog. |
|
| 505 |
+ |
|
| 506 |
+Note that client-deny denies a specific Key ID (pertaining to a |
|
| 507 |
+TLS renegotiation). A client-deny command issued in response to |
|
| 508 |
+an initial TLS key negotiation (notified by ">CLIENT:CONNECT") will |
|
| 509 |
+terminate the client session after returning "AUTH-FAILED" to the client. |
|
| 510 |
+On the other hand, a client-deny command issued in response to |
|
| 511 |
+a TLS renegotiation (">CLIENT:REAUTH") will invalidate the renegotiated
|
|
| 512 |
+key, however the TLS session associated with the currently active |
|
| 513 |
+key will continue to live for up to --tran-window seconds before |
|
| 514 |
+expiration. |
|
| 515 |
+ |
|
| 516 |
+To immediately kill a client session, use "client-kill". |
|
| 517 |
+ |
|
| 518 |
+COMMAND -- client-kill (OpenVPN 2.1 or higher) |
|
| 519 |
+----------------------------------------------- |
|
| 520 |
+ |
|
| 521 |
+Immediately kill a client instance by CID. |
|
| 522 |
+ |
|
| 523 |
+ client-kill {CID}
|
|
| 524 |
+ |
|
| 525 |
+CID -- client ID. See documentation for ">CLIENT:" notification for more |
|
| 526 |
+info. |
|
| 527 |
+ |
|
| 528 |
+COMMAND -- client-pf (OpenVPN 2.1 or higher) |
|
| 529 |
+--------------------------------------------- |
|
| 530 |
+ |
|
| 531 |
+Push a packet filter file to a specific client. |
|
| 532 |
+ |
|
| 533 |
+The OpenVPN server should have been started with the |
|
| 534 |
+--management-client-pf directive so that it will require that |
|
| 535 |
+VPN tunnel packets sent or received by client instances must |
|
| 536 |
+conform to that client's packet filter configuration. |
|
| 537 |
+ |
|
| 538 |
+ client-pf {CID}
|
|
| 539 |
+ line_1 |
|
| 540 |
+ line_2 |
|
| 541 |
+ ... |
|
| 542 |
+ line_n |
|
| 543 |
+ END |
|
| 544 |
+ |
|
| 545 |
+CID -- client ID. See documentation for ">CLIENT:" notification for |
|
| 546 |
+more info. |
|
| 547 |
+ |
|
| 548 |
+line_1 to line_n -- the packet filter configuration file for this |
|
| 549 |
+client. |
|
| 550 |
+ |
|
| 551 |
+Packet filter file grammar: |
|
| 552 |
+ |
|
| 553 |
+ [CLIENTS DROP|ACCEPT] |
|
| 554 |
+ {+|-}common_name1
|
|
| 555 |
+ {+|-}common_name2
|
|
| 556 |
+ . . . |
|
| 557 |
+ [SUBNETS DROP|ACCEPT] |
|
| 558 |
+ {+|-}subnet1
|
|
| 559 |
+ {+|-}subnet2
|
|
| 560 |
+ . . . |
|
| 561 |
+ [END] |
|
| 562 |
+ |
|
| 563 |
+ Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS | "unknown" |
|
| 564 |
+ |
|
| 565 |
+ CLIENTS refers to the set of clients (by their common-name) which |
|
| 566 |
+ this instance is allowed ('+') to connect to, or is excluded ('-')
|
|
| 567 |
+ from connecting to. Note that in the case of client-to-client |
|
| 568 |
+ connections, such communication must be allowed by the packet filter |
|
| 569 |
+ configuration files of both clients AND the --client-to-client |
|
| 570 |
+ directive must have been specified in the OpenVPN server config. |
|
| 571 |
+ |
|
| 572 |
+ SUBNETS refers to IP addresses or IP address subnets which this |
|
| 573 |
+ client instance may connect to ('+') or is excluded ('-') from
|
|
| 574 |
+ connecting to, and applies to IPv4 and ARP packets. The special |
|
| 575 |
+ "unknown" tag refers to packets of unknown type, i.e. a packet that |
|
| 576 |
+ is not IPv4 or ARP. |
|
| 577 |
+ |
|
| 578 |
+ DROP or ACCEPT defines default policy when there is no explicit match |
|
| 579 |
+ for a common-name or subnet. The [END] tag must exist. |
|
| 580 |
+ |
|
| 581 |
+ Notes: |
|
| 582 |
+ |
|
| 583 |
+ * The SUBNETS section currently only supports IPv4 addresses and |
|
| 584 |
+ subnets. |
|
| 585 |
+ |
|
| 586 |
+ * A given client or subnet rule applies to both incoming and |
|
| 587 |
+ outgoing packets. |
|
| 588 |
+ |
|
| 589 |
+ * The CLIENTS list is order-invariant. Because the list is stored |
|
| 590 |
+ as a hash-table, the order of the list does not affect its function. |
|
| 591 |
+ |
|
| 592 |
+ * The SUBNETS table is scanned sequentially, and the first item to |
|
| 593 |
+ match is chosen. Therefore the SUBNETS table is NOT order-invariant. |
|
| 594 |
+ |
|
| 595 |
+ * No client-to-client communication is allowed unless the |
|
| 596 |
+ --client-to-client configuration directive is enabled AND |
|
| 597 |
+ the CLIENTS list of BOTH clients allows the communication. |
|
| 598 |
+ |
|
| 599 |
+Example packet filter spec, as transmitted to the management interface: |
|
| 600 |
+ |
|
| 601 |
+ client-pf 42 |
|
| 602 |
+ [CLIENTS ACCEPT] |
|
| 603 |
+ -accounting |
|
| 604 |
+ -enigma |
|
| 605 |
+ [SUBNETS DROP] |
|
| 606 |
+ -10.46.79.9 |
|
| 607 |
+ +10.0.0.0/8 |
|
| 608 |
+ [END] |
|
| 609 |
+ END |
|
| 610 |
+ |
|
| 611 |
+The above example sets the packet filter policy for the client |
|
| 612 |
+identified by CID=42. This client may connect to all other clients |
|
| 613 |
+except those having a common name of "accounting" or "enigma". |
|
| 614 |
+The client may only interact with external IP addresses in the |
|
| 615 |
+10.0.0.0/8 subnet, however access to 10.46.79.9 is specifically |
|
| 616 |
+excluded. |
|
| 617 |
+ |
|
| 618 |
+Another example packet filter spec, as transmitted to the |
|
| 619 |
+management interface: |
|
| 620 |
+ |
|
| 621 |
+ client-pf 99 |
|
| 622 |
+ [CLIENTS DENY] |
|
| 623 |
+ +public |
|
| 624 |
+ [SUBNETS ACCEPT] |
|
| 625 |
+ +10.10.0.1 |
|
| 626 |
+ -10.0.0.0/8 |
|
| 627 |
+ -unknown |
|
| 628 |
+ [END] |
|
| 629 |
+ END |
|
| 630 |
+ |
|
| 631 |
+The above example sets the packet filter policy for the client |
|
| 632 |
+identified by CID=99. This client may not connect to any other |
|
| 633 |
+clients except those having a common name of "public". It may |
|
| 634 |
+interact with any external IP address except those in the |
|
| 635 |
+10.0.0.0/8 netblock. However interaction with one address in |
|
| 636 |
+the 10.0.0.0/8 netblock is allowed: 10.10.0.1. Also, the client |
|
| 637 |
+may not interact with external IP addresses using an "unknown" |
|
| 638 |
+protocol (i.e. one that is not IPv4 or ARP). |
|
| 639 |
+ |
|
| 447 | 640 |
OUTPUT FORMAT |
| 448 | 641 |
------------- |
| 449 | 642 |
|
| ... | ... |
@@ -454,7 +646,7 @@ OUTPUT FORMAT |
| 454 | 454 |
the last line will be "END". |
| 455 | 455 |
|
| 456 | 456 |
(3) Real-time messages will be in the form ">[source]:[text]", |
| 457 |
- where source is "ECHO", "FATAL", "HOLD", "INFO", "LOG", |
|
| 457 |
+ where source is "CLIENT", "ECHO", "FATAL", "HOLD", "INFO", "LOG", |
|
| 458 | 458 |
"NEED-OK", "PASSWORD", or "STATE". |
| 459 | 459 |
|
| 460 | 460 |
REAL-TIME MESSAGE FORMAT |
| ... | ... |
@@ -469,6 +661,12 @@ column and are immediately followed by a type keyword |
| 469 | 469 |
indicating the type of real-time message. The following |
| 470 | 470 |
types are currently defined: |
| 471 | 471 |
|
| 472 |
+CLIENT -- Notification of client connections and disconnections |
|
| 473 |
+ on an OpenVPN server. Enabled when OpenVPN is started |
|
| 474 |
+ with the --management-client-auth option. CLIENT |
|
| 475 |
+ notifications may be multi-line. See "The CLIENT |
|
| 476 |
+ notification" section below for detailed info. |
|
| 477 |
+ |
|
| 472 | 478 |
ECHO -- Echo messages as controlled by the "echo" command. |
| 473 | 479 |
|
| 474 | 480 |
FATAL -- A fatal error which is output to the log file just |
| ... | ... |
@@ -497,6 +695,60 @@ PASSWORD -- Used to tell the management client that OpenVPN |
| 497 | 497 |
STATE -- Shows the current OpenVPN state, as controlled |
| 498 | 498 |
by the "state" command. |
| 499 | 499 |
|
| 500 |
+The CLIENT notification |
|
| 501 |
+----------------------- |
|
| 502 |
+ |
|
| 503 |
+The ">CLIENT:" notification is enabled by the --management-client-auth |
|
| 504 |
+OpenVPN configuration directive that gives the management interface client |
|
| 505 |
+the responsibility to authenticate OpenVPN clients after their client |
|
| 506 |
+certificate has been verified. CLIENT notifications may be multi-line, and |
|
| 507 |
+the sequentiality of a given CLIENT notification, its associated environmental |
|
| 508 |
+variables, and the terminating ">CLIENT:ENV,END" line are guaranteed to be |
|
| 509 |
+atomic. |
|
| 510 |
+ |
|
| 511 |
+CLIENT notification types: |
|
| 512 |
+ |
|
| 513 |
+(1) Notify new client connection ("CONNECT") or existing client TLS session
|
|
| 514 |
+ renegotiation ("REAUTH"). Information about the client is provided
|
|
| 515 |
+ by a list of environmental variables which are documented in the OpenVPN |
|
| 516 |
+ man page. The environmental variables passed are equivalent to those |
|
| 517 |
+ that would be passed to an --auth-user-pass-verify script. |
|
| 518 |
+ |
|
| 519 |
+ >CLIENT:CONNECT|REAUTH,{CID},{KID}
|
|
| 520 |
+ >CLIENT:ENV,name1=val1 |
|
| 521 |
+ >CLIENT:ENV,name2=val2 |
|
| 522 |
+ >CLIENT:ENV,... |
|
| 523 |
+ >CLIENT:ENV,END |
|
| 524 |
+ |
|
| 525 |
+(2) Notify existing client disconnection. The environmental variables passed |
|
| 526 |
+ are equivalent to those that would be passed to a --client-disconnect |
|
| 527 |
+ script. |
|
| 528 |
+ |
|
| 529 |
+ >CLIENT:DISCONNECT,{CID}
|
|
| 530 |
+ >CLIENT:ENV,name1=val1 |
|
| 531 |
+ >CLIENT:ENV,name2=val2 |
|
| 532 |
+ >CLIENT:ENV,... |
|
| 533 |
+ >CLIENT:ENV,END |
|
| 534 |
+ |
|
| 535 |
+(3) Notify that a particular virtual address or subnet |
|
| 536 |
+ is now associated with a specific client. |
|
| 537 |
+ |
|
| 538 |
+ >CLIENT:ADDRESS,{CID},{ADDR},{PRI}
|
|
| 539 |
+ |
|
| 540 |
+Variables: |
|
| 541 |
+ |
|
| 542 |
+CID -- Client ID, numerical ID for each connecting client, sequence = 0,1,2,... |
|
| 543 |
+KID -- Key ID, numerical ID for the key associated with a given client TLS session, |
|
| 544 |
+ sequence = 0,1,2,... |
|
| 545 |
+PRI -- Primary (1) or Secondary (0) VPN address/subnet. All clients have at least |
|
| 546 |
+ one primary IP address. Secondary address/subnets are associated with |
|
| 547 |
+ client-specific "iroute" directives. |
|
| 548 |
+ADDR -- IPv4 address/subnet in the form 1.2.3.4 or 1.2.3.0/255.255.255.0 |
|
| 549 |
+ |
|
| 550 |
+In the unlikely scenario of an extremely long-running OpenVPN server, |
|
| 551 |
+CID and KID should be assumed to recycle to 0 after (2^32)-1, however this |
|
| 552 |
+recycling behavior is guaranteed to be collision-free. |
|
| 553 |
+ |
|
| 500 | 554 |
Command Parsing |
| 501 | 555 |
--------------- |
| 502 | 556 |
|
| ... | ... |
@@ -76,87 +76,144 @@ mroute_learnable_address (const struct mroute_addr *addr) |
| 76 | 76 |
return not_all_zeros && not_all_ones && !is_mac_mcast_maddr (addr); |
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 |
-/* |
|
| 80 |
- * Given a raw packet in buf, return the src and dest |
|
| 81 |
- * addresses of the packet. |
|
| 82 |
- */ |
|
| 79 |
+static inline void |
|
| 80 |
+mroute_get_in_addr_t (struct mroute_addr *ma, const in_addr_t src, unsigned int mask) |
|
| 81 |
+{
|
|
| 82 |
+ if (ma) |
|
| 83 |
+ {
|
|
| 84 |
+ ma->type = MR_ADDR_IPV4 | mask; |
|
| 85 |
+ ma->netbits = 0; |
|
| 86 |
+ ma->len = 4; |
|
| 87 |
+ *(in_addr_t*)ma->addr = src; |
|
| 88 |
+ } |
|
| 89 |
+} |
|
| 90 |
+ |
|
| 91 |
+static inline bool |
|
| 92 |
+mroute_is_mcast (const in_addr_t addr) |
|
| 93 |
+{
|
|
| 94 |
+ return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK)); |
|
| 95 |
+} |
|
| 96 |
+ |
|
| 97 |
+#ifdef ENABLE_PF |
|
| 98 |
+ |
|
| 99 |
+static unsigned int |
|
| 100 |
+mroute_extract_addr_arp (struct mroute_addr *src, |
|
| 101 |
+ struct mroute_addr *dest, |
|
| 102 |
+ const struct buffer *buf) |
|
| 103 |
+{
|
|
| 104 |
+ unsigned int ret = 0; |
|
| 105 |
+ if (BLEN (buf) >= (int) sizeof (struct openvpn_arp)) |
|
| 106 |
+ {
|
|
| 107 |
+ const struct openvpn_arp *arp = (const struct openvpn_arp *) BPTR (buf); |
|
| 108 |
+ if (arp->mac_addr_type == htons(0x0001) |
|
| 109 |
+ && arp->proto_addr_type == htons(0x0800) |
|
| 110 |
+ && arp->mac_addr_size == 0x06 |
|
| 111 |
+ && arp->proto_addr_size == 0x04) |
|
| 112 |
+ {
|
|
| 113 |
+ mroute_get_in_addr_t (src, arp->ip_src, MR_ARP); |
|
| 114 |
+ mroute_get_in_addr_t (dest, arp->ip_dest, MR_ARP); |
|
| 115 |
+ |
|
| 116 |
+ /* multicast packet? */ |
|
| 117 |
+ if (mroute_is_mcast (arp->ip_dest)) |
|
| 118 |
+ ret |= MROUTE_EXTRACT_MCAST; |
|
| 119 |
+ |
|
| 120 |
+ ret |= MROUTE_EXTRACT_SUCCEEDED; |
|
| 121 |
+ } |
|
| 122 |
+ } |
|
| 123 |
+ return ret; |
|
| 124 |
+} |
|
| 125 |
+ |
|
| 126 |
+#endif |
|
| 127 |
+ |
|
| 83 | 128 |
unsigned int |
| 84 |
-mroute_extract_addr_from_packet (struct mroute_addr *src, |
|
| 85 |
- struct mroute_addr *dest, |
|
| 86 |
- struct buffer *buf, |
|
| 87 |
- int tunnel_type) |
|
| 129 |
+mroute_extract_addr_ipv4 (struct mroute_addr *src, |
|
| 130 |
+ struct mroute_addr *dest, |
|
| 131 |
+ const struct buffer *buf) |
|
| 88 | 132 |
{
|
| 89 | 133 |
unsigned int ret = 0; |
| 90 |
- verify_align_4 (buf); |
|
| 91 |
- if (tunnel_type == DEV_TYPE_TUN) |
|
| 134 |
+ if (BLEN (buf) >= 1) |
|
| 92 | 135 |
{
|
| 93 |
- if (BLEN (buf) >= 1) |
|
| 136 |
+ switch (OPENVPN_IPH_GET_VER (*BPTR(buf))) |
|
| 94 | 137 |
{
|
| 95 |
- switch (OPENVPN_IPH_GET_VER (*BPTR(buf))) |
|
| 138 |
+ case 4: |
|
| 139 |
+ if (BLEN (buf) >= (int) sizeof (struct openvpn_iphdr)) |
|
| 96 | 140 |
{
|
| 97 |
- case 4: |
|
| 98 |
- if (BLEN (buf) >= (int) sizeof (struct openvpn_iphdr)) |
|
| 99 |
- {
|
|
| 100 |
- const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR (buf); |
|
| 101 |
- if (src) |
|
| 102 |
- {
|
|
| 103 |
- src->type = MR_ADDR_IPV4; |
|
| 104 |
- src->netbits = 0; |
|
| 105 |
- src->len = 4; |
|
| 106 |
- memcpy (src->addr, &ip->saddr, 4); |
|
| 107 |
- } |
|
| 108 |
- if (dest) |
|
| 109 |
- {
|
|
| 110 |
- dest->type = MR_ADDR_IPV4; |
|
| 111 |
- dest->netbits = 0; |
|
| 112 |
- dest->len = 4; |
|
| 113 |
- memcpy (dest->addr, &ip->daddr, 4); |
|
| 114 |
- |
|
| 115 |
- /* mcast address? */ |
|
| 116 |
- if ((ip->daddr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK)) |
|
| 117 |
- ret |= MROUTE_EXTRACT_MCAST; |
|
| 118 |
- |
|
| 119 |
- /* IGMP message? */ |
|
| 120 |
- if (ip->protocol == OPENVPN_IPPROTO_IGMP) |
|
| 121 |
- ret |= MROUTE_EXTRACT_IGMP; |
|
| 122 |
- } |
|
| 123 |
- ret |= MROUTE_EXTRACT_SUCCEEDED; |
|
| 124 |
- } |
|
| 125 |
- break; |
|
| 126 |
- case 6: |
|
| 127 |
- {
|
|
| 128 |
- msg (M_WARN, "Need IPv6 code in mroute_extract_addr_from_packet"); |
|
| 129 |
- break; |
|
| 130 |
- } |
|
| 141 |
+ const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR (buf); |
|
| 142 |
+ |
|
| 143 |
+ mroute_get_in_addr_t (src, ip->saddr, 0); |
|
| 144 |
+ mroute_get_in_addr_t (dest, ip->daddr, 0); |
|
| 145 |
+ |
|
| 146 |
+ /* multicast packet? */ |
|
| 147 |
+ if (mroute_is_mcast (ip->daddr)) |
|
| 148 |
+ ret |= MROUTE_EXTRACT_MCAST; |
|
| 149 |
+ |
|
| 150 |
+ /* IGMP message? */ |
|
| 151 |
+ if (ip->protocol == OPENVPN_IPPROTO_IGMP) |
|
| 152 |
+ ret |= MROUTE_EXTRACT_IGMP; |
|
| 153 |
+ |
|
| 154 |
+ ret |= MROUTE_EXTRACT_SUCCEEDED; |
|
| 131 | 155 |
} |
| 156 |
+ break; |
|
| 157 |
+ case 6: |
|
| 158 |
+ {
|
|
| 159 |
+ msg (M_WARN, "Need IPv6 code in mroute_extract_addr_from_packet"); |
|
| 160 |
+ break; |
|
| 161 |
+ } |
|
| 132 | 162 |
} |
| 133 | 163 |
} |
| 134 |
- else if (tunnel_type == DEV_TYPE_TAP) |
|
| 164 |
+ return ret; |
|
| 165 |
+} |
|
| 166 |
+ |
|
| 167 |
+unsigned int |
|
| 168 |
+mroute_extract_addr_ether (struct mroute_addr *src, |
|
| 169 |
+ struct mroute_addr *dest, |
|
| 170 |
+ struct mroute_addr *esrc, |
|
| 171 |
+ struct mroute_addr *edest, |
|
| 172 |
+ const struct buffer *buf) |
|
| 173 |
+{
|
|
| 174 |
+ unsigned int ret = 0; |
|
| 175 |
+ if (BLEN (buf) >= (int) sizeof (struct openvpn_ethhdr)) |
|
| 135 | 176 |
{
|
| 136 |
- if (BLEN (buf) >= (int) sizeof (struct openvpn_ethhdr)) |
|
| 177 |
+ const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR (buf); |
|
| 178 |
+ if (src) |
|
| 137 | 179 |
{
|
| 138 |
- const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR (buf); |
|
| 139 |
- if (src) |
|
| 140 |
- {
|
|
| 141 |
- src->type = MR_ADDR_ETHER; |
|
| 142 |
- src->netbits = 0; |
|
| 143 |
- src->len = 6; |
|
| 144 |
- memcpy (src->addr, eth->source, 6); |
|
| 145 |
- } |
|
| 146 |
- if (dest) |
|
| 180 |
+ src->type = MR_ADDR_ETHER; |
|
| 181 |
+ src->netbits = 0; |
|
| 182 |
+ src->len = 6; |
|
| 183 |
+ memcpy (src->addr, eth->source, 6); |
|
| 184 |
+ } |
|
| 185 |
+ if (dest) |
|
| 186 |
+ {
|
|
| 187 |
+ dest->type = MR_ADDR_ETHER; |
|
| 188 |
+ dest->netbits = 0; |
|
| 189 |
+ dest->len = 6; |
|
| 190 |
+ memcpy (dest->addr, eth->dest, 6); |
|
| 191 |
+ |
|
| 192 |
+ /* ethernet broadcast/multicast packet? */ |
|
| 193 |
+ if (is_mac_mcast_addr (eth->dest)) |
|
| 194 |
+ ret |= MROUTE_EXTRACT_BCAST; |
|
| 195 |
+ } |
|
| 196 |
+ |
|
| 197 |
+ ret |= MROUTE_EXTRACT_SUCCEEDED; |
|
| 198 |
+ |
|
| 199 |
+#ifdef ENABLE_PF |
|
| 200 |
+ if (esrc || edest) |
|
| 201 |
+ {
|
|
| 202 |
+ struct buffer b = *buf; |
|
| 203 |
+ if (buf_advance (&b, sizeof (struct openvpn_ethhdr))) |
|
| 147 | 204 |
{
|
| 148 |
- dest->type = MR_ADDR_ETHER; |
|
| 149 |
- dest->netbits = 0; |
|
| 150 |
- dest->len = 6; |
|
| 151 |
- memcpy (dest->addr, eth->dest, 6); |
|
| 152 |
- |
|
| 153 |
- /* ethernet broadcast/multicast packet? */ |
|
| 154 |
- if (is_mac_mcast_addr (eth->dest)) |
|
| 155 |
- ret |= MROUTE_EXTRACT_BCAST; |
|
| 205 |
+ switch (ntohs (eth->proto)) |
|
| 206 |
+ {
|
|
| 207 |
+ case OPENVPN_ETH_P_IPV4: |
|
| 208 |
+ ret |= (mroute_extract_addr_ipv4 (esrc, edest, &b) << MROUTE_SEC_SHIFT); |
|
| 209 |
+ break; |
|
| 210 |
+ case OPENVPN_ETH_P_ARP: |
|
| 211 |
+ ret |= (mroute_extract_addr_arp (esrc, edest, &b) << MROUTE_SEC_SHIFT); |
|
| 212 |
+ break; |
|
| 213 |
+ } |
|
| 156 | 214 |
} |
| 157 |
- |
|
| 158 |
- ret |= MROUTE_EXTRACT_SUCCEEDED; |
|
| 159 | 215 |
} |
| 216 |
+#endif |
|
| 160 | 217 |
} |
| 161 | 218 |
return ret; |
| 162 | 219 |
} |
| ... | ... |
@@ -229,6 +286,14 @@ const char * |
| 229 | 229 |
mroute_addr_print (const struct mroute_addr *ma, |
| 230 | 230 |
struct gc_arena *gc) |
| 231 | 231 |
{
|
| 232 |
+ return mroute_addr_print_ex (ma, MAPF_IA_EMPTY_IF_UNDEF, gc); |
|
| 233 |
+} |
|
| 234 |
+ |
|
| 235 |
+const char * |
|
| 236 |
+mroute_addr_print_ex (const struct mroute_addr *ma, |
|
| 237 |
+ const unsigned int flags, |
|
| 238 |
+ struct gc_arena *gc) |
|
| 239 |
+{
|
|
| 232 | 240 |
struct buffer out = alloc_buf_gc (64, gc); |
| 233 | 241 |
if (ma) |
| 234 | 242 |
{
|
| ... | ... |
@@ -249,9 +314,19 @@ mroute_addr_print (const struct mroute_addr *ma, |
| 249 | 249 |
addr = buf_read_u32 (&buf, &status); |
| 250 | 250 |
if (status) |
| 251 | 251 |
{
|
| 252 |
- buf_printf (&out, "%s", print_in_addr_t (addr, IA_EMPTY_IF_UNDEF, gc)); |
|
| 252 |
+ if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP)) |
|
| 253 |
+ buf_printf (&out, "ARP/"); |
|
| 254 |
+ buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc)); |
|
| 253 | 255 |
if (maddr.type & MR_WITH_NETBITS) |
| 254 |
- buf_printf (&out, "/%d", maddr.netbits); |
|
| 256 |
+ {
|
|
| 257 |
+ if (flags & MAPF_SUBNET) |
|
| 258 |
+ {
|
|
| 259 |
+ const in_addr_t netmask = netbits_to_netmask (maddr.netbits); |
|
| 260 |
+ buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc)); |
|
| 261 |
+ } |
|
| 262 |
+ else |
|
| 263 |
+ buf_printf (&out, "/%d", maddr.netbits); |
|
| 264 |
+ } |
|
| 255 | 265 |
} |
| 256 | 266 |
if (maddr.type & MR_WITH_PORT) |
| 257 | 267 |
{
|
| ... | ... |
@@ -35,10 +35,18 @@ |
| 35 | 35 |
#define IP_MCAST_NETWORK ((in_addr_t)224<<24) |
| 36 | 36 |
|
| 37 | 37 |
/* Return status values for mroute_extract_addr_from_packet */ |
| 38 |
-#define MROUTE_EXTRACT_SUCCEEDED (1<<1) |
|
| 39 |
-#define MROUTE_EXTRACT_BCAST (1<<2) |
|
| 40 |
-#define MROUTE_EXTRACT_MCAST (1<<3) |
|
| 41 |
-#define MROUTE_EXTRACT_IGMP (1<<4) |
|
| 38 |
+ |
|
| 39 |
+#define MROUTE_EXTRACT_SUCCEEDED (1<<0) |
|
| 40 |
+#define MROUTE_EXTRACT_BCAST (1<<1) |
|
| 41 |
+#define MROUTE_EXTRACT_MCAST (1<<2) |
|
| 42 |
+#define MROUTE_EXTRACT_IGMP (1<<3) |
|
| 43 |
+ |
|
| 44 |
+#define MROUTE_SEC_EXTRACT_SUCCEEDED (1<<(0+MROUTE_SEC_SHIFT)) |
|
| 45 |
+#define MROUTE_SEC_EXTRACT_BCAST (1<<(1+MROUTE_SEC_SHIFT)) |
|
| 46 |
+#define MROUTE_SEC_EXTRACT_MCAST (1<<(2+MROUTE_SEC_SHIFT)) |
|
| 47 |
+#define MROUTE_SEC_EXTRACT_IGMP (1<<(3+MROUTE_SEC_SHIFT)) |
|
| 48 |
+ |
|
| 49 |
+#define MROUTE_SEC_SHIFT 4 |
|
| 42 | 50 |
|
| 43 | 51 |
/* |
| 44 | 52 |
* Choose the largest address possible with |
| ... | ... |
@@ -62,6 +70,9 @@ |
| 62 | 62 |
/* Address type mask indicating that netbits is part of address */ |
| 63 | 63 |
#define MR_WITH_NETBITS 8 |
| 64 | 64 |
|
| 65 |
+/* Indicates than IPv4 addr was extracted from ARP packet */ |
|
| 66 |
+#define MR_ARP 16 |
|
| 67 |
+ |
|
| 65 | 68 |
struct mroute_addr {
|
| 66 | 69 |
uint8_t len; /* length of address */ |
| 67 | 70 |
uint8_t unused; |
| ... | ... |
@@ -72,8 +83,7 @@ struct mroute_addr {
|
| 72 | 72 |
}; |
| 73 | 73 |
|
| 74 | 74 |
/* |
| 75 |
- * Number of bits in an address. Should be raised for |
|
| 76 |
- * IPv6. |
|
| 75 |
+ * Number of bits in an address. Should be raised for IPv6. |
|
| 77 | 76 |
*/ |
| 78 | 77 |
#define MR_HELPER_NET_LEN 32 |
| 79 | 78 |
|
| ... | ... |
@@ -89,11 +99,6 @@ struct mroute_helper {
|
| 89 | 89 |
int net_len_refcount[MR_HELPER_NET_LEN]; /* refcount of each netlength */ |
| 90 | 90 |
}; |
| 91 | 91 |
|
| 92 |
-unsigned int mroute_extract_addr_from_packet (struct mroute_addr *src, |
|
| 93 |
- struct mroute_addr *dest, |
|
| 94 |
- struct buffer *buf, |
|
| 95 |
- int tunnel_type); |
|
| 96 |
- |
|
| 97 | 92 |
struct openvpn_sockaddr; |
| 98 | 93 |
|
| 99 | 94 |
bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr, |
| ... | ... |
@@ -110,6 +115,13 @@ void mroute_addr_init (struct mroute_addr *addr); |
| 110 | 110 |
const char *mroute_addr_print (const struct mroute_addr *ma, |
| 111 | 111 |
struct gc_arena *gc); |
| 112 | 112 |
|
| 113 |
+#define MAPF_SUBNET (1<<0) |
|
| 114 |
+#define MAPF_IA_EMPTY_IF_UNDEF (1<<1) |
|
| 115 |
+#define MAPF_SHOW_ARP (1<<2) |
|
| 116 |
+const char *mroute_addr_print_ex (const struct mroute_addr *ma, |
|
| 117 |
+ const unsigned int flags, |
|
| 118 |
+ struct gc_arena *gc); |
|
| 119 |
+ |
|
| 113 | 120 |
void mroute_addr_mask_host_bits (struct mroute_addr *ma); |
| 114 | 121 |
|
| 115 | 122 |
struct mroute_helper *mroute_helper_init (int ageable_ttl_secs); |
| ... | ... |
@@ -117,6 +129,36 @@ void mroute_helper_free (struct mroute_helper *mh); |
| 117 | 117 |
void mroute_helper_add_iroute (struct mroute_helper *mh, const struct iroute *ir); |
| 118 | 118 |
void mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir); |
| 119 | 119 |
|
| 120 |
+/* |
|
| 121 |
+ * Given a raw packet in buf, return the src and dest |
|
| 122 |
+ * addresses of the packet. |
|
| 123 |
+ */ |
|
| 124 |
+static inline unsigned int |
|
| 125 |
+mroute_extract_addr_from_packet (struct mroute_addr *src, |
|
| 126 |
+ struct mroute_addr *dest, |
|
| 127 |
+ struct mroute_addr *esrc, |
|
| 128 |
+ struct mroute_addr *edest, |
|
| 129 |
+ const struct buffer *buf, |
|
| 130 |
+ int tunnel_type) |
|
| 131 |
+{
|
|
| 132 |
+ unsigned int mroute_extract_addr_ipv4 (struct mroute_addr *src, |
|
| 133 |
+ struct mroute_addr *dest, |
|
| 134 |
+ const struct buffer *buf); |
|
| 135 |
+ |
|
| 136 |
+ unsigned int mroute_extract_addr_ether (struct mroute_addr *src, |
|
| 137 |
+ struct mroute_addr *dest, |
|
| 138 |
+ struct mroute_addr *esrc, |
|
| 139 |
+ struct mroute_addr *edest, |
|
| 140 |
+ const struct buffer *buf); |
|
| 141 |
+ unsigned int ret = 0; |
|
| 142 |
+ verify_align_4 (buf); |
|
| 143 |
+ if (tunnel_type == DEV_TYPE_TUN) |
|
| 144 |
+ ret = mroute_extract_addr_ipv4 (src, dest, buf); |
|
| 145 |
+ else if (tunnel_type == DEV_TYPE_TAP) |
|
| 146 |
+ ret = mroute_extract_addr_ether (src, dest, esrc, edest, buf); |
|
| 147 |
+ return ret; |
|
| 148 |
+} |
|
| 149 |
+ |
|
| 120 | 150 |
static inline void |
| 121 | 151 |
mroute_helper_lock (struct mroute_helper *mh) |
| 122 | 152 |
{
|
| ... | ... |
@@ -166,11 +208,18 @@ mroute_extract_in_addr_t (struct mroute_addr *dest, const in_addr_t src) |
| 166 | 166 |
static inline in_addr_t |
| 167 | 167 |
in_addr_t_from_mroute_addr (const struct mroute_addr *addr) |
| 168 | 168 |
{
|
| 169 |
- if (addr->type == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4) |
|
| 169 |
+ if ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4) |
|
| 170 | 170 |
return ntohl(*(in_addr_t*)addr->addr); |
| 171 | 171 |
else |
| 172 | 172 |
return 0; |
| 173 | 173 |
} |
| 174 | 174 |
|
| 175 |
+static inline void |
|
| 176 |
+mroute_addr_reset (struct mroute_addr *ma) |
|
| 177 |
+{
|
|
| 178 |
+ ma->len = 0; |
|
| 179 |
+ ma->type = MR_ADDR_NONE; |
|
| 180 |
+} |
|
| 181 |
+ |
|
| 175 | 182 |
#endif /* P2MP_SERVER */ |
| 176 | 183 |
#endif /* MROUTE_H */ |
| ... | ... |
@@ -35,6 +35,7 @@ |
| 35 | 35 |
#include "memdbg.h" |
| 36 | 36 |
|
| 37 | 37 |
#include "forward-inline.h" |
| 38 |
+#include "pf-inline.h" |
|
| 38 | 39 |
|
| 39 | 40 |
/*#define MULTI_DEBUG_EVENT_LOOP*/ |
| 40 | 41 |
|
| ... | ... |
@@ -49,6 +50,16 @@ id (struct multi_instance *mi) |
| 49 | 49 |
} |
| 50 | 50 |
#endif |
| 51 | 51 |
|
| 52 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 53 |
+static void |
|
| 54 |
+set_cc_config (struct multi_instance *mi, struct buffer_list *cc_config) |
|
| 55 |
+{
|
|
| 56 |
+ if (mi->cc_config) |
|
| 57 |
+ buffer_list_free (mi->cc_config); |
|
| 58 |
+ mi->cc_config = cc_config; |
|
| 59 |
+} |
|
| 60 |
+#endif |
|
| 61 |
+ |
|
| 52 | 62 |
static bool |
| 53 | 63 |
learn_address_script (const struct multi_context *m, |
| 54 | 64 |
const struct multi_instance *mi, |
| ... | ... |
@@ -198,6 +209,25 @@ reap_buckets_per_pass (int n_buckets) |
| 198 | 198 |
return constrain_int (n_buckets / REAP_DIVISOR, REAP_MIN, REAP_MAX); |
| 199 | 199 |
} |
| 200 | 200 |
|
| 201 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 202 |
+ |
|
| 203 |
+static uint32_t |
|
| 204 |
+cid_hash_function (const void *key, uint32_t iv) |
|
| 205 |
+{
|
|
| 206 |
+ const unsigned long *k = (const unsigned long *)key; |
|
| 207 |
+ return (uint32_t) *k; |
|
| 208 |
+} |
|
| 209 |
+ |
|
| 210 |
+static bool |
|
| 211 |
+cid_compare_function (const void *key1, const void *key2) |
|
| 212 |
+{
|
|
| 213 |
+ const unsigned long *k1 = (const unsigned long *)key1; |
|
| 214 |
+ const unsigned long *k2 = (const unsigned long *)key2; |
|
| 215 |
+ return *k1 == *k2; |
|
| 216 |
+} |
|
| 217 |
+ |
|
| 218 |
+#endif |
|
| 219 |
+ |
|
| 201 | 220 |
/* |
| 202 | 221 |
* Main initialization function, init multi_context object. |
| 203 | 222 |
*/ |
| ... | ... |
@@ -252,6 +282,13 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa |
| 252 | 252 |
mroute_addr_hash_function, |
| 253 | 253 |
mroute_addr_compare_function); |
| 254 | 254 |
|
| 255 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 256 |
+ m->cid_hash = hash_init (t->options.real_hash_size, |
|
| 257 |
+ 0, |
|
| 258 |
+ cid_hash_function, |
|
| 259 |
+ cid_compare_function); |
|
| 260 |
+#endif |
|
| 261 |
+ |
|
| 255 | 262 |
/* |
| 256 | 263 |
* This is our scheduler, for time-based wakeup |
| 257 | 264 |
* events. |
| ... | ... |
@@ -376,6 +413,15 @@ ungenerate_prefix (struct multi_instance *mi) |
| 376 | 376 |
set_prefix (mi); |
| 377 | 377 |
} |
| 378 | 378 |
|
| 379 |
+static const char * |
|
| 380 |
+mi_prefix (const struct multi_instance *mi) |
|
| 381 |
+{
|
|
| 382 |
+ if (mi && mi->msg_prefix) |
|
| 383 |
+ return mi->msg_prefix; |
|
| 384 |
+ else |
|
| 385 |
+ return "UNDEF_I"; |
|
| 386 |
+} |
|
| 387 |
+ |
|
| 379 | 388 |
/* |
| 380 | 389 |
* Tell the route helper about deleted iroutes so |
| 381 | 390 |
* that it can update its mask of currently used |
| ... | ... |
@@ -439,6 +485,11 @@ multi_client_disconnect_script (struct multi_context *m, |
| 439 | 439 |
|
| 440 | 440 |
gc_free (&gc); |
| 441 | 441 |
} |
| 442 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 443 |
+ if (management) |
|
| 444 |
+ management_notify_client_close (management, &mi->context.c2.mda_context, mi->context.c2.es); |
|
| 445 |
+#endif |
|
| 446 |
+ |
|
| 442 | 447 |
} |
| 443 | 448 |
} |
| 444 | 449 |
|
| ... | ... |
@@ -470,6 +521,12 @@ multi_close_instance (struct multi_context *m, |
| 470 | 470 |
{
|
| 471 | 471 |
ASSERT (hash_remove (m->iter, &mi->real)); |
| 472 | 472 |
} |
| 473 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 474 |
+ if (mi->did_cid_hash) |
|
| 475 |
+ {
|
|
| 476 |
+ ASSERT (hash_remove (m->cid_hash, &mi->context.c2.mda_context.cid)); |
|
| 477 |
+ } |
|
| 478 |
+#endif |
|
| 473 | 479 |
|
| 474 | 480 |
schedule_remove_entry (m->schedule, (struct schedule_entry *) mi); |
| 475 | 481 |
|
| ... | ... |
@@ -487,6 +544,10 @@ multi_close_instance (struct multi_context *m, |
| 487 | 487 |
mbuf_dereference_instance (m->mbuf, mi); |
| 488 | 488 |
} |
| 489 | 489 |
|
| 490 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 491 |
+ set_cc_config (mi, NULL); |
|
| 492 |
+#endif |
|
| 493 |
+ |
|
| 490 | 494 |
multi_client_disconnect_script (m, mi); |
| 491 | 495 |
|
| 492 | 496 |
if (mi->did_open_context) |
| ... | ... |
@@ -538,6 +599,9 @@ multi_uninit (struct multi_context *m) |
| 538 | 538 |
hash_free (m->hash); |
| 539 | 539 |
hash_free (m->vhash); |
| 540 | 540 |
hash_free (m->iter); |
| 541 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 542 |
+ hash_free (m->cid_hash); |
|
| 543 |
+#endif |
|
| 541 | 544 |
m->hash = NULL; |
| 542 | 545 |
|
| 543 | 546 |
schedule_free (m->schedule); |
| ... | ... |
@@ -608,6 +672,13 @@ multi_create_instance (struct multi_context *m, const struct mroute_addr *real) |
| 608 | 608 |
} |
| 609 | 609 |
mi->did_iter = true; |
| 610 | 610 |
|
| 611 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 612 |
+ do {
|
|
| 613 |
+ mi->context.c2.mda_context.cid = m->cid_counter++; |
|
| 614 |
+ } while (!hash_add (m->cid_hash, &mi->context.c2.mda_context.cid, mi, false)); |
|
| 615 |
+ mi->did_cid_hash = true; |
|
| 616 |
+#endif |
|
| 617 |
+ |
|
| 611 | 618 |
mi->context.c2.push_reply_deferred = true; |
| 612 | 619 |
|
| 613 | 620 |
if (!multi_process_post (m, mi, MPP_PRE_SELECT)) |
| ... | ... |
@@ -983,7 +1054,8 @@ static struct multi_instance * |
| 983 | 983 |
multi_learn_in_addr_t (struct multi_context *m, |
| 984 | 984 |
struct multi_instance *mi, |
| 985 | 985 |
in_addr_t a, |
| 986 |
- int netbits) /* -1 if host route, otherwise # of network bits in address */ |
|
| 986 |
+ int netbits, /* -1 if host route, otherwise # of network bits in address */ |
|
| 987 |
+ bool primary) |
|
| 987 | 988 |
{
|
| 988 | 989 |
struct openvpn_sockaddr remote_si; |
| 989 | 990 |
struct mroute_addr addr; |
| ... | ... |
@@ -998,7 +1070,15 @@ multi_learn_in_addr_t (struct multi_context *m, |
| 998 | 998 |
addr.type |= MR_WITH_NETBITS; |
| 999 | 999 |
addr.netbits = (uint8_t) netbits; |
| 1000 | 1000 |
} |
| 1001 |
- return multi_learn_addr (m, mi, &addr, 0); |
|
| 1001 |
+ |
|
| 1002 |
+ {
|
|
| 1003 |
+ struct multi_instance *owner = multi_learn_addr (m, mi, &addr, 0); |
|
| 1004 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1005 |
+ if (management && owner) |
|
| 1006 |
+ management_learn_addr (management, &mi->context.c2.mda_context, &addr, primary); |
|
| 1007 |
+#endif |
|
| 1008 |
+ return owner; |
|
| 1009 |
+ } |
|
| 1002 | 1010 |
} |
| 1003 | 1011 |
|
| 1004 | 1012 |
/* |
| ... | ... |
@@ -1028,7 +1108,7 @@ multi_add_iroutes (struct multi_context *m, |
| 1028 | 1028 |
|
| 1029 | 1029 |
mroute_helper_add_iroute (m->route_helper, ir); |
| 1030 | 1030 |
|
| 1031 |
- multi_learn_in_addr_t (m, mi, ir->network, ir->netbits); |
|
| 1031 |
+ multi_learn_in_addr_t (m, mi, ir->network, ir->netbits, false); |
|
| 1032 | 1032 |
} |
| 1033 | 1033 |
} |
| 1034 | 1034 |
gc_free (&gc); |
| ... | ... |
@@ -1255,7 +1335,7 @@ multi_client_connect_post_plugin (struct multi_context *m, |
| 1255 | 1255 |
for (i = 0; i < config.n; ++i) |
| 1256 | 1256 |
{
|
| 1257 | 1257 |
if (config.list[i] && config.list[i]->value) |
| 1258 |
- options_plugin_import (&mi->context.options, |
|
| 1258 |
+ options_string_import (&mi->context.options, |
|
| 1259 | 1259 |
config.list[i]->value, |
| 1260 | 1260 |
D_IMPORT_ERRORS|M_OPTERR, |
| 1261 | 1261 |
option_permissions_mask, |
| ... | ... |
@@ -1276,6 +1356,46 @@ multi_client_connect_post_plugin (struct multi_context *m, |
| 1276 | 1276 |
|
| 1277 | 1277 |
#endif |
| 1278 | 1278 |
|
| 1279 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1280 |
+ |
|
| 1281 |
+/* |
|
| 1282 |
+ * Called to load management-derived client-connect config |
|
| 1283 |
+ */ |
|
| 1284 |
+static void |
|
| 1285 |
+multi_client_connect_mda (struct multi_context *m, |
|
| 1286 |
+ struct multi_instance *mi, |
|
| 1287 |
+ const struct buffer_list *config, |
|
| 1288 |
+ unsigned int option_permissions_mask, |
|
| 1289 |
+ unsigned int *option_types_found) |
|
| 1290 |
+{
|
|
| 1291 |
+ if (config) |
|
| 1292 |
+ {
|
|
| 1293 |
+ struct buffer_entry *be; |
|
| 1294 |
+ |
|
| 1295 |
+ for (be = config->head; be != NULL; be = be->next) |
|
| 1296 |
+ {
|
|
| 1297 |
+ const char *opt = BSTR(&be->buf); |
|
| 1298 |
+ options_string_import (&mi->context.options, |
|
| 1299 |
+ opt, |
|
| 1300 |
+ D_IMPORT_ERRORS|M_OPTERR, |
|
| 1301 |
+ option_permissions_mask, |
|
| 1302 |
+ option_types_found, |
|
| 1303 |
+ mi->context.c2.es); |
|
| 1304 |
+ } |
|
| 1305 |
+ |
|
| 1306 |
+ /* |
|
| 1307 |
+ * If the --client-connect script generates a config file |
|
| 1308 |
+ * with an --ifconfig-push directive, it will override any |
|
| 1309 |
+ * --ifconfig-push directive from the --client-config-dir |
|
| 1310 |
+ * directory or any --ifconfig-pool dynamic address. |
|
| 1311 |
+ */ |
|
| 1312 |
+ multi_select_virtual_addr (m, mi); |
|
| 1313 |
+ multi_set_virtual_addr_env (m, mi); |
|
| 1314 |
+ } |
|
| 1315 |
+} |
|
| 1316 |
+ |
|
| 1317 |
+#endif |
|
| 1318 |
+ |
|
| 1279 | 1319 |
static void |
| 1280 | 1320 |
multi_client_connect_setenv (struct multi_context *m, |
| 1281 | 1321 |
struct multi_instance *mi) |
| ... | ... |
@@ -1469,6 +1589,17 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi |
| 1469 | 1469 |
} |
| 1470 | 1470 |
|
| 1471 | 1471 |
/* |
| 1472 |
+ * Check for client-connect script left by management interface client |
|
| 1473 |
+ */ |
|
| 1474 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1475 |
+ if (cc_succeeded && mi->cc_config) |
|
| 1476 |
+ {
|
|
| 1477 |
+ multi_client_connect_mda (m, mi, mi->cc_config, option_permissions_mask, &option_types_found); |
|
| 1478 |
+ ++cc_succeeded_count; |
|
| 1479 |
+ } |
|
| 1480 |
+#endif |
|
| 1481 |
+ |
|
| 1482 |
+ /* |
|
| 1472 | 1483 |
* Check for "disable" directive in client-config-dir file |
| 1473 | 1484 |
* or config file generated by --client-connect script. |
| 1474 | 1485 |
*/ |
| ... | ... |
@@ -1515,7 +1646,7 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi |
| 1515 | 1515 |
{
|
| 1516 | 1516 |
if (mi->context.c2.push_ifconfig_defined) |
| 1517 | 1517 |
{
|
| 1518 |
- multi_learn_in_addr_t (m, mi, mi->context.c2.push_ifconfig_local, -1); |
|
| 1518 |
+ multi_learn_in_addr_t (m, mi, mi->context.c2.push_ifconfig_local, -1, true); |
|
| 1519 | 1519 |
msg (D_MULTI_LOW, "MULTI: primary virtual IP for %s: %s", |
| 1520 | 1520 |
multi_instance_string (mi, false, &gc), |
| 1521 | 1521 |
print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc)); |
| ... | ... |
@@ -1553,6 +1684,11 @@ multi_connection_established (struct multi_context *m, struct multi_instance *mi |
| 1553 | 1553 |
/* set flag so we don't get called again */ |
| 1554 | 1554 |
mi->connection_established_flag = true; |
| 1555 | 1555 |
|
| 1556 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1557 |
+ if (management) |
|
| 1558 |
+ management_connection_established (management, &mi->context.c2.mda_context); |
|
| 1559 |
+#endif |
|
| 1560 |
+ |
|
| 1556 | 1561 |
gc_free (&gc); |
| 1557 | 1562 |
} |
| 1558 | 1563 |
|
| ... | ... |
@@ -1606,10 +1742,11 @@ multi_unicast (struct multi_context *m, |
| 1606 | 1606 |
/* |
| 1607 | 1607 |
* Broadcast a packet to all clients. |
| 1608 | 1608 |
*/ |
| 1609 |
-void |
|
| 1609 |
+static void |
|
| 1610 | 1610 |
multi_bcast (struct multi_context *m, |
| 1611 | 1611 |
const struct buffer *buf, |
| 1612 |
- struct multi_instance *omit) |
|
| 1612 |
+ const struct multi_instance *sender_instance, |
|
| 1613 |
+ const struct mroute_addr *sender_addr) |
|
| 1613 | 1614 |
{
|
| 1614 | 1615 |
struct hash_iterator hi; |
| 1615 | 1616 |
struct hash_element *he; |
| ... | ... |
@@ -1628,8 +1765,34 @@ multi_bcast (struct multi_context *m, |
| 1628 | 1628 |
while ((he = hash_iterator_next (&hi))) |
| 1629 | 1629 |
{
|
| 1630 | 1630 |
mi = (struct multi_instance *) he->value; |
| 1631 |
- if (mi != omit && !mi->halt) |
|
| 1632 |
- multi_add_mbuf (m, mi, mb); |
|
| 1631 |
+ if (mi != sender_instance && !mi->halt) |
|
| 1632 |
+ {
|
|
| 1633 |
+#ifdef ENABLE_PF |
|
| 1634 |
+ if (sender_instance) |
|
| 1635 |
+ {
|
|
| 1636 |
+ if (!pf_c2c_test (&sender_instance->context, &mi->context, "bcast_c2c")) |
|
| 1637 |
+ {
|
|
| 1638 |
+ msg (D_PF_DROPPED_BCAST, "PF: client[%s] -> client[%s] packet dropped by BCAST packet filter", |
|
| 1639 |
+ mi_prefix (sender_instance), |
|
| 1640 |
+ mi_prefix (mi)); |
|
| 1641 |
+ continue; |
|
| 1642 |
+ } |
|
| 1643 |
+ } |
|
| 1644 |
+ if (sender_addr) |
|
| 1645 |
+ {
|
|
| 1646 |
+ if (!pf_addr_test (&mi->context, sender_addr, "bcast_src_addr")) |
|
| 1647 |
+ {
|
|
| 1648 |
+ struct gc_arena gc = gc_new (); |
|
| 1649 |
+ msg (D_PF_DROPPED_BCAST, "PF: addr[%s] -> client[%s] packet dropped by BCAST packet filter", |
|
| 1650 |
+ mroute_addr_print_ex (sender_addr, MAPF_SHOW_ARP, &gc), |
|
| 1651 |
+ mi_prefix (mi)); |
|
| 1652 |
+ gc_free (&gc); |
|
| 1653 |
+ continue; |
|
| 1654 |
+ } |
|
| 1655 |
+ } |
|
| 1656 |
+#endif |
|
| 1657 |
+ multi_add_mbuf (m, mi, mb); |
|
| 1658 |
+ } |
|
| 1633 | 1659 |
} |
| 1634 | 1660 |
|
| 1635 | 1661 |
hash_iterator_free (&hi); |
| ... | ... |
@@ -1789,6 +1952,8 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins |
| 1789 | 1789 |
/* extract packet source and dest addresses */ |
| 1790 | 1790 |
mroute_flags = mroute_extract_addr_from_packet (&src, |
| 1791 | 1791 |
&dest, |
| 1792 |
+ NULL, |
|
| 1793 |
+ NULL, |
|
| 1792 | 1794 |
&c->c2.to_tun, |
| 1793 | 1795 |
DEV_TYPE_TUN); |
| 1794 | 1796 |
|
| ... | ... |
@@ -1811,7 +1976,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins |
| 1811 | 1811 |
if (mroute_flags & MROUTE_EXTRACT_MCAST) |
| 1812 | 1812 |
{
|
| 1813 | 1813 |
/* for now, treat multicast as broadcast */ |
| 1814 |
- multi_bcast (m, &c->c2.to_tun, m->pending); |
|
| 1814 |
+ multi_bcast (m, &c->c2.to_tun, m->pending, NULL); |
|
| 1815 | 1815 |
} |
| 1816 | 1816 |
else /* possible client to client routing */ |
| 1817 | 1817 |
{
|
| ... | ... |
@@ -1822,10 +1987,10 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins |
| 1822 | 1822 |
if (mi) |
| 1823 | 1823 |
{
|
| 1824 | 1824 |
#ifdef ENABLE_PF |
| 1825 |
- if (!pf_c2c_test (c, &mi->context)) |
|
| 1825 |
+ if (!pf_c2c_test (c, &mi->context, "tun_c2c")) |
|
| 1826 | 1826 |
{
|
| 1827 |
- msg (D_PF, "PF: client -> [%s] packet dropped by packet filter", |
|
| 1828 |
- np (mi->msg_prefix)); |
|
| 1827 |
+ msg (D_PF_DROPPED, "PF: client -> client[%s] packet dropped by TUN packet filter", |
|
| 1828 |
+ mi_prefix (mi)); |
|
| 1829 | 1829 |
} |
| 1830 | 1830 |
else |
| 1831 | 1831 |
#endif |
| ... | ... |
@@ -1838,18 +2003,29 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins |
| 1838 | 1838 |
} |
| 1839 | 1839 |
} |
| 1840 | 1840 |
#ifdef ENABLE_PF |
| 1841 |
- else if (!pf_addr_test (c, &dest)) |
|
| 1841 |
+ if (c->c2.to_tun.len && !pf_addr_test (c, &dest, "tun_dest_addr")) |
|
| 1842 | 1842 |
{
|
| 1843 |
- msg (D_PF, "PF: client -> [%s] packet dropped by packet filter", |
|
| 1844 |
- mroute_addr_print (&dest, &gc)); |
|
| 1843 |
+ msg (D_PF_DROPPED, "PF: client -> addr[%s] packet dropped by TUN packet filter", |
|
| 1844 |
+ mroute_addr_print_ex (&dest, MAPF_SHOW_ARP, &gc)); |
|
| 1845 |
+ c->c2.to_tun.len = 0; |
|
| 1845 | 1846 |
} |
| 1846 | 1847 |
#endif |
| 1847 | 1848 |
} |
| 1848 | 1849 |
else if (TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TAP) |
| 1849 | 1850 |
{
|
| 1851 |
+#ifdef ENABLE_PF |
|
| 1852 |
+ struct mroute_addr edest; |
|
| 1853 |
+ mroute_addr_reset (&edest); |
|
| 1854 |
+#endif |
|
| 1850 | 1855 |
/* extract packet source and dest addresses */ |
| 1851 | 1856 |
mroute_flags = mroute_extract_addr_from_packet (&src, |
| 1852 | 1857 |
&dest, |
| 1858 |
+ NULL, |
|
| 1859 |
+#ifdef ENABLE_PF |
|
| 1860 |
+ &edest, |
|
| 1861 |
+#else |
|
| 1862 |
+ NULL, |
|
| 1863 |
+#endif |
|
| 1853 | 1864 |
&c->c2.to_tun, |
| 1854 | 1865 |
DEV_TYPE_TAP); |
| 1855 | 1866 |
|
| ... | ... |
@@ -1862,7 +2038,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins |
| 1862 | 1862 |
{
|
| 1863 | 1863 |
if (mroute_flags & (MROUTE_EXTRACT_BCAST|MROUTE_EXTRACT_MCAST)) |
| 1864 | 1864 |
{
|
| 1865 |
- multi_bcast (m, &c->c2.to_tun, m->pending); |
|
| 1865 |
+ multi_bcast (m, &c->c2.to_tun, m->pending, NULL); |
|
| 1866 | 1866 |
} |
| 1867 | 1867 |
else /* try client-to-client routing */ |
| 1868 | 1868 |
{
|
| ... | ... |
@@ -1871,12 +2047,30 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins |
| 1871 | 1871 |
/* if dest addr is a known client, route to it */ |
| 1872 | 1872 |
if (mi) |
| 1873 | 1873 |
{
|
| 1874 |
- multi_unicast (m, &c->c2.to_tun, mi); |
|
| 1875 |
- register_activity (c, BLEN(&c->c2.to_tun)); |
|
| 1874 |
+#ifdef ENABLE_PF |
|
| 1875 |
+ if (!pf_c2c_test (c, &mi->context, "tap_c2c")) |
|
| 1876 |
+ {
|
|
| 1877 |
+ msg (D_PF_DROPPED, "PF: client -> client[%s] packet dropped by TAP packet filter", |
|
| 1878 |
+ mi_prefix (mi)); |
|
| 1879 |
+ } |
|
| 1880 |
+ else |
|
| 1881 |
+#endif |
|
| 1882 |
+ {
|
|
| 1883 |
+ multi_unicast (m, &c->c2.to_tun, mi); |
|
| 1884 |
+ register_activity (c, BLEN(&c->c2.to_tun)); |
|
| 1885 |
+ } |
|
| 1876 | 1886 |
c->c2.to_tun.len = 0; |
| 1877 | 1887 |
} |
| 1878 | 1888 |
} |
| 1879 | 1889 |
} |
| 1890 |
+#ifdef ENABLE_PF |
|
| 1891 |
+ if (c->c2.to_tun.len && !pf_addr_test (c, &edest, "tap_dest_addr")) |
|
| 1892 |
+ {
|
|
| 1893 |
+ msg (D_PF_DROPPED, "PF: client -> addr[%s] packet dropped by TAP packet filter", |
|
| 1894 |
+ mroute_addr_print_ex (&edest, MAPF_SHOW_ARP, &gc)); |
|
| 1895 |
+ c->c2.to_tun.len = 0; |
|
| 1896 |
+ } |
|
| 1897 |
+#endif |
|
| 1880 | 1898 |
} |
| 1881 | 1899 |
else |
| 1882 | 1900 |
{
|
| ... | ... |
@@ -1918,6 +2112,20 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag |
| 1918 | 1918 |
struct mroute_addr src, dest; |
| 1919 | 1919 |
const int dev_type = TUNNEL_TYPE (m->top.c1.tuntap); |
| 1920 | 1920 |
|
| 1921 |
+#ifdef ENABLE_PF |
|
| 1922 |
+ struct mroute_addr esrc, *e1, *e2; |
|
| 1923 |
+ if (dev_type == DEV_TYPE_TUN) |
|
| 1924 |
+ {
|
|
| 1925 |
+ e1 = NULL; |
|
| 1926 |
+ e2 = &src; |
|
| 1927 |
+ } |
|
| 1928 |
+ else |
|
| 1929 |
+ {
|
|
| 1930 |
+ e1 = e2 = &esrc; |
|
| 1931 |
+ mroute_addr_reset (&esrc); |
|
| 1932 |
+ } |
|
| 1933 |
+#endif |
|
| 1934 |
+ |
|
| 1921 | 1935 |
#ifdef MULTI_DEBUG_EVENT_LOOP |
| 1922 | 1936 |
printf ("TUN -> TCP/UDP [%d]\n", BLEN (&m->top.c2.buf));
|
| 1923 | 1937 |
#endif |
| ... | ... |
@@ -1932,6 +2140,12 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag |
| 1932 | 1932 |
|
| 1933 | 1933 |
mroute_flags = mroute_extract_addr_from_packet (&src, |
| 1934 | 1934 |
&dest, |
| 1935 |
+#ifdef ENABLE_PF |
|
| 1936 |
+ e1, |
|
| 1937 |
+#else |
|
| 1938 |
+ NULL, |
|
| 1939 |
+#endif |
|
| 1940 |
+ NULL, |
|
| 1935 | 1941 |
&m->top.c2.buf, |
| 1936 | 1942 |
dev_type); |
| 1937 | 1943 |
|
| ... | ... |
@@ -1943,7 +2157,11 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag |
| 1943 | 1943 |
if (mroute_flags & (MROUTE_EXTRACT_BCAST|MROUTE_EXTRACT_MCAST)) |
| 1944 | 1944 |
{
|
| 1945 | 1945 |
/* for now, treat multicast as broadcast */ |
| 1946 |
- multi_bcast (m, &m->top.c2.buf, NULL); |
|
| 1946 |
+#ifdef ENABLE_PF |
|
| 1947 |
+ multi_bcast (m, &m->top.c2.buf, NULL, e2); |
|
| 1948 |
+#else |
|
| 1949 |
+ multi_bcast (m, &m->top.c2.buf, NULL, NULL); |
|
| 1950 |
+#endif |
|
| 1947 | 1951 |
} |
| 1948 | 1952 |
else |
| 1949 | 1953 |
{
|
| ... | ... |
@@ -1957,10 +2175,10 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag |
| 1957 | 1957 |
set_prefix (m->pending); |
| 1958 | 1958 |
|
| 1959 | 1959 |
#ifdef ENABLE_PF |
| 1960 |
- if (!pf_addr_test (c, &src)) |
|
| 1960 |
+ if (!pf_addr_test (c, e2, "tun_tap_src_addr")) |
|
| 1961 | 1961 |
{
|
| 1962 |
- msg (D_PF, "PF: [%s] -> client packet dropped by packet filter", |
|
| 1963 |
- mroute_addr_print (&src, &gc)); |
|
| 1962 |
+ msg (D_PF_DROPPED, "PF: addr[%s] -> client packet dropped by packet filter", |
|
| 1963 |
+ mroute_addr_print_ex (&src, MAPF_SHOW_ARP, &gc)); |
|
| 1964 | 1964 |
buf_reset_len (&c->c2.buf); |
| 1965 | 1965 |
} |
| 1966 | 1966 |
else |
| ... | ... |
@@ -2111,7 +2329,7 @@ gremlin_flood_clients (struct multi_context *m) |
| 2111 | 2111 |
ASSERT (buf_write_u8 (&buf, get_random () & 0xFF)); |
| 2112 | 2112 |
|
| 2113 | 2113 |
for (i = 0; i < parm.n_packets; ++i) |
| 2114 |
- multi_bcast (m, &buf, NULL); |
|
| 2114 |
+ multi_bcast (m, &buf, NULL, NULL); |
|
| 2115 | 2115 |
|
| 2116 | 2116 |
gc_free (&gc); |
| 2117 | 2117 |
} |
| ... | ... |
@@ -2281,6 +2499,86 @@ management_delete_event (void *arg, event_t event) |
| 2281 | 2281 |
|
| 2282 | 2282 |
#endif |
| 2283 | 2283 |
|
| 2284 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 2285 |
+ |
|
| 2286 |
+static struct multi_instance * |
|
| 2287 |
+lookup_by_cid (struct multi_context *m, const unsigned long cid) |
|
| 2288 |
+{
|
|
| 2289 |
+ if (m) |
|
| 2290 |
+ {
|
|
| 2291 |
+ struct multi_instance *mi = (struct multi_instance *) hash_lookup (m->cid_hash, &cid); |
|
| 2292 |
+ if (mi && !mi->halt) |
|
| 2293 |
+ return mi; |
|
| 2294 |
+ } |
|
| 2295 |
+ return NULL; |
|
| 2296 |
+} |
|
| 2297 |
+ |
|
| 2298 |
+static bool |
|
| 2299 |
+management_kill_by_cid (void *arg, const unsigned long cid) |
|
| 2300 |
+{
|
|
| 2301 |
+ struct multi_context *m = (struct multi_context *) arg; |
|
| 2302 |
+ struct multi_instance *mi = lookup_by_cid (m, cid); |
|
| 2303 |
+ if (mi) |
|
| 2304 |
+ {
|
|
| 2305 |
+ multi_signal_instance (m, mi, SIGTERM); |
|
| 2306 |
+ return true; |
|
| 2307 |
+ } |
|
| 2308 |
+ else |
|
| 2309 |
+ return false; |
|
| 2310 |
+} |
|
| 2311 |
+ |
|
| 2312 |
+static bool |
|
| 2313 |
+management_client_auth (void *arg, |
|
| 2314 |
+ const unsigned long cid, |
|
| 2315 |
+ const unsigned int mda_key_id, |
|
| 2316 |
+ const bool auth, |
|
| 2317 |
+ const char *reason, |
|
| 2318 |
+ struct buffer_list *cc_config) /* ownership transferred */ |
|
| 2319 |
+{
|
|
| 2320 |
+ struct multi_context *m = (struct multi_context *) arg; |
|
| 2321 |
+ struct multi_instance *mi = lookup_by_cid (m, cid); |
|
| 2322 |
+ bool cc_config_owned = true; |
|
| 2323 |
+ bool ret = false; |
|
| 2324 |
+ |
|
| 2325 |
+ if (mi) |
|
| 2326 |
+ {
|
|
| 2327 |
+ ret = tls_authenticate_key (mi->context.c2.tls_multi, mda_key_id, auth); |
|
| 2328 |
+ if (ret) |
|
| 2329 |
+ {
|
|
| 2330 |
+ if (auth && !mi->connection_established_flag) |
|
| 2331 |
+ {
|
|
| 2332 |
+ set_cc_config (mi, cc_config); |
|
| 2333 |
+ cc_config_owned = false; |
|
| 2334 |
+ } |
|
| 2335 |
+ if (!auth && reason) |
|
| 2336 |
+ msg (D_MULTI_LOW, "MULTI: connection rejected: %s", reason); |
|
| 2337 |
+ } |
|
| 2338 |
+ } |
|
| 2339 |
+ if (cc_config_owned && cc_config) |
|
| 2340 |
+ buffer_list_free (cc_config); |
|
| 2341 |
+ return ret; |
|
| 2342 |
+} |
|
| 2343 |
+#endif |
|
| 2344 |
+ |
|
| 2345 |
+#ifdef MANAGEMENT_PF |
|
| 2346 |
+static bool |
|
| 2347 |
+management_client_pf (void *arg, |
|
| 2348 |
+ const unsigned long cid, |
|
| 2349 |
+ struct buffer_list *pf_config) /* ownership transferred */ |
|
| 2350 |
+{
|
|
| 2351 |
+ struct multi_context *m = (struct multi_context *) arg; |
|
| 2352 |
+ struct multi_instance *mi = lookup_by_cid (m, cid); |
|
| 2353 |
+ bool ret = false; |
|
| 2354 |
+ |
|
| 2355 |
+ if (mi && pf_config) |
|
| 2356 |
+ ret = pf_load_from_buffer_list (&mi->context, pf_config); |
|
| 2357 |
+ |
|
| 2358 |
+ if (pf_config) |
|
| 2359 |
+ buffer_list_free (pf_config); |
|
| 2360 |
+ return ret; |
|
| 2361 |
+} |
|
| 2362 |
+#endif |
|
| 2363 |
+ |
|
| 2284 | 2364 |
void |
| 2285 | 2365 |
init_management_callback_multi (struct multi_context *m) |
| 2286 | 2366 |
{
|
| ... | ... |
@@ -2295,6 +2593,13 @@ init_management_callback_multi (struct multi_context *m) |
| 2295 | 2295 |
cb.kill_by_cn = management_callback_kill_by_cn; |
| 2296 | 2296 |
cb.kill_by_addr = management_callback_kill_by_addr; |
| 2297 | 2297 |
cb.delete_event = management_delete_event; |
| 2298 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 2299 |
+ cb.kill_by_cid = management_kill_by_cid; |
|
| 2300 |
+ cb.client_auth = management_client_auth; |
|
| 2301 |
+#endif |
|
| 2302 |
+#ifdef MANAGEMENT_PF |
|
| 2303 |
+ cb.client_pf = management_client_pf; |
|
| 2304 |
+#endif |
|
| 2298 | 2305 |
management_set_callback (management, &cb); |
| 2299 | 2306 |
} |
| 2300 | 2307 |
#endif |
| ... | ... |
@@ -77,6 +77,10 @@ struct multi_instance {
|
| 77 | 77 |
bool did_open_context; |
| 78 | 78 |
bool did_real_hash; |
| 79 | 79 |
bool did_iter; |
| 80 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 81 |
+ bool did_cid_hash; |
|
| 82 |
+ struct buffer_list *cc_config; |
|
| 83 |
+#endif |
|
| 80 | 84 |
bool connection_established_flag; |
| 81 | 85 |
bool did_iroutes; |
| 82 | 86 |
|
| ... | ... |
@@ -111,6 +115,11 @@ struct multi_context {
|
| 111 | 111 |
int tcp_queue_limit; |
| 112 | 112 |
int status_file_version; |
| 113 | 113 |
|
| 114 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 115 |
+ struct hash *cid_hash; |
|
| 116 |
+ unsigned long cid_counter; |
|
| 117 |
+#endif |
|
| 118 |
+ |
|
| 114 | 119 |
struct multi_instance *pending; |
| 115 | 120 |
struct multi_instance *earliest_wakeup; |
| 116 | 121 |
struct multi_instance **mpp_touched; |
| ... | ... |
@@ -143,10 +152,6 @@ void tunnel_server (struct context *top); |
| 143 | 143 |
|
| 144 | 144 |
const char *multi_instance_string (const struct multi_instance *mi, bool null, struct gc_arena *gc); |
| 145 | 145 |
|
| 146 |
-void multi_bcast (struct multi_context *m, |
|
| 147 |
- const struct buffer *buf, |
|
| 148 |
- struct multi_instance *omit); |
|
| 149 |
- |
|
| 150 | 146 |
/* |
| 151 | 147 |
* Called by mtcp.c, mudp.c, or other (to be written) protocol drivers |
| 152 | 148 |
*/ |
| ... | ... |
@@ -179,6 +179,8 @@ openvpn \- secure IP tunnel daemon. |
| 179 | 179 |
[\ \fB\-\-log\fR\ \fIfile\fR\ ] |
| 180 | 180 |
[\ \fB\-\-suppress-timestamps\fR\ ] |
| 181 | 181 |
[\ \fB\-\-lport\fR\ \fIport\fR\ ] |
| 182 |
+[\ \fB\-\-management\-client\-auth\fR\ ] |
|
| 183 |
+[\ \fB\-\-management\-client\-pf\fR\ ] |
|
| 182 | 184 |
[\ \fB\-\-management\-forget\-disconnect\fR\ ] |
| 183 | 185 |
[\ \fB\-\-management\-hold\fR\ ] |
| 184 | 186 |
[\ \fB\-\-management\-log\-cache\fR\ \fIn\fR\ ] |
| ... | ... |
@@ -2357,6 +2359,19 @@ lines of log file history for usage |
| 2357 | 2357 |
by the management channel. |
| 2358 | 2358 |
.\"********************************************************* |
| 2359 | 2359 |
.TP |
| 2360 |
+.B --management-client-auth |
|
| 2361 |
+Gives management interface client the responsibility |
|
| 2362 |
+to authenticate clients after their client certificate |
|
| 2363 |
+has been verified. See management-notes.txt in OpenVPN |
|
| 2364 |
+distribution for detailed notes. |
|
| 2365 |
+.\"********************************************************* |
|
| 2366 |
+.TP |
|
| 2367 |
+.B --management-client-pf |
|
| 2368 |
+Management interface clients must specify a packet |
|
| 2369 |
+filter file for each connecting client. See management-notes.txt |
|
| 2370 |
+in OpenVPN distribution for detailed notes. |
|
| 2371 |
+.\"********************************************************* |
|
| 2372 |
+.TP |
|
| 2360 | 2373 |
.B --plugin module-pathname [init-string] |
| 2361 | 2374 |
Load plug-in module from the file |
| 2362 | 2375 |
.B module-pathname, |
| ... | ... |
@@ -316,6 +316,15 @@ static const char usage_message[] = |
| 316 | 316 |
" event occurs.\n" |
| 317 | 317 |
"--management-log-cache n : Cache n lines of log file history for usage\n" |
| 318 | 318 |
" by the management channel.\n" |
| 319 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 320 |
+ "--management-client-auth : gives management interface client the responsibility\n" |
|
| 321 |
+ " to authenticate clients after their client certificate\n" |
|
| 322 |
+ " has been verified.\n" |
|
| 323 |
+#endif |
|
| 324 |
+#ifdef MANAGEMENT_PF |
|
| 325 |
+ "--management-client-pf : management interface clients must specify a packet\n" |
|
| 326 |
+ " filter file for each connecting client.\n" |
|
| 327 |
+#endif |
|
| 319 | 328 |
#endif |
| 320 | 329 |
#ifdef ENABLE_PLUGIN |
| 321 | 330 |
"--plugin m [str]: Load plug-in module m passing str as an argument\n" |
| ... | ... |
@@ -1195,12 +1204,8 @@ show_settings (const struct options *o) |
| 1195 | 1195 |
SHOW_STR (management_user_pass); |
| 1196 | 1196 |
SHOW_INT (management_log_history_cache); |
| 1197 | 1197 |
SHOW_INT (management_echo_buffer_size); |
| 1198 |
- SHOW_BOOL (management_query_passwords); |
|
| 1199 |
- SHOW_BOOL (management_hold); |
|
| 1200 |
- SHOW_BOOL (management_client); |
|
| 1201 |
- SHOW_BOOL (management_signal); |
|
| 1202 |
- SHOW_BOOL (management_forget_disconnect); |
|
| 1203 | 1198 |
SHOW_STR (management_write_peer_info_file); |
| 1199 |
+ SHOW_INT (management_flags); |
|
| 1204 | 1200 |
#endif |
| 1205 | 1201 |
#ifdef ENABLE_PLUGIN |
| 1206 | 1202 |
if (o->plugin_list) |
| ... | ... |
@@ -1525,8 +1530,7 @@ options_postprocess (struct options *options, bool first_time) |
| 1525 | 1525 |
*/ |
| 1526 | 1526 |
#ifdef ENABLE_MANAGEMENT |
| 1527 | 1527 |
if (!options->management_addr && |
| 1528 |
- (options->management_query_passwords || options->management_hold || options->management_signal |
|
| 1529 |
- || options->management_forget_disconnect || options->management_client |
|
| 1528 |
+ (options->management_flags |
|
| 1530 | 1529 |
|| options->management_write_peer_info_file |
| 1531 | 1530 |
|| options->management_log_history_cache != defaults.management_log_history_cache)) |
| 1532 | 1531 |
msg (M_USAGE, "--management is not specified, however one or more options which modify the behavior of --management were specified"); |
| ... | ... |
@@ -1672,12 +1676,15 @@ options_postprocess (struct options *options, bool first_time) |
| 1672 | 1672 |
if (options->key_method != 2) |
| 1673 | 1673 |
msg (M_USAGE, "--mode server requires --key-method 2"); |
| 1674 | 1674 |
|
| 1675 |
- if (PLUGIN_OPTION_LIST (options) == NULL) |
|
| 1676 | 1675 |
{
|
| 1677 |
- if (options->client_cert_not_required && !options->auth_user_pass_verify_script) |
|
| 1678 |
- msg (M_USAGE, "--client-cert-not-required must be used with an --auth-user-pass-verify script"); |
|
| 1679 |
- if (options->username_as_common_name && !options->auth_user_pass_verify_script) |
|
| 1680 |
- msg (M_USAGE, "--username-as-common-name must be used with an --auth-user-pass-verify script"); |
|
| 1676 |
+ const bool ccnr = (options->auth_user_pass_verify_script |
|
| 1677 |
+ || PLUGIN_OPTION_LIST (options) |
|
| 1678 |
+ || MAN_CLIENT_AUTH_ENABLED (options)); |
|
| 1679 |
+ const char *postfix = "must be used with --management-client-auth, an --auth-user-pass-verify script, or plugin"; |
|
| 1680 |
+ if (options->client_cert_not_required && !ccnr) |
|
| 1681 |
+ msg (M_USAGE, "--client-cert-not-required %s", postfix); |
|
| 1682 |
+ if (options->username_as_common_name && !ccnr) |
|
| 1683 |
+ msg (M_USAGE, "--username-as-common-name %s", postfix); |
|
| 1681 | 1684 |
} |
| 1682 | 1685 |
} |
| 1683 | 1686 |
else |
| ... | ... |
@@ -2983,9 +2990,7 @@ options_server_import (struct options *o, |
| 2983 | 2983 |
es); |
| 2984 | 2984 |
} |
| 2985 | 2985 |
|
| 2986 |
-#ifdef ENABLE_PLUGIN |
|
| 2987 |
- |
|
| 2988 |
-void options_plugin_import (struct options *options, |
|
| 2986 |
+void options_string_import (struct options *options, |
|
| 2989 | 2987 |
const char *config, |
| 2990 | 2988 |
const int msglevel, |
| 2991 | 2989 |
const unsigned int permission_mask, |
| ... | ... |
@@ -2995,8 +3000,6 @@ void options_plugin_import (struct options *options, |
| 2995 | 2995 |
read_config_string (options, config, msglevel, permission_mask, option_types_found, es); |
| 2996 | 2996 |
} |
| 2997 | 2997 |
|
| 2998 |
-#endif |
|
| 2999 |
- |
|
| 3000 | 2998 |
#if P2MP |
| 3001 | 2999 |
|
| 3002 | 3000 |
#define VERIFY_PERMISSION(mask) { if (!verify_permission(p[0], (mask), permission_mask, option_types_found, msglevel)) goto err; }
|
| ... | ... |
@@ -3144,29 +3147,43 @@ add_option (struct options *options, |
| 3144 | 3144 |
else if (streq (p[0], "management-query-passwords")) |
| 3145 | 3145 |
{
|
| 3146 | 3146 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
| 3147 |
- options->management_query_passwords = true; |
|
| 3147 |
+ options->management_flags |= MF_QUERY_PASSWORDS; |
|
| 3148 | 3148 |
} |
| 3149 | 3149 |
else if (streq (p[0], "management-hold")) |
| 3150 | 3150 |
{
|
| 3151 | 3151 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
| 3152 |
- options->management_hold = true; |
|
| 3152 |
+ options->management_flags |= MF_HOLD; |
|
| 3153 | 3153 |
} |
| 3154 | 3154 |
else if (streq (p[0], "management-signal")) |
| 3155 | 3155 |
{
|
| 3156 | 3156 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
| 3157 |
- options->management_signal = true; |
|
| 3157 |
+ options->management_flags |= MF_SIGNAL; |
|
| 3158 | 3158 |
} |
| 3159 | 3159 |
else if (streq (p[0], "management-forget-disconnect")) |
| 3160 | 3160 |
{
|
| 3161 | 3161 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
| 3162 |
- options->management_forget_disconnect = true; |
|
| 3162 |
+ options->management_flags |= MF_FORGET_DISCONNECT; |
|
| 3163 | 3163 |
} |
| 3164 | 3164 |
else if (streq (p[0], "management-client")) |
| 3165 | 3165 |
{
|
| 3166 | 3166 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
| 3167 |
- options->management_client = true; |
|
| 3167 |
+ options->management_flags |= MF_CONNECT_AS_CLIENT; |
|
| 3168 | 3168 |
options->management_write_peer_info_file = p[1]; |
| 3169 | 3169 |
} |
| 3170 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 3171 |
+ else if (streq (p[0], "management-client-auth")) |
|
| 3172 |
+ {
|
|
| 3173 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
| 3174 |
+ options->management_flags |= MF_CLIENT_AUTH; |
|
| 3175 |
+ } |
|
| 3176 |
+#endif |
|
| 3177 |
+#ifdef MANAGEMENT_PF |
|
| 3178 |
+ else if (streq (p[0], "management-client-pf")) |
|
| 3179 |
+ {
|
|
| 3180 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
| 3181 |
+ options->management_flags |= (MF_CLIENT_PF | MF_CLIENT_AUTH); |
|
| 3182 |
+ } |
|
| 3183 |
+#endif |
|
| 3170 | 3184 |
else if (streq (p[0], "management-log-cache") && p[1]) |
| 3171 | 3185 |
{
|
| 3172 | 3186 |
int cache; |
| ... | ... |
@@ -281,12 +281,10 @@ struct options |
| 281 | 281 |
int management_log_history_cache; |
| 282 | 282 |
int management_echo_buffer_size; |
| 283 | 283 |
int management_state_buffer_size; |
| 284 |
- bool management_query_passwords; |
|
| 285 |
- bool management_hold; |
|
| 286 |
- bool management_signal; |
|
| 287 |
- bool management_forget_disconnect; |
|
| 288 |
- bool management_client; |
|
| 289 | 284 |
const char *management_write_peer_info_file; |
| 285 |
+ |
|
| 286 |
+ /* Mask of MF_ values of manage.h */ |
|
| 287 |
+ unsigned int management_flags; |
|
| 290 | 288 |
#endif |
| 291 | 289 |
|
| 292 | 290 |
#ifdef ENABLE_PLUGIN |
| ... | ... |
@@ -537,6 +535,12 @@ struct options |
| 537 | 537 |
#define PLUGIN_OPTION_LIST(opt) (NULL) |
| 538 | 538 |
#endif |
| 539 | 539 |
|
| 540 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 541 |
+#define MAN_CLIENT_AUTH_ENABLED(opt) ((opt)->management_flags & MF_CLIENT_AUTH) |
|
| 542 |
+#else |
|
| 543 |
+#define MAN_CLIENT_AUTH_ENABLED(opt) (false) |
|
| 544 |
+#endif |
|
| 545 |
+ |
|
| 540 | 546 |
void parse_argv (struct options *options, |
| 541 | 547 |
const int argc, |
| 542 | 548 |
char *argv[], |
| ... | ... |
@@ -632,9 +636,7 @@ const char *auth_retry_print (void); |
| 632 | 632 |
|
| 633 | 633 |
#endif |
| 634 | 634 |
|
| 635 |
-#ifdef ENABLE_PLUGIN |
|
| 636 |
- |
|
| 637 |
-void options_plugin_import (struct options *options, |
|
| 635 |
+void options_string_import (struct options *options, |
|
| 638 | 636 |
const char *config, |
| 639 | 637 |
const int msglevel, |
| 640 | 638 |
const unsigned int permission_mask, |
| ... | ... |
@@ -642,5 +644,3 @@ void options_plugin_import (struct options *options, |
| 642 | 642 |
struct env_set *es); |
| 643 | 643 |
|
| 644 | 644 |
#endif |
| 645 |
- |
|
| 646 |
-#endif |
| 647 | 645 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,59 @@ |
| 0 |
+/* |
|
| 1 |
+ * OpenVPN -- An application to securely tunnel IP networks |
|
| 2 |
+ * over a single TCP/UDP port, with support for SSL/TLS-based |
|
| 3 |
+ * session authentication and key exchange, |
|
| 4 |
+ * packet encryption, packet authentication, and |
|
| 5 |
+ * packet compression. |
|
| 6 |
+ * |
|
| 7 |
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net> |
|
| 8 |
+ * |
|
| 9 |
+ * This program is free software; you can redistribute it and/or modify |
|
| 10 |
+ * it under the terms of the GNU General Public License version 2 |
|
| 11 |
+ * as published by the Free Software Foundation. |
|
| 12 |
+ * |
|
| 13 |
+ * This program is distributed in the hope that it will be useful, |
|
| 14 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 15 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 16 |
+ * GNU General Public License for more details. |
|
| 17 |
+ * |
|
| 18 |
+ * You should have received a copy of the GNU General Public License |
|
| 19 |
+ * along with this program (see the file COPYING included with this |
|
| 20 |
+ * distribution); if not, write to the Free Software Foundation, Inc., |
|
| 21 |
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 22 |
+ */ |
|
| 23 |
+ |
|
| 24 |
+#if defined(ENABLE_PF) && !defined(PF_INLINE_H) |
|
| 25 |
+#define PF_INLINE_H |
|
| 26 |
+ |
|
| 27 |
+/* |
|
| 28 |
+ * Inline functions |
|
| 29 |
+ */ |
|
| 30 |
+ |
|
| 31 |
+#define PCT_SRC 1 |
|
| 32 |
+#define PCT_DEST 2 |
|
| 33 |
+static inline bool |
|
| 34 |
+pf_c2c_test (const struct context *src, const struct context *dest, const char *prefix) |
|
| 35 |
+{
|
|
| 36 |
+ bool pf_cn_test (struct pf_set *pfs, const struct tls_multi *tm, const int type, const char *prefix); |
|
| 37 |
+ return (!src->c2.pf.enabled || pf_cn_test (src->c2.pf.pfs, dest->c2.tls_multi, PCT_DEST, prefix)) |
|
| 38 |
+ && (!dest->c2.pf.enabled || pf_cn_test (dest->c2.pf.pfs, src->c2.tls_multi, PCT_SRC, prefix)); |
|
| 39 |
+} |
|
| 40 |
+ |
|
| 41 |
+static inline bool |
|
| 42 |
+pf_addr_test (const struct context *src, const struct mroute_addr *dest, const char *prefix) |
|
| 43 |
+{
|
|
| 44 |
+ bool pf_addr_test_dowork (const struct context *src, const struct mroute_addr *dest, const char *prefix); |
|
| 45 |
+ |
|
| 46 |
+ if (src->c2.pf.enabled) |
|
| 47 |
+ return pf_addr_test_dowork (src, dest, prefix); |
|
| 48 |
+ else |
|
| 49 |
+ return true; |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+static inline bool |
|
| 53 |
+pf_kill_test (const struct pf_set *pfs) |
|
| 54 |
+{
|
|
| 55 |
+ return pfs->kill; |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+#endif |
| ... | ... |
@@ -32,6 +32,8 @@ |
| 32 | 32 |
|
| 33 | 33 |
#include "memdbg.h" |
| 34 | 34 |
|
| 35 |
+#include "pf-inline.h" |
|
| 36 |
+ |
|
| 35 | 37 |
static void |
| 36 | 38 |
pf_destroy (struct pf_set *pfs) |
| 37 | 39 |
{
|
| ... | ... |
@@ -64,7 +66,7 @@ pf_destroy (struct pf_set *pfs) |
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 | 66 |
static bool |
| 67 |
-add_client (const char *line, const char *fn, const int line_num, struct pf_cn_elem ***next, const bool exclude) |
|
| 67 |
+add_client (const char *line, const char *prefix, const int line_num, struct pf_cn_elem ***next, const bool exclude) |
|
| 68 | 68 |
{
|
| 69 | 69 |
struct pf_cn_elem *e; |
| 70 | 70 |
ALLOC_OBJ_CLEAR (e, struct pf_cn_elem); |
| ... | ... |
@@ -76,34 +78,44 @@ add_client (const char *line, const char *fn, const int line_num, struct pf_cn_e |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
static bool |
| 79 |
-add_subnet (const char *line, const char *fn, const int line_num, struct pf_subnet ***next, const bool exclude) |
|
| 79 |
+add_subnet (const char *line, const char *prefix, const int line_num, struct pf_subnet ***next, const bool exclude) |
|
| 80 | 80 |
{
|
| 81 | 81 |
struct in_addr network; |
| 82 | 82 |
in_addr_t netmask = 0; |
| 83 |
- int netbits = 32; |
|
| 84 |
- char *div = strchr (line, '/'); |
|
| 85 | 83 |
|
| 86 |
- if (div) |
|
| 84 |
+ if (strcmp (line, "unknown")) |
|
| 87 | 85 |
{
|
| 88 |
- *div++ = '\0'; |
|
| 89 |
- if (sscanf (div, "%d", &netbits) != 1) |
|
| 86 |
+ int netbits = 32; |
|
| 87 |
+ char *div = strchr (line, '/'); |
|
| 88 |
+ |
|
| 89 |
+ if (div) |
|
| 90 | 90 |
{
|
| 91 |
- msg (D_PF, "PF: %s/%d: bad '/n' subnet specifier: '%s'", fn, line_num, div); |
|
| 92 |
- return false; |
|
| 91 |
+ *div++ = '\0'; |
|
| 92 |
+ if (sscanf (div, "%d", &netbits) != 1) |
|
| 93 |
+ {
|
|
| 94 |
+ msg (D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: '%s'", prefix, line_num, div); |
|
| 95 |
+ return false; |
|
| 96 |
+ } |
|
| 97 |
+ if (netbits < 0 || netbits > 32) |
|
| 98 |
+ {
|
|
| 99 |
+ msg (D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: must be between 0 and 32: '%s'", prefix, line_num, div); |
|
| 100 |
+ return false; |
|
| 101 |
+ } |
|
| 93 | 102 |
} |
| 94 |
- if (netbits < 0 || netbits > 32) |
|
| 103 |
+ |
|
| 104 |
+ if (openvpn_inet_aton (line, &network) != OIA_IP) |
|
| 95 | 105 |
{
|
| 96 |
- msg (D_PF, "PF: %s/%d: bad '/n' subnet specifier: must be between 0 and 32: '%s'", fn, line_num, div); |
|
| 106 |
+ msg (D_PF_INFO, "PF: %s/%d: bad network address: '%s'", prefix, line_num, line); |
|
| 97 | 107 |
return false; |
| 98 | 108 |
} |
| 109 |
+ netmask = netbits_to_netmask (netbits); |
|
| 99 | 110 |
} |
| 100 |
- |
|
| 101 |
- if (openvpn_inet_aton (line, &network) != OIA_IP) |
|
| 111 |
+ else |
|
| 102 | 112 |
{
|
| 103 |
- msg (D_PF, "PF: %s/%d: bad network address: '%s'", fn, line_num, line); |
|
| 104 |
- return false; |
|
| 113 |
+ /* match special "unknown" tag for addresses unrecognized by mroute */ |
|
| 114 |
+ network.s_addr = htonl(0); |
|
| 115 |
+ netmask = ~0; |
|
| 105 | 116 |
} |
| 106 |
- netmask = netbits_to_netmask (netbits); |
|
| 107 | 117 |
|
| 108 | 118 |
{
|
| 109 | 119 |
struct pf_subnet *e; |
| ... | ... |
@@ -130,7 +142,7 @@ cn_compare_function (const void *key1, const void *key2) |
| 130 | 130 |
} |
| 131 | 131 |
|
| 132 | 132 |
static bool |
| 133 |
-genhash (struct pf_cn_set *cns, const char *fn, const int n_clients) |
|
| 133 |
+genhash (struct pf_cn_set *cns, const char *prefix, const int n_clients) |
|
| 134 | 134 |
{
|
| 135 | 135 |
struct pf_cn_elem *e; |
| 136 | 136 |
bool status = true; |
| ... | ... |
@@ -143,7 +155,7 @@ genhash (struct pf_cn_set *cns, const char *fn, const int n_clients) |
| 143 | 143 |
{
|
| 144 | 144 |
if (!hash_add (cns->hash_table, e->rule.cn, &e->rule, false)) |
| 145 | 145 |
{
|
| 146 |
- msg (D_PF, "PF: %s: duplicate common name in [clients] section: '%s'", fn, e->rule.cn); |
|
| 146 |
+ msg (D_PF_INFO, "PF: %s: duplicate common name in [clients] section: '%s'", prefix, e->rule.cn); |
|
| 147 | 147 |
status = false; |
| 148 | 148 |
} |
| 149 | 149 |
} |
| ... | ... |
@@ -152,7 +164,7 @@ genhash (struct pf_cn_set *cns, const char *fn, const int n_clients) |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 | 154 |
static struct pf_set * |
| 155 |
-pf_init (const char *fn) |
|
| 155 |
+pf_init (const struct buffer_list *bl, const char *prefix, const bool allow_kill) |
|
| 156 | 156 |
{
|
| 157 | 157 |
# define MODE_UNDEF 0 |
| 158 | 158 |
# define MODE_CLIENTS 1 |
| ... | ... |
@@ -163,18 +175,19 @@ pf_init (const char *fn) |
| 163 | 163 |
int n_subnets = 0; |
| 164 | 164 |
int n_errors = 0; |
| 165 | 165 |
struct pf_set *pfs = NULL; |
| 166 |
- char line[256]; |
|
| 166 |
+ char line[PF_MAX_LINE_LEN]; |
|
| 167 | 167 |
|
| 168 | 168 |
ALLOC_OBJ_CLEAR (pfs, struct pf_set); |
| 169 |
- FILE *fp = fopen (fn, "r"); |
|
| 170 |
- if (fp) |
|
| 169 |
+ if (bl) |
|
| 171 | 170 |
{
|
| 172 | 171 |
struct pf_cn_elem **cl = &pfs->cns.list; |
| 173 | 172 |
struct pf_subnet **sl = &pfs->sns.list; |
| 173 |
+ struct buffer_entry *be; |
|
| 174 | 174 |
|
| 175 |
- while (fgets (line, sizeof (line), fp) != NULL) |
|
| 175 |
+ for (be = bl->head; be != NULL; be = be->next) |
|
| 176 | 176 |
{
|
| 177 | 177 |
++line_num; |
| 178 |
+ strncpynt (line, BSTR(&be->buf), sizeof(line)); |
|
| 178 | 179 |
rm_trailing_chars (line, "\r\n\t "); |
| 179 | 180 |
if (line[0] == '\0' || line[0] == '#') |
| 180 | 181 |
; |
| ... | ... |
@@ -184,19 +197,19 @@ pf_init (const char *fn) |
| 184 | 184 |
|
| 185 | 185 |
if (line[1] =='\0') |
| 186 | 186 |
{
|
| 187 |
- msg (D_PF, "PF: %s/%d: no data after +/-: '%s'", fn, line_num, line); |
|
| 187 |
+ msg (D_PF_INFO, "PF: %s/%d: no data after +/-: '%s'", prefix, line_num, line); |
|
| 188 | 188 |
++n_errors; |
| 189 | 189 |
} |
| 190 | 190 |
else if (mode == MODE_CLIENTS) |
| 191 | 191 |
{
|
| 192 |
- if (add_client (&line[1], fn, line_num, &cl, exclude)) |
|
| 192 |
+ if (add_client (&line[1], prefix, line_num, &cl, exclude)) |
|
| 193 | 193 |
++n_clients; |
| 194 | 194 |
else |
| 195 | 195 |
++n_errors; |
| 196 | 196 |
} |
| 197 | 197 |
else if (mode == MODE_SUBNETS) |
| 198 | 198 |
{
|
| 199 |
- if (add_subnet (&line[1], fn, line_num, &sl, exclude)) |
|
| 199 |
+ if (add_subnet (&line[1], prefix, line_num, &sl, exclude)) |
|
| 200 | 200 |
++n_subnets; |
| 201 | 201 |
else |
| 202 | 202 |
++n_errors; |
| ... | ... |
@@ -232,41 +245,40 @@ pf_init (const char *fn) |
| 232 | 232 |
} |
| 233 | 233 |
else if (!strcasecmp (line, "[end]")) |
| 234 | 234 |
goto done; |
| 235 |
- else if (!strcasecmp (line, "[kill]")) |
|
| 235 |
+ else if (allow_kill && !strcasecmp (line, "[kill]")) |
|
| 236 | 236 |
goto kill; |
| 237 | 237 |
else |
| 238 | 238 |
{
|
| 239 | 239 |
mode = MODE_UNDEF; |
| 240 |
- msg (D_PF, "PF: %s/%d unknown tag: '%s'", fn, line_num, line); |
|
| 240 |
+ msg (D_PF_INFO, "PF: %s/%d unknown tag: '%s'", prefix, line_num, line); |
|
| 241 | 241 |
++n_errors; |
| 242 | 242 |
} |
| 243 | 243 |
} |
| 244 | 244 |
else |
| 245 | 245 |
{
|
| 246 |
- msg (D_PF, "PF: %s/%d line must begin with '+', '-', or '[' : '%s'", fn, line_num, line); |
|
| 246 |
+ msg (D_PF_INFO, "PF: %s/%d line must begin with '+', '-', or '[' : '%s'", prefix, line_num, line); |
|
| 247 | 247 |
++n_errors; |
| 248 | 248 |
} |
| 249 | 249 |
} |
| 250 | 250 |
++n_errors; |
| 251 |
- msg (D_PF, "PF: %s: missing [end]", fn); |
|
| 251 |
+ msg (D_PF_INFO, "PF: %s: missing [end]", prefix); |
|
| 252 | 252 |
} |
| 253 | 253 |
else |
| 254 | 254 |
{
|
| 255 |
- msg (D_PF|M_ERRNO, "PF: %s: cannot open", fn); |
|
| 255 |
+ msg (D_PF_INFO, "PF: %s: cannot open", prefix); |
|
| 256 | 256 |
++n_errors; |
| 257 | 257 |
} |
| 258 | 258 |
|
| 259 | 259 |
done: |
| 260 |
- if (fp) |
|
| 260 |
+ if (bl) |
|
| 261 | 261 |
{
|
| 262 |
- fclose (fp); |
|
| 263 | 262 |
if (!n_errors) |
| 264 | 263 |
{
|
| 265 |
- if (!genhash (&pfs->cns, fn, n_clients)) |
|
| 264 |
+ if (!genhash (&pfs->cns, prefix, n_clients)) |
|
| 266 | 265 |
++n_errors; |
| 267 | 266 |
} |
| 268 | 267 |
if (n_errors) |
| 269 |
- msg (D_PF, "PF: %s rejected due to %d error(s)", fn, n_errors); |
|
| 268 |
+ msg (D_PF_INFO, "PF: %s rejected due to %d error(s)", prefix, n_errors); |
|
| 270 | 269 |
} |
| 271 | 270 |
if (n_errors) |
| 272 | 271 |
{
|
| ... | ... |
@@ -276,15 +288,32 @@ pf_init (const char *fn) |
| 276 | 276 |
return pfs; |
| 277 | 277 |
|
| 278 | 278 |
kill: |
| 279 |
- if (fp) |
|
| 280 |
- fclose (fp); |
|
| 281 | 279 |
pf_destroy (pfs); |
| 282 | 280 |
ALLOC_OBJ_CLEAR (pfs, struct pf_set); |
| 283 | 281 |
pfs->kill = true; |
| 284 | 282 |
return pfs; |
| 285 | 283 |
} |
| 286 | 284 |
|
| 287 |
-#if PF_DEBUG >= 1 |
|
| 285 |
+#ifdef PLUGIN_PF |
|
| 286 |
+static struct pf_set * |
|
| 287 |
+pf_init_from_file (const char *fn) |
|
| 288 |
+{
|
|
| 289 |
+ struct buffer_list *bl = buffer_list_file (fn, PF_MAX_LINE_LEN); |
|
| 290 |
+ if (bl) |
|
| 291 |
+ {
|
|
| 292 |
+ struct pf_set *pfs = pf_init (bl, fn, true); |
|
| 293 |
+ buffer_list_free (bl); |
|
| 294 |
+ return pfs; |
|
| 295 |
+ } |
|
| 296 |
+ else |
|
| 297 |
+ {
|
|
| 298 |
+ msg (D_PF_INFO|M_ERRNO, "PF: %s: cannot open", fn); |
|
| 299 |
+ return NULL; |
|
| 300 |
+ } |
|
| 301 |
+} |
|
| 302 |
+#endif |
|
| 303 |
+ |
|
| 304 |
+#ifdef ENABLE_DEBUG |
|
| 288 | 305 |
|
| 289 | 306 |
static const char * |
| 290 | 307 |
drop_accept (const bool accept) |
| ... | ... |
@@ -292,31 +321,46 @@ drop_accept (const bool accept) |
| 292 | 292 |
return accept ? "ACCEPT" : "DROP"; |
| 293 | 293 |
} |
| 294 | 294 |
|
| 295 |
-#endif |
|
| 296 |
- |
|
| 297 |
-#if PF_DEBUG >= 2 |
|
| 295 |
+static const char * |
|
| 296 |
+pct_name (const int type) |
|
| 297 |
+{
|
|
| 298 |
+ switch (type) |
|
| 299 |
+ {
|
|
| 300 |
+ case PCT_SRC: |
|
| 301 |
+ return "SRC"; |
|
| 302 |
+ case PCT_DEST: |
|
| 303 |
+ return "DEST"; |
|
| 304 |
+ default: |
|
| 305 |
+ return "???"; |
|
| 306 |
+ } |
|
| 307 |
+} |
|
| 298 | 308 |
|
| 299 | 309 |
static void |
| 300 | 310 |
pf_cn_test_print (const char *prefix, |
| 311 |
+ const int type, |
|
| 312 |
+ const char *prefix2, |
|
| 301 | 313 |
const char *cn, |
| 302 | 314 |
const bool allow, |
| 303 | 315 |
const struct pf_cn *rule) |
| 304 | 316 |
{
|
| 305 | 317 |
if (rule) |
| 306 | 318 |
{
|
| 307 |
- msg (D_PF, "PF: %s %s %s rule=[%s %s]", |
|
| 308 |
- prefix, cn, drop_accept (allow), |
|
| 319 |
+ dmsg (D_PF_DEBUG, "PF: %s/%s/%s %s %s rule=[%s %s]", |
|
| 320 |
+ prefix, prefix2, pct_name (type), |
|
| 321 |
+ cn, drop_accept (allow), |
|
| 309 | 322 |
rule->cn, drop_accept (!rule->exclude)); |
| 310 | 323 |
} |
| 311 | 324 |
else |
| 312 | 325 |
{
|
| 313 |
- msg (D_PF, "PF: %s %s %s", |
|
| 314 |
- prefix, cn, drop_accept (allow)); |
|
| 326 |
+ dmsg (D_PF_DEBUG, "PF: %s/%s/%s %s %s", |
|
| 327 |
+ prefix, prefix2, pct_name (type), |
|
| 328 |
+ cn, drop_accept (allow)); |
|
| 315 | 329 |
} |
| 316 | 330 |
} |
| 317 | 331 |
|
| 318 | 332 |
static void |
| 319 | 333 |
pf_addr_test_print (const char *prefix, |
| 334 |
+ const char *prefix2, |
|
| 320 | 335 |
const struct context *src, |
| 321 | 336 |
const struct mroute_addr *dest, |
| 322 | 337 |
const bool allow, |
| ... | ... |
@@ -325,10 +369,11 @@ pf_addr_test_print (const char *prefix, |
| 325 | 325 |
struct gc_arena gc = gc_new (); |
| 326 | 326 |
if (rule) |
| 327 | 327 |
{
|
| 328 |
- msg (D_PF, "PF: %s %s %s %s rule=[%s/%s %s]", |
|
| 328 |
+ dmsg (D_PF_DEBUG, "PF: %s/%s %s %s %s rule=[%s/%s %s]", |
|
| 329 | 329 |
prefix, |
| 330 |
+ prefix2, |
|
| 330 | 331 |
tls_common_name (src->c2.tls_multi, false), |
| 331 |
- mroute_addr_print (dest, &gc), |
|
| 332 |
+ mroute_addr_print_ex (dest, MAPF_SHOW_ARP, &gc), |
|
| 332 | 333 |
drop_accept (allow), |
| 333 | 334 |
print_in_addr_t (rule->network, 0, &gc), |
| 334 | 335 |
print_in_addr_t (rule->netmask, 0, &gc), |
| ... | ... |
@@ -336,10 +381,11 @@ pf_addr_test_print (const char *prefix, |
| 336 | 336 |
} |
| 337 | 337 |
else |
| 338 | 338 |
{
|
| 339 |
- msg (D_PF, "PF: %s %s %s %s", |
|
| 339 |
+ dmsg (D_PF_DEBUG, "PF: %s/%s %s %s %s", |
|
| 340 | 340 |
prefix, |
| 341 |
+ prefix2, |
|
| 341 | 342 |
tls_common_name (src->c2.tls_multi, false), |
| 342 |
- mroute_addr_print (dest, &gc), |
|
| 343 |
+ mroute_addr_print_ex (dest, MAPF_SHOW_ARP, &gc), |
|
| 343 | 344 |
drop_accept (allow)); |
| 344 | 345 |
} |
| 345 | 346 |
gc_free (&gc); |
| ... | ... |
@@ -357,8 +403,8 @@ lookup_cn_rule (struct hash *h, const char *cn, const uint32_t cn_hash) |
| 357 | 357 |
return NULL; |
| 358 | 358 |
} |
| 359 | 359 |
|
| 360 |
-static inline bool |
|
| 361 |
-cn_test (struct pf_set *pfs, const struct tls_multi *tm) |
|
| 360 |
+bool |
|
| 361 |
+pf_cn_test (struct pf_set *pfs, const struct tls_multi *tm, const int type, const char *prefix) |
|
| 362 | 362 |
{
|
| 363 | 363 |
if (!pfs->kill) |
| 364 | 364 |
{
|
| ... | ... |
@@ -369,8 +415,9 @@ cn_test (struct pf_set *pfs, const struct tls_multi *tm) |
| 369 | 369 |
const struct pf_cn *rule = lookup_cn_rule (pfs->cns.hash_table, cn, cn_hash); |
| 370 | 370 |
if (rule) |
| 371 | 371 |
{
|
| 372 |
-#if PF_DEBUG >= 2 |
|
| 373 |
- pf_cn_test_print ("PF_CN_MATCH", cn, !rule->exclude, rule);
|
|
| 372 |
+#ifdef ENABLE_DEBUG |
|
| 373 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 374 |
+ pf_cn_test_print ("PF_CN_MATCH", type, prefix, cn, !rule->exclude, rule);
|
|
| 374 | 375 |
#endif |
| 375 | 376 |
if (!rule->exclude) |
| 376 | 377 |
return true; |
| ... | ... |
@@ -379,8 +426,9 @@ cn_test (struct pf_set *pfs, const struct tls_multi *tm) |
| 379 | 379 |
} |
| 380 | 380 |
else |
| 381 | 381 |
{
|
| 382 |
-#if PF_DEBUG >= 2 |
|
| 383 |
- pf_cn_test_print ("PF_CN_DEFAULT", cn, pfs->cns.default_allow, NULL);
|
|
| 382 |
+#ifdef ENABLE_DEBUG |
|
| 383 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 384 |
+ pf_cn_test_print ("PF_CN_DEFAULT", type, prefix, cn, pfs->cns.default_allow, NULL);
|
|
| 384 | 385 |
#endif |
| 385 | 386 |
if (pfs->cns.default_allow) |
| 386 | 387 |
return true; |
| ... | ... |
@@ -389,59 +437,50 @@ cn_test (struct pf_set *pfs, const struct tls_multi *tm) |
| 389 | 389 |
} |
| 390 | 390 |
} |
| 391 | 391 |
} |
| 392 |
-#if PF_DEBUG >= 2 |
|
| 393 |
- pf_cn_test_print ("PF_CN_FAULT", tls_common_name (tm, false), false, NULL);
|
|
| 392 |
+#ifdef ENABLE_DEBUG |
|
| 393 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 394 |
+ pf_cn_test_print ("PF_CN_FAULT", type, prefix, tls_common_name (tm, false), false, NULL);
|
|
| 394 | 395 |
#endif |
| 395 | 396 |
return false; |
| 396 | 397 |
} |
| 397 | 398 |
|
| 398 | 399 |
bool |
| 399 |
-pf_c2c_test (const struct context *src, const struct context *dest) |
|
| 400 |
+pf_addr_test_dowork (const struct context *src, const struct mroute_addr *dest, const char *prefix) |
|
| 400 | 401 |
{
|
| 401 |
- return (!src->c2.pf.filename || cn_test (src->c2.pf.pfs, dest->c2.tls_multi)) |
|
| 402 |
- && (!dest->c2.pf.filename || cn_test (dest->c2.pf.pfs, src->c2.tls_multi)); |
|
| 403 |
-} |
|
| 404 |
- |
|
| 405 |
-bool |
|
| 406 |
-pf_addr_test (const struct context *src, const struct mroute_addr *dest) |
|
| 407 |
-{
|
|
| 408 |
- if (src->c2.pf.filename) |
|
| 402 |
+ struct pf_set *pfs = src->c2.pf.pfs; |
|
| 403 |
+ if (pfs && !pfs->kill) |
|
| 409 | 404 |
{
|
| 410 |
- struct pf_set *pfs = src->c2.pf.pfs; |
|
| 411 |
- if (pfs && !pfs->kill) |
|
| 405 |
+ const in_addr_t addr = in_addr_t_from_mroute_addr (dest); |
|
| 406 |
+ const struct pf_subnet *se = pfs->sns.list; |
|
| 407 |
+ while (se) |
|
| 412 | 408 |
{
|
| 413 |
- const in_addr_t addr = in_addr_t_from_mroute_addr (dest); |
|
| 414 |
- const struct pf_subnet *se = pfs->sns.list; |
|
| 415 |
- while (se) |
|
| 409 |
+ if ((addr & se->rule.netmask) == se->rule.network) |
|
| 416 | 410 |
{
|
| 417 |
- if ((addr & se->rule.netmask) == se->rule.network) |
|
| 418 |
- {
|
|
| 419 |
-#if PF_DEBUG >= 2 |
|
| 420 |
- pf_addr_test_print ("PF_ADDR_MATCH", src, dest, !se->rule.exclude, &se->rule);
|
|
| 411 |
+#ifdef ENABLE_DEBUG |
|
| 412 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 413 |
+ pf_addr_test_print ("PF_ADDR_MATCH", prefix, src, dest, !se->rule.exclude, &se->rule);
|
|
| 421 | 414 |
#endif |
| 422 |
- return !se->rule.exclude; |
|
| 423 |
- } |
|
| 424 |
- se = se->next; |
|
| 415 |
+ return !se->rule.exclude; |
|
| 425 | 416 |
} |
| 426 |
-#if PF_DEBUG >= 2 |
|
| 427 |
- pf_addr_test_print ("PF_ADDR_DEFAULT", src, dest, pfs->sns.default_allow, NULL);
|
|
| 428 |
-#endif |
|
| 429 |
- return pfs->sns.default_allow; |
|
| 417 |
+ se = se->next; |
|
| 430 | 418 |
} |
| 431 |
- else |
|
| 432 |
- {
|
|
| 433 |
-#if PF_DEBUG >= 2 |
|
| 434 |
- pf_addr_test_print ("PF_ADDR_FAULT", src, dest, false, NULL);
|
|
| 419 |
+#ifdef ENABLE_DEBUG |
|
| 420 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 421 |
+ pf_addr_test_print ("PF_ADDR_DEFAULT", prefix, src, dest, pfs->sns.default_allow, NULL);
|
|
| 435 | 422 |
#endif |
| 436 |
- return false; |
|
| 437 |
- } |
|
| 423 |
+ return pfs->sns.default_allow; |
|
| 438 | 424 |
} |
| 439 | 425 |
else |
| 440 | 426 |
{
|
| 441 |
- return true; |
|
| 427 |
+#ifdef ENABLE_DEBUG |
|
| 428 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 429 |
+ pf_addr_test_print ("PF_ADDR_FAULT", prefix, src, dest, false, NULL);
|
|
| 430 |
+#endif |
|
| 431 |
+ return false; |
|
| 442 | 432 |
} |
| 443 | 433 |
} |
| 444 | 434 |
|
| 435 |
+#ifdef PLUGIN_PF |
|
| 445 | 436 |
void |
| 446 | 437 |
pf_check_reload (struct context *c) |
| 447 | 438 |
{
|
| ... | ... |
@@ -450,14 +489,16 @@ pf_check_reload (struct context *c) |
| 450 | 450 |
const int wakeup_transition = 60; |
| 451 | 451 |
bool reloaded = false; |
| 452 | 452 |
|
| 453 |
- if (c->c2.pf.filename && event_timeout_trigger (&c->c2.pf.reload, &c->c2.timeval, ETT_DEFAULT)) |
|
| 453 |
+ if (c->c2.pf.enabled |
|
| 454 |
+ && c->c2.pf.filename |
|
| 455 |
+ && event_timeout_trigger (&c->c2.pf.reload, &c->c2.timeval, ETT_DEFAULT)) |
|
| 454 | 456 |
{
|
| 455 | 457 |
struct stat s; |
| 456 | 458 |
if (!stat (c->c2.pf.filename, &s)) |
| 457 | 459 |
{
|
| 458 | 460 |
if (s.st_mtime > c->c2.pf.file_last_mod) |
| 459 | 461 |
{
|
| 460 |
- struct pf_set *pfs = pf_init (c->c2.pf.filename); |
|
| 462 |
+ struct pf_set *pfs = pf_init_from_file (c->c2.pf.filename); |
|
| 461 | 463 |
if (pfs) |
| 462 | 464 |
{
|
| 463 | 465 |
if (c->c2.pf.pfs) |
| ... | ... |
@@ -482,16 +523,35 @@ pf_check_reload (struct context *c) |
| 482 | 482 |
c->c2.pf.n_check_reload++; |
| 483 | 483 |
} |
| 484 | 484 |
} |
| 485 |
-#if PF_DEBUG >= 1 |
|
| 486 |
- if (reloaded) |
|
| 487 |
- pf_context_print (&c->c2.pf, "pf_check_reload", M_INFO); |
|
| 485 |
+#ifdef ENABLE_DEBUG |
|
| 486 |
+ if (reloaded && check_debug_level (D_PF_DEBUG)) |
|
| 487 |
+ pf_context_print (&c->c2.pf, "pf_check_reload", D_PF_DEBUG); |
|
| 488 | 488 |
#endif |
| 489 | 489 |
} |
| 490 |
+#endif |
|
| 491 |
+ |
|
| 492 |
+#ifdef MANAGEMENT_PF |
|
| 493 |
+bool |
|
| 494 |
+pf_load_from_buffer_list (struct context *c, const struct buffer_list *config) |
|
| 495 |
+{
|
|
| 496 |
+ struct pf_set *pfs = pf_init (config, "[SERVER-PF]", false); |
|
| 497 |
+ if (pfs) |
|
| 498 |
+ {
|
|
| 499 |
+ if (c->c2.pf.pfs) |
|
| 500 |
+ pf_destroy (c->c2.pf.pfs); |
|
| 501 |
+ c->c2.pf.pfs = pfs; |
|
| 502 |
+ return true; |
|
| 503 |
+ } |
|
| 504 |
+ else |
|
| 505 |
+ return false; |
|
| 506 |
+} |
|
| 507 |
+#endif |
|
| 490 | 508 |
|
| 491 | 509 |
void |
| 492 | 510 |
pf_init_context (struct context *c) |
| 493 | 511 |
{
|
| 494 | 512 |
struct gc_arena gc = gc_new (); |
| 513 |
+#ifdef PLUGIN_PF |
|
| 495 | 514 |
if (plugin_defined (c->plugins, OPENVPN_PLUGIN_ENABLE_PF)) |
| 496 | 515 |
{
|
| 497 | 516 |
const char *pf_file = create_temp_filename (c->options.tmp_dir, "pf", &gc); |
| ... | ... |
@@ -502,8 +562,10 @@ pf_init_context (struct context *c) |
| 502 | 502 |
{
|
| 503 | 503 |
event_timeout_init (&c->c2.pf.reload, 1, now); |
| 504 | 504 |
c->c2.pf.filename = string_alloc (pf_file, NULL); |
| 505 |
-#if PF_DEBUG >= 1 |
|
| 506 |
- pf_context_print (&c->c2.pf, "pf_init_context", M_INFO); |
|
| 505 |
+ c->c2.pf.enabled = true; |
|
| 506 |
+#ifdef ENABLE_DEBUG |
|
| 507 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 508 |
+ pf_context_print (&c->c2.pf, "pf_init_context#1", D_PF_DEBUG); |
|
| 507 | 509 |
#endif |
| 508 | 510 |
} |
| 509 | 511 |
else |
| ... | ... |
@@ -511,22 +573,35 @@ pf_init_context (struct context *c) |
| 511 | 511 |
msg (M_WARN, "WARNING: OPENVPN_PLUGIN_ENABLE_PF disabled"); |
| 512 | 512 |
} |
| 513 | 513 |
} |
| 514 |
+#endif |
|
| 515 |
+#ifdef MANAGEMENT_PF |
|
| 516 |
+ if (!c->c2.pf.enabled && management_enable_pf (management)) |
|
| 517 |
+ {
|
|
| 518 |
+ c->c2.pf.enabled = true; |
|
| 519 |
+#ifdef ENABLE_DEBUG |
|
| 520 |
+ if (check_debug_level (D_PF_DEBUG)) |
|
| 521 |
+ pf_context_print (&c->c2.pf, "pf_init_context#2", D_PF_DEBUG); |
|
| 522 |
+#endif |
|
| 523 |
+ } |
|
| 524 |
+#endif |
|
| 514 | 525 |
gc_free (&gc); |
| 515 | 526 |
} |
| 516 | 527 |
|
| 517 | 528 |
void |
| 518 | 529 |
pf_destroy_context (struct pf_context *pfc) |
| 519 | 530 |
{
|
| 531 |
+#ifdef PLUGIN_PF |
|
| 520 | 532 |
if (pfc->filename) |
| 521 | 533 |
{
|
| 522 | 534 |
delete_file (pfc->filename); |
| 523 | 535 |
free (pfc->filename); |
| 524 | 536 |
} |
| 537 |
+#endif |
|
| 525 | 538 |
if (pfc->pfs) |
| 526 | 539 |
pf_destroy (pfc->pfs); |
| 527 | 540 |
} |
| 528 | 541 |
|
| 529 |
-#if PF_DEBUG >= 1 |
|
| 542 |
+#ifdef ENABLE_DEBUG |
|
| 530 | 543 |
|
| 531 | 544 |
static void |
| 532 | 545 |
pf_subnet_set_print (const struct pf_subnet_set *s, const int lev) |
| ... | ... |
@@ -613,10 +688,13 @@ pf_context_print (const struct pf_context *pfc, const char *prefix, const int le |
| 613 | 613 |
msg (lev, "----- %s : struct pf_context -----", prefix); |
| 614 | 614 |
if (pfc) |
| 615 | 615 |
{
|
| 616 |
+ msg (lev, "enabled=%d", pfc->enabled); |
|
| 617 |
+#ifdef PLUGIN_PF |
|
| 616 | 618 |
msg (lev, "filename='%s'", np(pfc->filename)); |
| 617 | 619 |
msg (lev, "file_last_mod=%u", (unsigned int)pfc->file_last_mod); |
| 618 | 620 |
msg (lev, "n_check_reload=%u", pfc->n_check_reload); |
| 619 | 621 |
msg (lev, "reload=[%d,%u,%u]", pfc->reload.defined, pfc->reload.n, (unsigned int)pfc->reload.last); |
| 622 |
+#endif |
|
| 620 | 623 |
pf_set_print (pfc->pfs, lev); |
| 621 | 624 |
} |
| 622 | 625 |
msg (lev, "--------------------"); |
| ... | ... |
@@ -30,7 +30,7 @@ |
| 30 | 30 |
#include "list.h" |
| 31 | 31 |
#include "mroute.h" |
| 32 | 32 |
|
| 33 |
-#define PF_DEBUG 0 |
|
| 33 |
+#define PF_MAX_LINE_LEN 256 |
|
| 34 | 34 |
|
| 35 | 35 |
struct context; |
| 36 | 36 |
|
| ... | ... |
@@ -73,30 +73,29 @@ struct pf_set {
|
| 73 | 73 |
}; |
| 74 | 74 |
|
| 75 | 75 |
struct pf_context {
|
| 76 |
+ bool enabled; |
|
| 77 |
+ struct pf_set *pfs; |
|
| 78 |
+#ifdef PLUGIN_PF |
|
| 76 | 79 |
char *filename; |
| 77 | 80 |
time_t file_last_mod; |
| 78 | 81 |
unsigned int n_check_reload; |
| 79 | 82 |
struct event_timeout reload; |
| 80 |
- struct pf_set *pfs; |
|
| 83 |
+#endif |
|
| 81 | 84 |
}; |
| 82 | 85 |
|
| 83 | 86 |
void pf_init_context (struct context *c); |
| 84 | 87 |
|
| 85 | 88 |
void pf_destroy_context (struct pf_context *pfc); |
| 86 | 89 |
|
| 90 |
+#ifdef PLUGIN_PF |
|
| 87 | 91 |
void pf_check_reload (struct context *c); |
| 92 |
+#endif |
|
| 88 | 93 |
|
| 89 |
-bool pf_c2c_test (const struct context *src, const struct context *dest); |
|
| 90 |
- |
|
| 91 |
-bool pf_addr_test (const struct context *src, const struct mroute_addr *dest); |
|
| 92 |
- |
|
| 93 |
-static inline bool |
|
| 94 |
-pf_kill_test (const struct pf_set *pfs) |
|
| 95 |
-{
|
|
| 96 |
- return pfs->kill; |
|
| 97 |
-} |
|
| 94 |
+#ifdef MANAGEMENT_PF |
|
| 95 |
+bool pf_load_from_buffer_list (struct context *c, const struct buffer_list *config); |
|
| 96 |
+#endif |
|
| 98 | 97 |
|
| 99 |
-#if PF_DEBUG >= 1 |
|
| 98 |
+#ifdef ENABLE_DEBUG |
|
| 100 | 99 |
void pf_context_print (const struct pf_context *pfc, const char *prefix, const int lev); |
| 101 | 100 |
#endif |
| 102 | 101 |
|
| ... | ... |
@@ -28,6 +28,8 @@ |
| 28 | 28 |
#include "common.h" |
| 29 | 29 |
#include "buffer.h" |
| 30 | 30 |
|
| 31 |
+#pragma pack(1) |
|
| 32 |
+ |
|
| 31 | 33 |
/* |
| 32 | 34 |
* Tunnel types |
| 33 | 35 |
*/ |
| ... | ... |
@@ -62,6 +64,24 @@ struct openvpn_ethhdr |
| 62 | 62 |
uint16_t proto; /* packet type ID field */ |
| 63 | 63 |
}; |
| 64 | 64 |
|
| 65 |
+struct openvpn_arp {
|
|
| 66 |
+# define ARP_MAC_ADDR_TYPE 0x0001 |
|
| 67 |
+ uint16_t mac_addr_type; // 0x0001 |
|
| 68 |
+ |
|
| 69 |
+ uint16_t proto_addr_type; // 0x0800 |
|
| 70 |
+ uint8_t mac_addr_size; // 0x06 |
|
| 71 |
+ uint8_t proto_addr_size; // 0x04 |
|
| 72 |
+ |
|
| 73 |
+# define ARP_REQUEST 0x0001 |
|
| 74 |
+# define ARP_REPLY 0x0002 |
|
| 75 |
+ uint16_t arp_command; // 0x0001 for ARP request, 0x0002 for ARP reply |
|
| 76 |
+ |
|
| 77 |
+ uint8_t mac_src[OPENVPN_ETH_ALEN]; |
|
| 78 |
+ in_addr_t ip_src; |
|
| 79 |
+ uint8_t mac_dest[OPENVPN_ETH_ALEN]; |
|
| 80 |
+ in_addr_t ip_dest; |
|
| 81 |
+}; |
|
| 82 |
+ |
|
| 65 | 83 |
struct openvpn_iphdr {
|
| 66 | 84 |
# define OPENVPN_IPH_GET_VER(v) (((v) >> 4) & 0x0F) |
| 67 | 85 |
# define OPENVPN_IPH_GET_LEN(v) (((v) & 0x0F) << 2) |
| ... | ... |
@@ -129,6 +149,8 @@ struct openvpn_tcphdr {
|
| 129 | 129 |
#define OPENVPN_TCPOPT_MAXSEG 2 |
| 130 | 130 |
#define OPENVPN_TCPOLEN_MAXSEG 4 |
| 131 | 131 |
|
| 132 |
+#pragma pack() |
|
| 133 |
+ |
|
| 132 | 134 |
/* |
| 133 | 135 |
* The following macro is used to update an |
| 134 | 136 |
* internet checksum. "acc" is a 32-bit |
| ... | ... |
@@ -860,6 +860,26 @@ tls_lock_common_name (struct tls_multi *multi) |
| 860 | 860 |
} |
| 861 | 861 |
|
| 862 | 862 |
#ifdef ENABLE_DEF_AUTH |
| 863 |
+/* key_state_test_auth_control_file return values, |
|
| 864 |
+ NOTE: acf_merge indexing depends on these values */ |
|
| 865 |
+#define ACF_UNDEFINED 0 |
|
| 866 |
+#define ACF_SUCCEEDED 1 |
|
| 867 |
+#define ACF_DISABLED 2 |
|
| 868 |
+#define ACF_FAILED 3 |
|
| 869 |
+#endif |
|
| 870 |
+ |
|
| 871 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 872 |
+static inline unsigned int |
|
| 873 |
+man_def_auth_test (const struct key_state *ks) |
|
| 874 |
+{
|
|
| 875 |
+ if (management_enable_def_auth (management)) |
|
| 876 |
+ return ks->mda_status; |
|
| 877 |
+ else |
|
| 878 |
+ return ACF_DISABLED; |
|
| 879 |
+} |
|
| 880 |
+#endif |
|
| 881 |
+ |
|
| 882 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 863 | 883 |
|
| 864 | 884 |
/* |
| 865 | 885 |
* auth_control_file functions |
| ... | ... |
@@ -890,17 +910,12 @@ key_state_gen_auth_control_file (struct key_state *ks, const struct tls_options |
| 890 | 890 |
gc_free (&gc); |
| 891 | 891 |
} |
| 892 | 892 |
|
| 893 |
-/* key_state_test_auth_control_file return values */ |
|
| 894 |
-#define ACF_UNDEFINED 0 |
|
| 895 |
-#define ACF_SUCCEEDED 1 |
|
| 896 |
-#define ACF_DISABLED 2 |
|
| 897 |
-#define ACF_FAILED 3 |
|
| 898 |
-static int |
|
| 893 |
+static unsigned int |
|
| 899 | 894 |
key_state_test_auth_control_file (struct key_state *ks) |
| 900 | 895 |
{
|
| 901 | 896 |
if (ks && ks->auth_control_file) |
| 902 | 897 |
{
|
| 903 |
- int ret = ks->auth_control_status; |
|
| 898 |
+ unsigned int ret = ks->auth_control_status; |
|
| 904 | 899 |
if (ret == ACF_UNDEFINED) |
| 905 | 900 |
{
|
| 906 | 901 |
FILE *fp = fopen (ks->auth_control_file, "r"); |
| ... | ... |
@@ -935,14 +950,37 @@ tls_authentication_status (struct tls_multi *multi, const int latency) |
| 935 | 935 |
bool active = false; |
| 936 | 936 |
|
| 937 | 937 |
#ifdef ENABLE_DEF_AUTH |
| 938 |
- if (latency && multi->tas_last && multi->tas_last + latency >= now) |
|
| 939 |
- return TLS_AUTHENTICATION_UNDEFINED; |
|
| 940 |
- multi->tas_last = now; |
|
| 938 |
+ static const unsigned char acf_merge[] = |
|
| 939 |
+ {
|
|
| 940 |
+ ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_UNDEFINED */ |
|
| 941 |
+ ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_SUCCEEDED */ |
|
| 942 |
+ ACF_UNDEFINED, /* s1=ACF_UNDEFINED s2=ACF_DISABLED */ |
|
| 943 |
+ ACF_FAILED, /* s1=ACF_UNDEFINED s2=ACF_FAILED */ |
|
| 944 |
+ ACF_UNDEFINED, /* s1=ACF_SUCCEEDED s2=ACF_UNDEFINED */ |
|
| 945 |
+ ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_SUCCEEDED */ |
|
| 946 |
+ ACF_SUCCEEDED, /* s1=ACF_SUCCEEDED s2=ACF_DISABLED */ |
|
| 947 |
+ ACF_FAILED, /* s1=ACF_SUCCEEDED s2=ACF_FAILED */ |
|
| 948 |
+ ACF_UNDEFINED, /* s1=ACF_DISABLED s2=ACF_UNDEFINED */ |
|
| 949 |
+ ACF_SUCCEEDED, /* s1=ACF_DISABLED s2=ACF_SUCCEEDED */ |
|
| 950 |
+ ACF_DISABLED, /* s1=ACF_DISABLED s2=ACF_DISABLED */ |
|
| 951 |
+ ACF_FAILED, /* s1=ACF_DISABLED s2=ACF_FAILED */ |
|
| 952 |
+ ACF_FAILED, /* s1=ACF_FAILED s2=ACF_UNDEFINED */ |
|
| 953 |
+ ACF_FAILED, /* s1=ACF_FAILED s2=ACF_SUCCEEDED */ |
|
| 954 |
+ ACF_FAILED, /* s1=ACF_FAILED s2=ACF_DISABLED */ |
|
| 955 |
+ ACF_FAILED /* s1=ACF_FAILED s2=ACF_FAILED */ |
|
| 956 |
+ }; |
|
| 941 | 957 |
#endif |
| 942 | 958 |
|
| 943 | 959 |
if (multi) |
| 944 | 960 |
{
|
| 945 | 961 |
int i; |
| 962 |
+ |
|
| 963 |
+#ifdef ENABLE_DEF_AUTH |
|
| 964 |
+ if (latency && multi->tas_last && multi->tas_last + latency >= now) |
|
| 965 |
+ return TLS_AUTHENTICATION_UNDEFINED; |
|
| 966 |
+ multi->tas_last = now; |
|
| 967 |
+#endif |
|
| 968 |
+ |
|
| 946 | 969 |
for (i = 0; i < KEY_SCAN_SIZE; ++i) |
| 947 | 970 |
{
|
| 948 | 971 |
struct key_state *ks = multi->key_scan[i]; |
| ... | ... |
@@ -952,7 +990,16 @@ tls_authentication_status (struct tls_multi *multi, const int latency) |
| 952 | 952 |
if (ks->authenticated) |
| 953 | 953 |
{
|
| 954 | 954 |
#ifdef ENABLE_DEF_AUTH |
| 955 |
- switch (key_state_test_auth_control_file (ks)) |
|
| 955 |
+ unsigned int s1 = ACF_DISABLED; |
|
| 956 |
+ unsigned int s2 = ACF_DISABLED; |
|
| 957 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 958 |
+ s1 = key_state_test_auth_control_file (ks); |
|
| 959 |
+#endif |
|
| 960 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 961 |
+ s2 = man_def_auth_test (ks); |
|
| 962 |
+#endif |
|
| 963 |
+ ASSERT (s1 < 4 && s2 < 4); |
|
| 964 |
+ switch (acf_merge[(s1<<2) + s2]) |
|
| 956 | 965 |
{
|
| 957 | 966 |
case ACF_SUCCEEDED: |
| 958 | 967 |
case ACF_DISABLED: |
| ... | ... |
@@ -989,6 +1036,28 @@ tls_authentication_status (struct tls_multi *multi, const int latency) |
| 989 | 989 |
return TLS_AUTHENTICATION_FAILED; |
| 990 | 990 |
} |
| 991 | 991 |
|
| 992 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 993 |
+bool |
|
| 994 |
+tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth) |
|
| 995 |
+{
|
|
| 996 |
+ bool ret = false; |
|
| 997 |
+ if (multi) |
|
| 998 |
+ {
|
|
| 999 |
+ int i; |
|
| 1000 |
+ for (i = 0; i < KEY_SCAN_SIZE; ++i) |
|
| 1001 |
+ {
|
|
| 1002 |
+ struct key_state *ks = multi->key_scan[i]; |
|
| 1003 |
+ if (ks->mda_key_id == mda_key_id) |
|
| 1004 |
+ {
|
|
| 1005 |
+ ks->mda_status = auth ? ACF_SUCCEEDED : ACF_FAILED; |
|
| 1006 |
+ ret = true; |
|
| 1007 |
+ } |
|
| 1008 |
+ } |
|
| 1009 |
+ } |
|
| 1010 |
+ return ret; |
|
| 1011 |
+} |
|
| 1012 |
+#endif |
|
| 1013 |
+ |
|
| 992 | 1014 |
void |
| 993 | 1015 |
tls_deauthenticate (struct tls_multi *multi) |
| 994 | 1016 |
{
|
| ... | ... |
@@ -1458,7 +1527,7 @@ init_ssl (const struct options *options) |
| 1458 | 1458 |
#if P2MP_SERVER |
| 1459 | 1459 |
if (options->client_cert_not_required) |
| 1460 | 1460 |
{
|
| 1461 |
- msg (M_WARN, "WARNING: This configuration may accept clients which do not present a certificate"); |
|
| 1461 |
+ msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION --client-cert-not-required may accept clients which do not present a certificate"); |
|
| 1462 | 1462 |
} |
| 1463 | 1463 |
else |
| 1464 | 1464 |
#endif |
| ... | ... |
@@ -1976,6 +2045,10 @@ key_state_init (struct tls_session *session, struct key_state *ks) |
| 1976 | 1976 |
packet_id_init (&ks->packet_id, |
| 1977 | 1977 |
session->opt->replay_window, |
| 1978 | 1978 |
session->opt->replay_time); |
| 1979 |
+ |
|
| 1980 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 1981 |
+ ks->mda_key_id = session->opt->mda_context->mda_key_id_counter++; |
|
| 1982 |
+#endif |
|
| 1979 | 1983 |
} |
| 1980 | 1984 |
|
| 1981 | 1985 |
static void |
| ... | ... |
@@ -2018,7 +2091,7 @@ key_state_free (struct key_state *ks, bool clear) |
| 2018 | 2018 |
|
| 2019 | 2019 |
packet_id_free (&ks->packet_id); |
| 2020 | 2020 |
|
| 2021 |
-#ifdef ENABLE_DEF_AUTH |
|
| 2021 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 2022 | 2022 |
key_state_rm_auth_control_file (ks); |
| 2023 | 2023 |
#endif |
| 2024 | 2024 |
|
| ... | ... |
@@ -2933,7 +3006,7 @@ verify_user_pass_plugin (struct tls_session *session, const struct user_pass *up |
| 2933 | 2933 |
/* setenv client real IP address */ |
| 2934 | 2934 |
setenv_untrusted (session); |
| 2935 | 2935 |
|
| 2936 |
-#ifdef ENABLE_DEF_AUTH |
|
| 2936 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 2937 | 2937 |
/* generate filename for deferred auth control file */ |
| 2938 | 2938 |
key_state_gen_auth_control_file (ks, session->opt); |
| 2939 | 2939 |
#endif |
| ... | ... |
@@ -2941,7 +3014,7 @@ verify_user_pass_plugin (struct tls_session *session, const struct user_pass *up |
| 2941 | 2941 |
/* call command */ |
| 2942 | 2942 |
retval = plugin_call (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es); |
| 2943 | 2943 |
|
| 2944 |
-#ifdef ENABLE_DEF_AUTH |
|
| 2944 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 2945 | 2945 |
/* purge auth control filename (and file itself) for non-deferred returns */ |
| 2946 | 2946 |
if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED) |
| 2947 | 2947 |
key_state_rm_auth_control_file (ks); |
| ... | ... |
@@ -2952,13 +3025,57 @@ verify_user_pass_plugin (struct tls_session *session, const struct user_pass *up |
| 2952 | 2952 |
} |
| 2953 | 2953 |
else |
| 2954 | 2954 |
{
|
| 2955 |
- msg (D_TLS_ERRORS, "TLS Auth Error: peer provided a blank username"); |
|
| 2955 |
+ msg (D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_plugin): peer provided a blank username"); |
|
| 2956 | 2956 |
} |
| 2957 | 2957 |
|
| 2958 | 2958 |
return retval; |
| 2959 | 2959 |
} |
| 2960 | 2960 |
|
| 2961 | 2961 |
/* |
| 2962 |
+ * MANAGEMENT_DEF_AUTH internal ssl.c status codes |
|
| 2963 |
+ */ |
|
| 2964 |
+#define KMDA_ERROR 0 |
|
| 2965 |
+#define KMDA_SUCCESS 1 |
|
| 2966 |
+#define KMDA_UNDEF 2 |
|
| 2967 |
+#define KMDA_DEF 3 |
|
| 2968 |
+ |
|
| 2969 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 2970 |
+static int |
|
| 2971 |
+verify_user_pass_management (struct tls_session *session, const struct user_pass *up, const char *raw_username) |
|
| 2972 |
+{
|
|
| 2973 |
+ int retval = KMDA_ERROR; |
|
| 2974 |
+ |
|
| 2975 |
+ /* Is username defined? */ |
|
| 2976 |
+ if (strlen (up->username)) |
|
| 2977 |
+ {
|
|
| 2978 |
+ /* set username/password in private env space */ |
|
| 2979 |
+ setenv_str (session->opt->es, "username", raw_username); |
|
| 2980 |
+ setenv_str (session->opt->es, "password", up->password); |
|
| 2981 |
+ |
|
| 2982 |
+ /* setenv incoming cert common name for script */ |
|
| 2983 |
+ setenv_str (session->opt->es, "common_name", session->common_name); |
|
| 2984 |
+ |
|
| 2985 |
+ /* setenv client real IP address */ |
|
| 2986 |
+ setenv_untrusted (session); |
|
| 2987 |
+ |
|
| 2988 |
+ if (management) |
|
| 2989 |
+ management_notify_client_needing_auth (management, ks->mda_key_id, session->opt->mda_context, session->opt->es); |
|
| 2990 |
+ |
|
| 2991 |
+ setenv_del (session->opt->es, "password"); |
|
| 2992 |
+ setenv_str (session->opt->es, "username", up->username); |
|
| 2993 |
+ |
|
| 2994 |
+ retval = KMDA_SUCCESS; |
|
| 2995 |
+ } |
|
| 2996 |
+ else |
|
| 2997 |
+ {
|
|
| 2998 |
+ msg (D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_management): peer provided a blank username"); |
|
| 2999 |
+ } |
|
| 3000 |
+ |
|
| 3001 |
+ return retval; |
|
| 3002 |
+} |
|
| 3003 |
+#endif |
|
| 3004 |
+ |
|
| 3005 |
+/* |
|
| 2962 | 3006 |
* Handle the reading and writing of key data to and from |
| 2963 | 3007 |
* the TLS control channel (cleartext). |
| 2964 | 3008 |
*/ |
| ... | ... |
@@ -3134,6 +3251,13 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi |
| 3134 | 3134 |
char *options; |
| 3135 | 3135 |
struct user_pass *up; |
| 3136 | 3136 |
|
| 3137 |
+ bool man_def_auth = KMDA_UNDEF; |
|
| 3138 |
+ |
|
| 3139 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 3140 |
+ if (management_enable_def_auth (management)) |
|
| 3141 |
+ man_def_auth = KMDA_DEF; |
|
| 3142 |
+#endif |
|
| 3143 |
+ |
|
| 3137 | 3144 |
ASSERT (session->opt->key_method == 2); |
| 3138 | 3145 |
|
| 3139 | 3146 |
/* allocate temporary objects */ |
| ... | ... |
@@ -3169,7 +3293,8 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi |
| 3169 | 3169 |
/* should we check username/password? */ |
| 3170 | 3170 |
ks->authenticated = false; |
| 3171 | 3171 |
if (session->opt->auth_user_pass_verify_script |
| 3172 |
- || plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)) |
|
| 3172 |
+ || plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) |
|
| 3173 |
+ || man_def_auth == KMDA_DEF) |
|
| 3173 | 3174 |
{
|
| 3174 | 3175 |
int s1 = OPENVPN_PLUGIN_FUNC_SUCCESS; |
| 3175 | 3176 |
bool s2 = true; |
| ... | ... |
@@ -3195,6 +3320,10 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi |
| 3195 | 3195 |
string_mod (up->password, CC_PRINT, CC_CRLF, '_'); |
| 3196 | 3196 |
|
| 3197 | 3197 |
/* call plugin(s) and/or script */ |
| 3198 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 3199 |
+ if (man_def_auth == KMDA_DEF) |
|
| 3200 |
+ man_def_auth = verify_user_pass_management (session, up, raw_username); |
|
| 3201 |
+#endif |
|
| 3198 | 3202 |
if (plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)) |
| 3199 | 3203 |
s1 = verify_user_pass_plugin (session, up, raw_username); |
| 3200 | 3204 |
if (session->opt->auth_user_pass_verify_script) |
| ... | ... |
@@ -3202,16 +3331,21 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi |
| 3202 | 3202 |
|
| 3203 | 3203 |
/* auth succeeded? */ |
| 3204 | 3204 |
if ((s1 == OPENVPN_PLUGIN_FUNC_SUCCESS |
| 3205 |
-#ifdef ENABLE_DEF_AUTH |
|
| 3205 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 3206 | 3206 |
|| s1 == OPENVPN_PLUGIN_FUNC_DEFERRED |
| 3207 | 3207 |
#endif |
| 3208 |
- ) && s2) |
|
| 3208 |
+ ) && s2 && man_def_auth != KMDA_ERROR) |
|
| 3209 | 3209 |
{
|
| 3210 | 3210 |
ks->authenticated = true; |
| 3211 |
-#ifdef ENABLE_DEF_AUTH |
|
| 3211 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 3212 | 3212 |
if (s1 == OPENVPN_PLUGIN_FUNC_DEFERRED) |
| 3213 | 3213 |
ks->auth_deferred = true; |
| 3214 | 3214 |
#endif |
| 3215 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 3216 |
+ if (man_def_auth != KMDA_UNDEF) |
|
| 3217 |
+ ks->auth_deferred = true; |
|
| 3218 |
+#endif |
|
| 3219 |
+ |
|
| 3215 | 3220 |
if (session->opt->username_as_common_name) |
| 3216 | 3221 |
set_common_name (session, up->username); |
| 3217 | 3222 |
msg (D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", |
| ... | ... |
@@ -375,9 +375,15 @@ struct key_state |
| 375 | 375 |
#ifdef ENABLE_DEF_AUTH |
| 376 | 376 |
/* If auth_deferred is true, authentication is being deferred */ |
| 377 | 377 |
bool auth_deferred; |
| 378 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 379 |
+ unsigned int mda_key_id; |
|
| 380 |
+ unsigned int mda_status; |
|
| 381 |
+#endif |
|
| 382 |
+#ifdef PLUGIN_DEF_AUTH |
|
| 383 |
+ unsigned int auth_control_status; |
|
| 378 | 384 |
time_t acf_last_mod; |
| 379 | 385 |
char *auth_control_file; |
| 380 |
- int auth_control_status; |
|
| 386 |
+#endif |
|
| 381 | 387 |
#endif |
| 382 | 388 |
}; |
| 383 | 389 |
|
| ... | ... |
@@ -459,6 +465,10 @@ struct tls_options |
| 459 | 459 |
struct env_set *es; |
| 460 | 460 |
const struct plugin_list *plugins; |
| 461 | 461 |
|
| 462 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 463 |
+ struct man_def_auth_context *mda_context; |
|
| 464 |
+#endif |
|
| 465 |
+ |
|
| 462 | 466 |
/* --gremlin bits */ |
| 463 | 467 |
int gremlin; |
| 464 | 468 |
}; |
| ... | ... |
@@ -679,6 +689,10 @@ void tls_lock_common_name (struct tls_multi *multi); |
| 679 | 679 |
int tls_authentication_status (struct tls_multi *multi, const int latency); |
| 680 | 680 |
void tls_deauthenticate (struct tls_multi *multi); |
| 681 | 681 |
|
| 682 |
+#ifdef MANAGEMENT_DEF_AUTH |
|
| 683 |
+bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_id, const bool auth); |
|
| 684 |
+#endif |
|
| 685 |
+ |
|
| 682 | 686 |
/* |
| 683 | 687 |
* inline functions |
| 684 | 688 |
*/ |
| ... | ... |
@@ -471,20 +471,41 @@ socket_defined (const socket_descriptor_t sd) |
| 471 | 471 |
#endif |
| 472 | 472 |
|
| 473 | 473 |
/* |
| 474 |
- * Enable deferred authentication |
|
| 474 |
+ * Enable deferred authentication? |
|
| 475 | 475 |
*/ |
| 476 |
-#if defined(ENABLE_PLUGIN) && P2MP_SERVER |
|
| 476 |
+#define CONFIGURE_DEF_AUTH /* this should be set by autoconf and config.h */ |
|
| 477 |
+#if defined(CONFIGURE_DEF_AUTH) && defined(P2MP_SERVER) && defined(ENABLE_PLUGIN) |
|
| 478 |
+#define PLUGIN_DEF_AUTH |
|
| 479 |
+#endif |
|
| 480 |
+#if defined(CONFIGURE_DEF_AUTH) && defined(P2MP_SERVER) && defined(ENABLE_MANAGEMENT) |
|
| 481 |
+#define MANAGEMENT_DEF_AUTH |
|
| 482 |
+#endif |
|
| 483 |
+#if defined(PLUGIN_DEF_AUTH) || defined(MANAGEMENT_DEF_AUTH) |
|
| 477 | 484 |
#define ENABLE_DEF_AUTH |
| 478 | 485 |
#endif |
| 479 | 486 |
|
| 480 | 487 |
/* |
| 481 |
- * Enable packet filter |
|
| 488 |
+ * Enable packet filter? |
|
| 482 | 489 |
*/ |
| 483 |
-#if defined(ENABLE_PLUGIN) && P2MP_SERVER && defined(HAVE_STAT) |
|
| 490 |
+#define CONFIGURE_PF /* this should be set by autoconf and config.h */ |
|
| 491 |
+#if defined(CONFIGURE_PF) && defined(P2MP_SERVER) && defined(ENABLE_PLUGIN) && defined(HAVE_STAT) |
|
| 492 |
+#define PLUGIN_PF |
|
| 493 |
+#endif |
|
| 494 |
+#if defined(CONFIGURE_PF) && defined(P2MP_SERVER) && defined(MANAGEMENT_DEF_AUTH) |
|
| 495 |
+#define MANAGEMENT_PF |
|
| 496 |
+#endif |
|
| 497 |
+#if defined(PLUGIN_PF) || defined(MANAGEMENT_PF) |
|
| 484 | 498 |
#define ENABLE_PF |
| 485 | 499 |
#endif |
| 486 | 500 |
|
| 487 | 501 |
/* |
| 502 |
+ * Don't compile the struct buffer_list code unless something needs it |
|
| 503 |
+ */ |
|
| 504 |
+#if defined(ENABLE_MANAGEMENT) || defined(ENABLE_PF) |
|
| 505 |
+#define ENABLE_BUFFER_LIST |
|
| 506 |
+#endif |
|
| 507 |
+ |
|
| 508 |
+/* |
|
| 488 | 509 |
* Do we have pthread capability? |
| 489 | 510 |
*/ |
| 490 | 511 |
#ifdef USE_PTHREAD |
| ... | ... |
@@ -1248,7 +1248,7 @@ close_tun (struct tuntap *tt) |
| 1248 | 1248 |
#endif |
| 1249 | 1249 |
|
| 1250 | 1250 |
msg (M_INFO, "%s", command_line); |
| 1251 |
- system_check (command_line, NULL, S_FATAL, "Linux ip addr del failed"); |
|
| 1251 |
+ system_check (command_line, NULL, 0, "Linux ip addr del failed"); |
|
| 1252 | 1252 |
|
| 1253 | 1253 |
gc_free (&gc); |
| 1254 | 1254 |
} |