management /tmp/openvpn unix
Also added management-client-user and management-client-group
directives to control which processes are allowed to connect
to the socket.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3396 e7ae566f-a301-0410-adde-c780ea21d3b5
... | ... |
@@ -26,9 +26,17 @@ |
26 | 26 |
#define BASIC_H |
27 | 27 |
|
28 | 28 |
/* bool definitions */ |
29 |
+#ifndef bool |
|
29 | 30 |
#define bool int |
31 |
+#endif |
|
32 |
+ |
|
33 |
+#ifndef true |
|
30 | 34 |
#define true 1 |
35 |
+#endif |
|
36 |
+ |
|
37 |
+#ifndef false |
|
31 | 38 |
#define false 0 |
39 |
+#endif |
|
32 | 40 |
|
33 | 41 |
#define BOOL_CAST(x) ((x) ? (true) : (false)) |
34 | 42 |
|
... | ... |
@@ -339,7 +339,7 @@ AC_CHECK_HEADERS(fcntl.h stdlib.h dnl |
339 | 339 |
|
340 | 340 |
if test "${WIN32}" != "yes"; then |
341 | 341 |
AC_HEADER_SYS_WAIT |
342 |
- AC_CHECK_HEADERS(sys/time.h sys/socket.h sys/ioctl.h sys/stat.h dnl |
|
342 |
+ AC_CHECK_HEADERS(sys/time.h sys/socket.h sys/un.h sys/ioctl.h sys/stat.h dnl |
|
343 | 343 |
sys/mman.h fcntl.h sys/file.h stdlib.h stdint.h dnl |
344 | 344 |
stdarg.h unistd.h signal.h stdio.h string.h dnl |
345 | 345 |
strings.h ctype.h errno.h syslog.h pwd.h grp.h dnl |
... | ... |
@@ -464,7 +464,7 @@ AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl |
464 | 464 |
getpass strerror syslog openlog mlockall getgrnam setgid dnl |
465 | 465 |
setgroups stat flock readv writev time dnl |
466 | 466 |
setsid chdir putenv getpeername unlink dnl |
467 |
- chsize ftruncate execve) |
|
467 |
+ chsize ftruncate execve getpeereid umask) |
|
468 | 468 |
|
469 | 469 |
# Windows use stdcall for winsock so we cannot auto detect these |
470 | 470 |
m4_define([SOCKET_FUNCS], [socket recv recvfrom send sendto listen dnl |
... | ... |
@@ -64,6 +64,32 @@ |
64 | 64 |
obj:/lib/ld-2.5.so |
65 | 65 |
obj:/lib/ld-2.5.so |
66 | 66 |
obj:/lib/ld-2.5.so |
67 |
+ obj:/lib/ld-2.5.so |
|
68 |
+ obj:/lib/ld-2.5.so |
|
69 |
+ obj:/lib/ld-2.5.so |
|
70 |
+ obj:/lib/libc-2.5.so |
|
71 |
+ obj:/lib/ld-2.5.so |
|
72 |
+ fun:__libc_dlopen_mode |
|
73 |
+ fun:__nss_lookup_function |
|
74 |
+ obj:/lib/libc-2.5.so |
|
75 |
+ fun:getpwnam_r |
|
76 |
+ fun:getpwnam |
|
77 |
+ fun:get_user |
|
78 |
+ fun:management_open |
|
79 |
+ fun:open_management |
|
80 |
+ fun:main |
|
81 |
+} |
|
82 |
+ |
|
83 |
+{ |
|
84 |
+ <insert a suppression name here> |
|
85 |
+ Memcheck:Addr8 |
|
86 |
+ obj:/lib/ld-2.5.so |
|
87 |
+ obj:/lib/ld-2.5.so |
|
88 |
+ obj:/lib/ld-2.5.so |
|
89 |
+ obj:/lib/ld-2.5.so |
|
90 |
+ obj:/lib/ld-2.5.so |
|
91 |
+ obj:/lib/ld-2.5.so |
|
92 |
+ obj:/lib/ld-2.5.so |
|
67 | 93 |
obj:/lib/libc-2.5.so |
68 | 94 |
obj:/lib/ld-2.5.so |
69 | 95 |
fun:__libc_dlopen_mode |
... | ... |
@@ -177,6 +203,79 @@ |
177 | 177 |
|
178 | 178 |
{ |
179 | 179 |
<insert a suppression name here> |
180 |
+ Memcheck:Addr8 |
|
181 |
+ obj:/lib/ld-2.7.so |
|
182 |
+ obj:/lib/ld-2.7.so |
|
183 |
+ obj:/lib/ld-2.7.so |
|
184 |
+ obj:/lib/ld-2.7.so |
|
185 |
+ obj:/lib/ld-2.7.so |
|
186 |
+ obj:/lib/ld-2.7.so |
|
187 |
+ obj:/lib/ld-2.7.so |
|
188 |
+ obj:/lib/ld-2.7.so |
|
189 |
+ obj:/lib/ld-2.7.so |
|
190 |
+ obj:/lib/ld-2.7.so |
|
191 |
+ obj:/lib/libc-2.7.so |
|
192 |
+ obj:/lib/ld-2.7.so |
|
193 |
+ fun:__libc_dlopen_mode |
|
194 |
+ fun:__nss_lookup_function |
|
195 |
+ obj:/lib/libc-2.7.so |
|
196 |
+ fun:getpwnam_r |
|
197 |
+ fun:getpwnam |
|
198 |
+ fun:get_user |
|
199 |
+ fun:management_open |
|
200 |
+ fun:open_management |
|
201 |
+ fun:main |
|
202 |
+} |
|
203 |
+ |
|
204 |
+{ |
|
205 |
+ <insert a suppression name here> |
|
206 |
+ Memcheck:Cond |
|
207 |
+ fun:BN_div |
|
208 |
+ fun:BN_MONT_CTX_set |
|
209 |
+ fun:BN_MONT_CTX_set_locked |
|
210 |
+ obj:/usr/lib/libcrypto.so.0.9.8 |
|
211 |
+ fun:ssl3_ctx_ctrl |
|
212 |
+ fun:init_ssl |
|
213 |
+ fun:init_instance |
|
214 |
+ fun:init_instance_handle_signals |
|
215 |
+ fun:tunnel_server_udp |
|
216 |
+ fun:main |
|
217 |
+} |
|
218 |
+ |
|
219 |
+{ |
|
220 |
+ <insert a suppression name here> |
|
221 |
+ Memcheck:Cond |
|
222 |
+ fun:BN_div |
|
223 |
+ fun:BN_nnmod |
|
224 |
+ fun:BN_mod_inverse |
|
225 |
+ fun:BN_MONT_CTX_set |
|
226 |
+ fun:BN_MONT_CTX_set_locked |
|
227 |
+ obj:/usr/lib/libcrypto.so.0.9.8 |
|
228 |
+ fun:ssl3_ctx_ctrl |
|
229 |
+ fun:init_ssl |
|
230 |
+ fun:init_instance |
|
231 |
+ fun:init_instance_handle_signals |
|
232 |
+ fun:tunnel_server_udp |
|
233 |
+ fun:main |
|
234 |
+} |
|
235 |
+ |
|
236 |
+{ |
|
237 |
+ <insert a suppression name here> |
|
238 |
+ Memcheck:Cond |
|
239 |
+ fun:BN_mod_inverse |
|
240 |
+ fun:BN_MONT_CTX_set |
|
241 |
+ fun:BN_MONT_CTX_set_locked |
|
242 |
+ obj:/usr/lib/libcrypto.so.0.9.8 |
|
243 |
+ fun:ssl3_ctx_ctrl |
|
244 |
+ fun:init_ssl |
|
245 |
+ fun:init_instance |
|
246 |
+ fun:init_instance_handle_signals |
|
247 |
+ fun:tunnel_server_udp |
|
248 |
+ fun:main |
|
249 |
+} |
|
250 |
+ |
|
251 |
+{ |
|
252 |
+ <insert a suppression name here> |
|
180 | 253 |
Memcheck:Cond |
181 | 254 |
obj:/lib/ld-2.5.so |
182 | 255 |
obj:/lib/ld-2.5.so |
... | ... |
@@ -428,6 +527,26 @@ |
428 | 428 |
obj:/lib/ld-2.5.so |
429 | 429 |
obj:/lib/ld-2.5.so |
430 | 430 |
obj:/lib/libc-2.5.so |
431 |
+ obj:/lib/ld-2.5.so |
|
432 |
+ fun:__libc_dlopen_mode |
|
433 |
+ fun:__nss_lookup_function |
|
434 |
+ obj:/lib/libc-2.5.so |
|
435 |
+ fun:getpwnam_r |
|
436 |
+ fun:getpwnam |
|
437 |
+ fun:get_user |
|
438 |
+ fun:management_open |
|
439 |
+ fun:open_management |
|
440 |
+ fun:main |
|
441 |
+} |
|
442 |
+ |
|
443 |
+{ |
|
444 |
+ <insert a suppression name here> |
|
445 |
+ Memcheck:Cond |
|
446 |
+ obj:/lib/ld-2.5.so |
|
447 |
+ obj:/lib/ld-2.5.so |
|
448 |
+ obj:/lib/ld-2.5.so |
|
449 |
+ obj:/lib/ld-2.5.so |
|
450 |
+ obj:/lib/libc-2.5.so |
|
431 | 451 |
obj:/lib/libdl-2.5.so |
432 | 452 |
obj:/lib/ld-2.5.so |
433 | 453 |
obj:/lib/libdl-2.5.so |
... | ... |
@@ -522,6 +641,21 @@ |
522 | 522 |
<insert a suppression name here> |
523 | 523 |
Memcheck:Leak |
524 | 524 |
fun:malloc |
525 |
+ fun:__nss_lookup_function |
|
526 |
+ obj:* |
|
527 |
+ obj:* |
|
528 |
+ fun:getpwnam_r |
|
529 |
+ fun:getpwnam |
|
530 |
+ fun:get_user |
|
531 |
+ fun:management_open |
|
532 |
+ fun:open_management |
|
533 |
+ fun:main |
|
534 |
+} |
|
535 |
+ |
|
536 |
+{ |
|
537 |
+ <insert a suppression name here> |
|
538 |
+ Memcheck:Leak |
|
539 |
+ fun:malloc |
|
525 | 540 |
fun:getdelim |
526 | 541 |
fun:getpass |
527 | 542 |
fun:get_console_input |
... | ... |
@@ -587,6 +721,22 @@ |
587 | 587 |
<insert a suppression name here> |
588 | 588 |
Memcheck:Leak |
589 | 589 |
fun:malloc |
590 |
+ fun:tsearch |
|
591 |
+ fun:__nss_lookup_function |
|
592 |
+ obj:* |
|
593 |
+ obj:* |
|
594 |
+ fun:getpwnam_r |
|
595 |
+ fun:getpwnam |
|
596 |
+ fun:get_user |
|
597 |
+ fun:management_open |
|
598 |
+ fun:open_management |
|
599 |
+ fun:main |
|
600 |
+} |
|
601 |
+ |
|
602 |
+{ |
|
603 |
+ <insert a suppression name here> |
|
604 |
+ Memcheck:Leak |
|
605 |
+ fun:malloc |
|
590 | 606 |
obj:/lib/libc-2.5.so |
591 | 607 |
fun:__nss_database_lookup |
592 | 608 |
obj:* |
... | ... |
@@ -636,3 +786,122 @@ |
636 | 636 |
fun:main |
637 | 637 |
} |
638 | 638 |
|
639 |
+{ |
|
640 |
+ <insert a suppression name here> |
|
641 |
+ Memcheck:Leak |
|
642 |
+ fun:malloc |
|
643 |
+ obj:/lib/libc-2.5.so |
|
644 |
+ fun:__nss_database_lookup |
|
645 |
+ obj:* |
|
646 |
+ obj:* |
|
647 |
+ fun:getpwnam_r |
|
648 |
+ fun:getpwnam |
|
649 |
+ fun:get_user |
|
650 |
+ fun:management_open |
|
651 |
+ fun:open_management |
|
652 |
+ fun:main |
|
653 |
+} |
|
654 |
+ |
|
655 |
+{ |
|
656 |
+ <insert a suppression name here> |
|
657 |
+ Memcheck:Leak |
|
658 |
+ fun:malloc |
|
659 |
+ obj:/lib/libc-2.7.so |
|
660 |
+ fun:__nss_database_lookup |
|
661 |
+ obj:* |
|
662 |
+ obj:* |
|
663 |
+ fun:getpwnam_r |
|
664 |
+ fun:getpwnam |
|
665 |
+ fun:get_user |
|
666 |
+ fun:management_open |
|
667 |
+ fun:open_management |
|
668 |
+ fun:main |
|
669 |
+} |
|
670 |
+ |
|
671 |
+{ |
|
672 |
+ <insert a suppression name here> |
|
673 |
+ Memcheck:Addr8 |
|
674 |
+ obj:/lib/ld-2.7.so |
|
675 |
+ obj:/lib/ld-2.7.so |
|
676 |
+ obj:/lib/ld-2.7.so |
|
677 |
+ obj:/lib/ld-2.7.so |
|
678 |
+ obj:/lib/ld-2.7.so |
|
679 |
+ obj:/lib/ld-2.7.so |
|
680 |
+ obj:/lib/ld-2.7.so |
|
681 |
+ obj:/lib/ld-2.7.so |
|
682 |
+ obj:/lib/ld-2.7.so |
|
683 |
+ obj:/lib/ld-2.7.so |
|
684 |
+ obj:/lib/libc-2.7.so |
|
685 |
+ obj:/lib/ld-2.7.so |
|
686 |
+ fun:__libc_dlopen_mode |
|
687 |
+ fun:__nss_lookup_function |
|
688 |
+ obj:/lib/libc-2.7.so |
|
689 |
+ fun:getgrnam_r |
|
690 |
+ fun:getgrnam |
|
691 |
+ fun:get_group |
|
692 |
+ fun:do_init_first_time |
|
693 |
+ fun:init_instance |
|
694 |
+ fun:init_instance_handle_signals |
|
695 |
+ fun:tunnel_server_udp |
|
696 |
+ fun:main |
|
697 |
+} |
|
698 |
+ |
|
699 |
+{ |
|
700 |
+ <insert a suppression name here> |
|
701 |
+ Memcheck:Leak |
|
702 |
+ fun:malloc |
|
703 |
+ obj:/lib/libc-2.7.so |
|
704 |
+ fun:__nss_database_lookup |
|
705 |
+ obj:* |
|
706 |
+ obj:* |
|
707 |
+ fun:getgrnam_r |
|
708 |
+ fun:getgrnam |
|
709 |
+ fun:get_group |
|
710 |
+ fun:do_init_first_time |
|
711 |
+ fun:init_instance |
|
712 |
+ fun:init_instance_handle_signals |
|
713 |
+ fun:tunnel_server_udp |
|
714 |
+ fun:main |
|
715 |
+} |
|
716 |
+ |
|
717 |
+{ |
|
718 |
+ <insert a suppression name here> |
|
719 |
+ Memcheck:Addr8 |
|
720 |
+ obj:/lib/ld-2.7.so |
|
721 |
+ obj:/lib/ld-2.7.so |
|
722 |
+ obj:/lib/ld-2.7.so |
|
723 |
+ obj:/lib/ld-2.7.so |
|
724 |
+ obj:/lib/ld-2.7.so |
|
725 |
+ obj:/lib/ld-2.7.so |
|
726 |
+ obj:/lib/ld-2.7.so |
|
727 |
+ obj:/lib/ld-2.7.so |
|
728 |
+ obj:/lib/ld-2.7.so |
|
729 |
+ obj:/lib/ld-2.7.so |
|
730 |
+ obj:/lib/libc-2.7.so |
|
731 |
+ obj:/lib/ld-2.7.so |
|
732 |
+ fun:__libc_dlopen_mode |
|
733 |
+ fun:__nss_lookup_function |
|
734 |
+ obj:/lib/libc-2.7.so |
|
735 |
+ fun:getgrnam_r |
|
736 |
+ fun:getgrnam |
|
737 |
+ fun:get_group |
|
738 |
+ fun:management_open |
|
739 |
+ fun:open_management |
|
740 |
+ fun:main |
|
741 |
+} |
|
742 |
+ |
|
743 |
+{ |
|
744 |
+ <insert a suppression name here> |
|
745 |
+ Memcheck:Leak |
|
746 |
+ fun:malloc |
|
747 |
+ fun:tsearch |
|
748 |
+ fun:__nss_lookup_function |
|
749 |
+ obj:* |
|
750 |
+ obj:* |
|
751 |
+ fun:getgrnam_r |
|
752 |
+ fun:getgrnam |
|
753 |
+ fun:get_group |
|
754 |
+ fun:management_open |
|
755 |
+ fun:open_management |
|
756 |
+ fun:main |
|
757 |
+} |
... | ... |
@@ -1290,11 +1290,11 @@ io_wait_dowork (struct context *c, const unsigned int flags) |
1290 | 1290 |
struct event_set_return esr[4]; |
1291 | 1291 |
|
1292 | 1292 |
/* These shifts all depend on EVENT_READ and EVENT_WRITE */ |
1293 |
- static const int socket_shift = 0; /* depends on SOCKET_READ and SOCKET_WRITE */ |
|
1294 |
- static const int tun_shift = 2; /* depends on TUN_READ and TUN_WRITE */ |
|
1295 |
- static const int err_shift = 4; /* depends on ES_ERROR */ |
|
1293 |
+ static int socket_shift = 0; /* depends on SOCKET_READ and SOCKET_WRITE */ |
|
1294 |
+ static int tun_shift = 2; /* depends on TUN_READ and TUN_WRITE */ |
|
1295 |
+ static int err_shift = 4; /* depends on ES_ERROR */ |
|
1296 | 1296 |
#ifdef ENABLE_MANAGEMENT |
1297 |
- static const int management_shift = 6; /* depends on MANAGEMENT_READ and MANAGEMENT_WRITE */ |
|
1297 |
+ static int management_shift = 6; /* depends on MANAGEMENT_READ and MANAGEMENT_WRITE */ |
|
1298 | 1298 |
#endif |
1299 | 1299 |
|
1300 | 1300 |
/* |
... | ... |
@@ -2670,6 +2670,8 @@ open_management (struct context *c) |
2670 | 2670 |
c->options.management_addr, |
2671 | 2671 |
c->options.management_port, |
2672 | 2672 |
c->options.management_user_pass, |
2673 |
+ c->options.management_client_user, |
|
2674 |
+ c->options.management_client_group, |
|
2673 | 2675 |
c->options.management_log_history_cache, |
2674 | 2676 |
c->options.management_echo_buffer_size, |
2675 | 2677 |
c->options.management_state_buffer_size, |
... | ... |
@@ -226,6 +226,15 @@ man_prompt (struct management *man) |
226 | 226 |
} |
227 | 227 |
|
228 | 228 |
static void |
229 |
+man_delete_unix_socket (struct management *man) |
|
230 |
+{ |
|
231 |
+#if UNIX_SOCK_SUPPORT |
|
232 |
+ if (man->settings.flags & MF_LISTEN_UNIX) |
|
233 |
+ socket_delete_unix (&man->settings.local_unix); |
|
234 |
+#endif |
|
235 |
+} |
|
236 |
+ |
|
237 |
+static void |
|
229 | 238 |
man_close_socket (struct management *man, const socket_descriptor_t sd) |
230 | 239 |
{ |
231 | 240 |
#ifndef WIN32 |
... | ... |
@@ -1231,9 +1240,18 @@ man_new_connection_post (struct management *man, const char *description) |
1231 | 1231 |
man_start_ne32 (man); |
1232 | 1232 |
#endif |
1233 | 1233 |
|
1234 |
- msg (D_MANAGEMENT, "MANAGEMENT: %s %s", |
|
1235 |
- description, |
|
1236 |
- print_sockaddr (&man->settings.local, &gc)); |
|
1234 |
+#if UNIX_SOCK_SUPPORT |
|
1235 |
+ if (man->settings.flags & MF_LISTEN_UNIX) |
|
1236 |
+ { |
|
1237 |
+ msg (D_MANAGEMENT, "MANAGEMENT: %s %s", |
|
1238 |
+ description, |
|
1239 |
+ sockaddr_unix_name (&man->settings.local_unix, "NULL")); |
|
1240 |
+ } |
|
1241 |
+ else |
|
1242 |
+#endif |
|
1243 |
+ msg (D_MANAGEMENT, "MANAGEMENT: %s %s", |
|
1244 |
+ description, |
|
1245 |
+ print_sockaddr (&man->settings.local, &gc)); |
|
1237 | 1246 |
|
1238 | 1247 |
buffer_list_reset (man->connection.out); |
1239 | 1248 |
|
... | ... |
@@ -1249,11 +1267,46 @@ static void |
1249 | 1249 |
man_accept (struct management *man) |
1250 | 1250 |
{ |
1251 | 1251 |
struct link_socket_actual act; |
1252 |
+ CLEAR (act); |
|
1252 | 1253 |
|
1253 | 1254 |
/* |
1254 |
- * Accept the TCP client. |
|
1255 |
+ * Accept the TCP or Unix domain socket client. |
|
1255 | 1256 |
*/ |
1256 |
- man->connection.sd_cli = socket_do_accept (man->connection.sd_top, &act, false); |
|
1257 |
+#if UNIX_SOCK_SUPPORT |
|
1258 |
+ if (man->settings.flags & MF_LISTEN_UNIX) |
|
1259 |
+ { |
|
1260 |
+ struct sockaddr_un remote; |
|
1261 |
+ man->connection.sd_cli = socket_accept_unix (man->connection.sd_top, &remote); |
|
1262 |
+ if (socket_defined (man->connection.sd_cli) && (man->settings.client_uid != -1 || man->settings.client_gid != -1)) |
|
1263 |
+ { |
|
1264 |
+ static const char err_prefix[] = "MANAGEMENT: unix domain socket client connection rejected --"; |
|
1265 |
+ int uid, gid; |
|
1266 |
+ if (unix_socket_get_peer_uid_gid (man->connection.sd_cli, &uid, &gid)) |
|
1267 |
+ { |
|
1268 |
+ if (man->settings.client_uid != -1 && man->settings.client_uid != uid) |
|
1269 |
+ { |
|
1270 |
+ msg (D_MANAGEMENT, "%s UID of socket peer (%d) doesn't match required value (%d) as given by --management-client-user", |
|
1271 |
+ err_prefix, uid, man->settings.client_uid); |
|
1272 |
+ sd_close (&man->connection.sd_cli); |
|
1273 |
+ } |
|
1274 |
+ if (man->settings.client_gid != -1 && man->settings.client_gid != gid) |
|
1275 |
+ { |
|
1276 |
+ msg (D_MANAGEMENT, "%s GID of socket peer (%d) doesn't match required value (%d) as given by --management-client-group", |
|
1277 |
+ err_prefix, gid, man->settings.client_gid); |
|
1278 |
+ sd_close (&man->connection.sd_cli); |
|
1279 |
+ } |
|
1280 |
+ } |
|
1281 |
+ else |
|
1282 |
+ { |
|
1283 |
+ msg (D_MANAGEMENT, "%s cannot get UID/GID of socket peer", err_prefix); |
|
1284 |
+ sd_close (&man->connection.sd_cli); |
|
1285 |
+ } |
|
1286 |
+ } |
|
1287 |
+ } |
|
1288 |
+ else |
|
1289 |
+#endif |
|
1290 |
+ man->connection.sd_cli = socket_do_accept (man->connection.sd_top, &act, false); |
|
1291 |
+ |
|
1257 | 1292 |
if (socket_defined (man->connection.sd_cli)) |
1258 | 1293 |
{ |
1259 | 1294 |
man->connection.remote = act.dest; |
... | ... |
@@ -1285,12 +1338,19 @@ man_listen (struct management *man) |
1285 | 1285 |
*/ |
1286 | 1286 |
if (man->connection.sd_top == SOCKET_UNDEFINED) |
1287 | 1287 |
{ |
1288 |
- man->connection.sd_top = create_socket_tcp (); |
|
1289 |
- |
|
1290 |
- /* |
|
1291 |
- * Bind socket |
|
1292 |
- */ |
|
1293 |
- socket_bind (man->connection.sd_top, &man->settings.local, "MANAGEMENT"); |
|
1288 |
+#if UNIX_SOCK_SUPPORT |
|
1289 |
+ if (man->settings.flags & MF_LISTEN_UNIX) |
|
1290 |
+ { |
|
1291 |
+ man_delete_unix_socket (man); |
|
1292 |
+ man->connection.sd_top = create_socket_unix (); |
|
1293 |
+ socket_bind_unix (man->connection.sd_top, &man->settings.local_unix, "MANAGEMENT"); |
|
1294 |
+ } |
|
1295 |
+ else |
|
1296 |
+#endif |
|
1297 |
+ { |
|
1298 |
+ man->connection.sd_top = create_socket_tcp (); |
|
1299 |
+ socket_bind (man->connection.sd_top, &man->settings.local, "MANAGEMENT"); |
|
1300 |
+ } |
|
1294 | 1301 |
|
1295 | 1302 |
/* |
1296 | 1303 |
* Listen for connection |
... | ... |
@@ -1304,8 +1364,16 @@ man_listen (struct management *man) |
1304 | 1304 |
set_nonblock (man->connection.sd_top); |
1305 | 1305 |
set_cloexec (man->connection.sd_top); |
1306 | 1306 |
|
1307 |
- msg (D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s", |
|
1308 |
- print_sockaddr (&man->settings.local, &gc)); |
|
1307 |
+#if UNIX_SOCK_SUPPORT |
|
1308 |
+ if (man->settings.flags & MF_LISTEN_UNIX) |
|
1309 |
+ { |
|
1310 |
+ msg (D_MANAGEMENT, "MANAGEMENT: unix domain socket listening on %s", |
|
1311 |
+ sockaddr_unix_name (&man->settings.local_unix, "NULL")); |
|
1312 |
+ } |
|
1313 |
+ else |
|
1314 |
+#endif |
|
1315 |
+ msg (D_MANAGEMENT, "MANAGEMENT: TCP Socket listening on %s", |
|
1316 |
+ print_sockaddr (&man->settings.local, &gc)); |
|
1309 | 1317 |
} |
1310 | 1318 |
|
1311 | 1319 |
#ifdef WIN32 |
... | ... |
@@ -1645,6 +1713,8 @@ man_settings_init (struct man_settings *ms, |
1645 | 1645 |
const char *addr, |
1646 | 1646 |
const int port, |
1647 | 1647 |
const char *pass_file, |
1648 |
+ const char *client_user, |
|
1649 |
+ const char *client_group, |
|
1648 | 1650 |
const int log_history_cache, |
1649 | 1651 |
const int echo_buffer_size, |
1650 | 1652 |
const int state_buffer_size, |
... | ... |
@@ -1657,6 +1727,8 @@ man_settings_init (struct man_settings *ms, |
1657 | 1657 |
CLEAR (*ms); |
1658 | 1658 |
|
1659 | 1659 |
ms->flags = flags; |
1660 |
+ ms->client_uid = -1; |
|
1661 |
+ ms->client_gid = -1; |
|
1660 | 1662 |
|
1661 | 1663 |
/* |
1662 | 1664 |
* Get username/password |
... | ... |
@@ -1664,27 +1736,54 @@ man_settings_init (struct man_settings *ms, |
1664 | 1664 |
if (pass_file) |
1665 | 1665 |
get_user_pass (&ms->up, pass_file, "Management", GET_USER_PASS_PASSWORD_ONLY); |
1666 | 1666 |
|
1667 |
- ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL); |
|
1668 |
- |
|
1669 |
- /* |
|
1670 |
- * Initialize socket address |
|
1671 |
- */ |
|
1672 |
- ms->local.sa.sin_family = AF_INET; |
|
1673 |
- ms->local.sa.sin_addr.s_addr = 0; |
|
1674 |
- ms->local.sa.sin_port = htons (port); |
|
1675 |
- |
|
1676 | 1667 |
/* |
1677 |
- * Run management over tunnel, or |
|
1678 |
- * separate channel? |
|
1668 |
+ * lookup client UID/GID if specified |
|
1679 | 1669 |
*/ |
1680 |
- if (streq (addr, "tunnel") && !(flags & MF_CONNECT_AS_CLIENT)) |
|
1670 |
+ if (client_user) |
|
1671 |
+ { |
|
1672 |
+ struct user_state s; |
|
1673 |
+ get_user (client_user, &s); |
|
1674 |
+ ms->client_uid = user_state_uid (&s); |
|
1675 |
+ msg (D_MANAGEMENT, "MANAGEMENT: client_uid=%d", ms->client_uid); |
|
1676 |
+ ASSERT (ms->client_uid >= 0); |
|
1677 |
+ } |
|
1678 |
+ if (client_group) |
|
1681 | 1679 |
{ |
1682 |
- ms->management_over_tunnel = true; |
|
1680 |
+ struct group_state s; |
|
1681 |
+ get_group (client_group, &s); |
|
1682 |
+ ms->client_gid = group_state_gid (&s); |
|
1683 |
+ msg (D_MANAGEMENT, "MANAGEMENT: client_gid=%d", ms->client_gid); |
|
1684 |
+ ASSERT (ms->client_gid >= 0); |
|
1683 | 1685 |
} |
1686 |
+ |
|
1687 |
+ ms->write_peer_info_file = string_alloc (write_peer_info_file, NULL); |
|
1688 |
+ |
|
1689 |
+#if UNIX_SOCK_SUPPORT |
|
1690 |
+ if (ms->flags & MF_LISTEN_UNIX) |
|
1691 |
+ sockaddr_unix_init (&ms->local_unix, addr); |
|
1684 | 1692 |
else |
1693 |
+#endif |
|
1685 | 1694 |
{ |
1686 |
- ms->local.sa.sin_addr.s_addr = getaddr |
|
1687 |
- (GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL); |
|
1695 |
+ /* |
|
1696 |
+ * Initialize socket address |
|
1697 |
+ */ |
|
1698 |
+ ms->local.sa.sin_family = AF_INET; |
|
1699 |
+ ms->local.sa.sin_addr.s_addr = 0; |
|
1700 |
+ ms->local.sa.sin_port = htons (port); |
|
1701 |
+ |
|
1702 |
+ /* |
|
1703 |
+ * Run management over tunnel, or |
|
1704 |
+ * separate channel? |
|
1705 |
+ */ |
|
1706 |
+ if (streq (addr, "tunnel") && !(flags & MF_CONNECT_AS_CLIENT)) |
|
1707 |
+ { |
|
1708 |
+ ms->management_over_tunnel = true; |
|
1709 |
+ } |
|
1710 |
+ else |
|
1711 |
+ { |
|
1712 |
+ ms->local.sa.sin_addr.s_addr = getaddr |
|
1713 |
+ (GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL); |
|
1714 |
+ } |
|
1688 | 1715 |
} |
1689 | 1716 |
|
1690 | 1717 |
/* |
... | ... |
@@ -1764,7 +1863,10 @@ man_connection_close (struct management *man) |
1764 | 1764 |
net_event_win32_close (&mc->ne32); |
1765 | 1765 |
#endif |
1766 | 1766 |
if (socket_defined (mc->sd_top)) |
1767 |
- man_close_socket (man, mc->sd_top); |
|
1767 |
+ { |
|
1768 |
+ man_close_socket (man, mc->sd_top); |
|
1769 |
+ man_delete_unix_socket (man); |
|
1770 |
+ } |
|
1768 | 1771 |
if (socket_defined (mc->sd_cli)) |
1769 | 1772 |
man_close_socket (man, mc->sd_cli); |
1770 | 1773 |
if (mc->in) |
... | ... |
@@ -1798,6 +1900,8 @@ management_open (struct management *man, |
1798 | 1798 |
const char *addr, |
1799 | 1799 |
const int port, |
1800 | 1800 |
const char *pass_file, |
1801 |
+ const char *client_user, |
|
1802 |
+ const char *client_group, |
|
1801 | 1803 |
const int log_history_cache, |
1802 | 1804 |
const int echo_buffer_size, |
1803 | 1805 |
const int state_buffer_size, |
... | ... |
@@ -1815,6 +1919,8 @@ management_open (struct management *man, |
1815 | 1815 |
addr, |
1816 | 1816 |
port, |
1817 | 1817 |
pass_file, |
1818 |
+ client_user, |
|
1819 |
+ client_group, |
|
1818 | 1820 |
log_history_cache, |
1819 | 1821 |
echo_buffer_size, |
1820 | 1822 |
state_buffer_size, |
... | ... |
@@ -202,12 +202,17 @@ struct man_settings { |
202 | 202 |
bool defined; |
203 | 203 |
unsigned int flags; /* MF_x flags */ |
204 | 204 |
struct openvpn_sockaddr local; |
205 |
+#if UNIX_SOCK_SUPPORT |
|
206 |
+ struct sockaddr_un local_unix; |
|
207 |
+#endif |
|
205 | 208 |
bool management_over_tunnel; |
206 | 209 |
struct user_pass up; |
207 | 210 |
int log_history_cache; |
208 | 211 |
int echo_buffer_size; |
209 | 212 |
int state_buffer_size; |
210 | 213 |
char *write_peer_info_file; |
214 |
+ int client_uid; |
|
215 |
+ int client_gid; |
|
211 | 216 |
|
212 | 217 |
/* flags for handling the management interface "signal" command */ |
213 | 218 |
# define MANSIG_IGNORE_USR1_HUP (1<<0) |
... | ... |
@@ -295,10 +300,14 @@ struct management *management_init (void); |
295 | 295 |
#ifdef MANAGEMENT_PF |
296 | 296 |
# define MF_CLIENT_PF (1<<7) |
297 | 297 |
#endif |
298 |
+# define MF_LISTEN_UNIX (1<<8) |
|
299 |
+ |
|
298 | 300 |
bool management_open (struct management *man, |
299 | 301 |
const char *addr, |
300 | 302 |
const int port, |
301 | 303 |
const char *pass_file, |
304 |
+ const char *client_user, |
|
305 |
+ const char *client_group, |
|
302 | 306 |
const int log_history_cache, |
303 | 307 |
const int echo_buffer_size, |
304 | 308 |
const int state_buffer_size, |
... | ... |
@@ -82,7 +82,7 @@ get_user (const char *username, struct user_state *state) |
82 | 82 |
state->username = username; |
83 | 83 |
ret = true; |
84 | 84 |
#else |
85 |
- msg (M_FATAL, "Sorry but I can't setuid to '%s' because this operating system doesn't appear to support the getpwname() or setuid() system calls", username); |
|
85 |
+ msg (M_FATAL, "cannot get UID for user %s -- platform lacks getpwname() or setuid() system calls", username); |
|
86 | 86 |
#endif |
87 | 87 |
} |
88 | 88 |
return ret; |
... | ... |
@@ -117,7 +117,7 @@ get_group (const char *groupname, struct group_state *state) |
117 | 117 |
state->groupname = groupname; |
118 | 118 |
ret = true; |
119 | 119 |
#else |
120 |
- msg (M_FATAL, "Sorry but I can't setgid to '%s' because this operating system doesn't appear to support the getgrnam() or setgid() system calls", groupname); |
|
120 |
+ msg (M_FATAL, "cannot get GID for group %s -- platform lacks getgrnam() or setgid() system calls", groupname); |
|
121 | 121 |
#endif |
122 | 122 |
} |
123 | 123 |
return ret; |
... | ... |
@@ -119,7 +119,7 @@ void warn_if_group_others_accessible(const char* filename); |
119 | 119 |
|
120 | 120 |
/* interpret the status code returned by system()/execve() */ |
121 | 121 |
bool system_ok(int); |
122 |
-int system_executed (int stat); |
|
122 |
+bool system_executed (int stat); |
|
123 | 123 |
const char *system_error_message (int, struct gc_arena *gc); |
124 | 124 |
|
125 | 125 |
/* wrapper around the execve() call */ |
... | ... |
@@ -330,4 +330,28 @@ void argv_printf_cat (struct argv *a, const char *format, ...) |
330 | 330 |
#endif |
331 | 331 |
; |
332 | 332 |
|
333 |
+/* |
|
334 |
+ * Extract UID or GID |
|
335 |
+ */ |
|
336 |
+ |
|
337 |
+static inline int |
|
338 |
+user_state_uid (const struct user_state *s) |
|
339 |
+{ |
|
340 |
+#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID) |
|
341 |
+ if (s->pw) |
|
342 |
+ return s->pw->pw_uid; |
|
343 |
+#endif |
|
344 |
+ return -1; |
|
345 |
+} |
|
346 |
+ |
|
347 |
+static inline int |
|
348 |
+group_state_gid (const struct group_state *s) |
|
349 |
+{ |
|
350 |
+#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID) |
|
351 |
+ if (s->gr) |
|
352 |
+ return s->gr->gr_gid; |
|
353 |
+#endif |
|
354 |
+ return -1; |
|
355 |
+} |
|
356 |
+ |
|
333 | 357 |
#endif |
... | ... |
@@ -181,7 +181,9 @@ openvpn \- secure IP tunnel daemon. |
181 | 181 |
[\ \fB\-\-suppress-timestamps\fR\ ] |
182 | 182 |
[\ \fB\-\-lport\fR\ \fIport\fR\ ] |
183 | 183 |
[\ \fB\-\-management\-client\-auth\fR\ ] |
184 |
+[\ \fB\-\-management\-client\-group\fR\ \fIg\fR\ ] |
|
184 | 185 |
[\ \fB\-\-management\-client\-pf\fR\ ] |
186 |
+[\ \fB\-\-management\-client\-user\fR\ \fIu\fR\ ] |
|
185 | 187 |
[\ \fB\-\-management\-forget\-disconnect\fR\ ] |
186 | 188 |
[\ \fB\-\-management\-hold\fR\ ] |
187 | 189 |
[\ \fB\-\-management\-log\-cache\fR\ \fIn\fR\ ] |
... | ... |
@@ -2455,6 +2457,19 @@ or "stdin" to prompt from standard input. The password |
2455 | 2455 |
provided will set the password which TCP clients will need |
2456 | 2456 |
to provide in order to access management functions. |
2457 | 2457 |
|
2458 |
+The management interface can also listen on a unix domain socket, |
|
2459 |
+for those platforms that support it. To use a unix domain socket, specify |
|
2460 |
+the unix socket pathname in place of |
|
2461 |
+.B IP |
|
2462 |
+and set |
|
2463 |
+.B port |
|
2464 |
+to 'unix'. While the default behavior is to create a unix domain socket |
|
2465 |
+that may be connected to by any process, the |
|
2466 |
+.B --management-client-user |
|
2467 |
+and |
|
2468 |
+.B --management-client-group |
|
2469 |
+directives can be used to restrict access. |
|
2470 |
+ |
|
2458 | 2471 |
The management interface provides a special mode where the TCP |
2459 | 2472 |
management link can operate over the tunnel itself. To enable this mode, |
2460 | 2473 |
set |
... | ... |
@@ -2532,6 +2547,18 @@ filter file for each connecting client. See management-notes.txt |
2532 | 2532 |
in OpenVPN distribution for detailed notes. |
2533 | 2533 |
.\"********************************************************* |
2534 | 2534 |
.TP |
2535 |
+.B --management-client-user u |
|
2536 |
+When the management interface is listening on a unix domain socket, |
|
2537 |
+only allow connections from user |
|
2538 |
+.B u. |
|
2539 |
+.\"********************************************************* |
|
2540 |
+.TP |
|
2541 |
+.B --management-client-group g |
|
2542 |
+When the management interface is listening on a unix domain socket, |
|
2543 |
+only allow connections from group |
|
2544 |
+.B g. |
|
2545 |
+.\"********************************************************* |
|
2546 |
+.TP |
|
2535 | 2547 |
.B --plugin module-pathname [init-string] |
2536 | 2548 |
Load plug-in module from the file |
2537 | 2549 |
.B module-pathname, |
... | ... |
@@ -311,6 +311,10 @@ static const char usage_message[] = |
311 | 311 |
"--management ip port [pass] : Enable a TCP server on ip:port to handle\n" |
312 | 312 |
" management functions. pass is a password file\n" |
313 | 313 |
" or 'stdin' to prompt from console.\n" |
314 |
+#if UNIX_SOCK_SUPPORT |
|
315 |
+ " To listen on a unix domain socket, specific the pathname\n" |
|
316 |
+ " in place of ip and use 'unix' as the port number.\n" |
|
317 |
+#endif |
|
314 | 318 |
"--management-client : Management interface will connect as a TCP client to\n" |
315 | 319 |
" ip/port rather than listen as a TCP server.\n" |
316 | 320 |
"--management-query-passwords : Query management channel for private key\n" |
... | ... |
@@ -322,6 +326,12 @@ static const char usage_message[] = |
322 | 322 |
" event occurs.\n" |
323 | 323 |
"--management-log-cache n : Cache n lines of log file history for usage\n" |
324 | 324 |
" by the management channel.\n" |
325 |
+#if UNIX_SOCK_SUPPORT |
|
326 |
+ "--management-client-user u : When management interface is a unix socket, only\n" |
|
327 |
+ " allow connections from user u.\n" |
|
328 |
+ "--management-client-group g : When management interface is a unix socket, only\n" |
|
329 |
+ " allow connections from group g.\n" |
|
330 |
+#endif |
|
325 | 331 |
#ifdef MANAGEMENT_DEF_AUTH |
326 | 332 |
"--management-client-auth : gives management interface client the responsibility\n" |
327 | 333 |
" to authenticate clients after their client certificate\n" |
... | ... |
@@ -1240,6 +1250,8 @@ show_settings (const struct options *o) |
1240 | 1240 |
SHOW_INT (management_log_history_cache); |
1241 | 1241 |
SHOW_INT (management_echo_buffer_size); |
1242 | 1242 |
SHOW_STR (management_write_peer_info_file); |
1243 |
+ SHOW_STR (management_client_user); |
|
1244 |
+ SHOW_STR (management_client_group); |
|
1243 | 1245 |
SHOW_INT (management_flags); |
1244 | 1246 |
#endif |
1245 | 1247 |
#ifdef ENABLE_PLUGIN |
... | ... |
@@ -1554,6 +1566,14 @@ options_postprocess_verify_ce (const struct options *options, const struct conne |
1554 | 1554 |
|| options->management_write_peer_info_file |
1555 | 1555 |
|| options->management_log_history_cache != defaults.management_log_history_cache)) |
1556 | 1556 |
msg (M_USAGE, "--management is not specified, however one or more options which modify the behavior of --management were specified"); |
1557 |
+ |
|
1558 |
+ if ((options->management_flags & (MF_LISTEN_UNIX|MF_CONNECT_AS_CLIENT)) |
|
1559 |
+ == (MF_LISTEN_UNIX|MF_CONNECT_AS_CLIENT)) |
|
1560 |
+ msg (M_USAGE, "--management-client does not support unix domain sockets"); |
|
1561 |
+ |
|
1562 |
+ if ((options->management_client_user || options->management_client_group) |
|
1563 |
+ && !(options->management_flags & MF_LISTEN_UNIX)) |
|
1564 |
+ msg (M_USAGE, "--management-client-(user|group) can only be used on unix domain sockets"); |
|
1557 | 1565 |
#endif |
1558 | 1566 |
|
1559 | 1567 |
/* |
... | ... |
@@ -3319,14 +3339,26 @@ add_option (struct options *options, |
3319 | 3319 |
#ifdef ENABLE_MANAGEMENT |
3320 | 3320 |
else if (streq (p[0], "management") && p[1] && p[2]) |
3321 | 3321 |
{ |
3322 |
- int port; |
|
3322 |
+ int port = 0; |
|
3323 | 3323 |
|
3324 | 3324 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
3325 |
- port = atoi (p[2]); |
|
3326 |
- if (!legal_ipv4_port (port)) |
|
3325 |
+ if (streq (p[2], "unix")) |
|
3327 | 3326 |
{ |
3328 |
- msg (msglevel, "port number associated with --management directive is out of range"); |
|
3327 |
+#if UNIX_SOCK_SUPPORT |
|
3328 |
+ options->management_flags |= MF_LISTEN_UNIX; |
|
3329 |
+#else |
|
3330 |
+ msg (msglevel, "MANAGEMENT: this platform does not support unix domain sockets"); |
|
3329 | 3331 |
goto err; |
3332 |
+#endif |
|
3333 |
+ } |
|
3334 |
+ else |
|
3335 |
+ { |
|
3336 |
+ port = atoi (p[2]); |
|
3337 |
+ if (!legal_ipv4_port (port)) |
|
3338 |
+ { |
|
3339 |
+ msg (msglevel, "port number associated with --management directive is out of range"); |
|
3340 |
+ goto err; |
|
3341 |
+ } |
|
3330 | 3342 |
} |
3331 | 3343 |
|
3332 | 3344 |
options->management_addr = p[1]; |
... | ... |
@@ -3336,6 +3368,16 @@ add_option (struct options *options, |
3336 | 3336 |
options->management_user_pass = p[3]; |
3337 | 3337 |
} |
3338 | 3338 |
} |
3339 |
+ else if (streq (p[0], "management-client-user") && p[1]) |
|
3340 |
+ { |
|
3341 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
3342 |
+ options->management_client_user = p[1]; |
|
3343 |
+ } |
|
3344 |
+ else if (streq (p[0], "management-client-group") && p[1]) |
|
3345 |
+ { |
|
3346 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
3347 |
+ options->management_client_group = p[1]; |
|
3348 |
+ } |
|
3339 | 3349 |
else if (streq (p[0], "management-query-passwords")) |
3340 | 3350 |
{ |
3341 | 3351 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
... | ... |
@@ -319,6 +319,9 @@ struct options |
319 | 319 |
int management_state_buffer_size; |
320 | 320 |
const char *management_write_peer_info_file; |
321 | 321 |
|
322 |
+ const char *management_client_user; |
|
323 |
+ const char *management_client_group; |
|
324 |
+ |
|
322 | 325 |
/* Mask of MF_ values of manage.h */ |
323 | 326 |
unsigned int management_flags; |
324 | 327 |
#endif |
... | ... |
@@ -610,9 +613,9 @@ char *options_string (const struct options *o, |
610 | 610 |
bool remote, |
611 | 611 |
struct gc_arena *gc); |
612 | 612 |
|
613 |
-int options_cmp_equal_safe (char *actual, const char *expected, size_t actual_n); |
|
613 |
+bool options_cmp_equal_safe (char *actual, const char *expected, size_t actual_n); |
|
614 | 614 |
void options_warning_safe (char *actual, const char *expected, size_t actual_n); |
615 |
-int options_cmp_equal (char *actual, const char *expected); |
|
615 |
+bool options_cmp_equal (char *actual, const char *expected); |
|
616 | 616 |
void options_warning (char *actual, const char *expected); |
617 | 617 |
|
618 | 618 |
#endif |
... | ... |
@@ -2627,3 +2627,125 @@ socket_set (struct link_socket *s, |
2627 | 2627 |
} |
2628 | 2628 |
return rwflags; |
2629 | 2629 |
} |
2630 |
+ |
|
2631 |
+void |
|
2632 |
+sd_close (socket_descriptor_t *sd) |
|
2633 |
+{ |
|
2634 |
+ if (sd && socket_defined (*sd)) |
|
2635 |
+ { |
|
2636 |
+ openvpn_close_socket (*sd); |
|
2637 |
+ *sd = SOCKET_UNDEFINED; |
|
2638 |
+ } |
|
2639 |
+} |
|
2640 |
+ |
|
2641 |
+#if UNIX_SOCK_SUPPORT |
|
2642 |
+ |
|
2643 |
+/* |
|
2644 |
+ * code for unix domain sockets |
|
2645 |
+ */ |
|
2646 |
+ |
|
2647 |
+const char * |
|
2648 |
+sockaddr_unix_name (const struct sockaddr_un *local, const char *null) |
|
2649 |
+{ |
|
2650 |
+ if (local && local->sun_family == PF_UNIX) |
|
2651 |
+ return local->sun_path; |
|
2652 |
+ else |
|
2653 |
+ return null; |
|
2654 |
+} |
|
2655 |
+ |
|
2656 |
+socket_descriptor_t |
|
2657 |
+create_socket_unix (void) |
|
2658 |
+{ |
|
2659 |
+ socket_descriptor_t sd; |
|
2660 |
+ |
|
2661 |
+ if ((sd = socket (PF_UNIX, SOCK_STREAM, 0)) < 0) |
|
2662 |
+ msg (M_SOCKERR, "Cannot create unix domain socket"); |
|
2663 |
+ return sd; |
|
2664 |
+} |
|
2665 |
+ |
|
2666 |
+void |
|
2667 |
+socket_bind_unix (socket_descriptor_t sd, |
|
2668 |
+ struct sockaddr_un *local, |
|
2669 |
+ const char *prefix) |
|
2670 |
+{ |
|
2671 |
+ struct gc_arena gc = gc_new (); |
|
2672 |
+ |
|
2673 |
+#ifdef HAVE_UMASK |
|
2674 |
+ const mode_t orig_umask = umask (0); |
|
2675 |
+#endif |
|
2676 |
+ |
|
2677 |
+ if (bind (sd, (struct sockaddr *) local, sizeof (struct sockaddr_un))) |
|
2678 |
+ { |
|
2679 |
+ const int errnum = openvpn_errno_socket (); |
|
2680 |
+ msg (M_FATAL, "%s: Socket bind[%d] failed on unix domain socket %s: %s", |
|
2681 |
+ prefix, |
|
2682 |
+ (int)sd, |
|
2683 |
+ sockaddr_unix_name (local, "NULL"), |
|
2684 |
+ strerror_ts (errnum, &gc)); |
|
2685 |
+ } |
|
2686 |
+ |
|
2687 |
+#ifdef HAVE_UMASK |
|
2688 |
+ umask (orig_umask); |
|
2689 |
+#endif |
|
2690 |
+ |
|
2691 |
+ gc_free (&gc); |
|
2692 |
+} |
|
2693 |
+ |
|
2694 |
+socket_descriptor_t |
|
2695 |
+socket_accept_unix (socket_descriptor_t sd, |
|
2696 |
+ struct sockaddr_un *remote) |
|
2697 |
+{ |
|
2698 |
+ socklen_t remote_len = sizeof (struct sockaddr_un); |
|
2699 |
+ socket_descriptor_t ret; |
|
2700 |
+ |
|
2701 |
+ CLEAR (*remote); |
|
2702 |
+ ret = accept (sd, (struct sockaddr *) remote, &remote_len); |
|
2703 |
+ return ret; |
|
2704 |
+} |
|
2705 |
+ |
|
2706 |
+void |
|
2707 |
+sockaddr_unix_init (struct sockaddr_un *local, const char *path) |
|
2708 |
+{ |
|
2709 |
+ local->sun_family = PF_UNIX; |
|
2710 |
+ strncpynt (local->sun_path, path, sizeof (local->sun_path)); |
|
2711 |
+} |
|
2712 |
+ |
|
2713 |
+void |
|
2714 |
+socket_delete_unix (const struct sockaddr_un *local) |
|
2715 |
+{ |
|
2716 |
+ const char *name = sockaddr_unix_name (local, NULL); |
|
2717 |
+#ifdef HAVE_UNLINK |
|
2718 |
+ if (name && strlen (name)) |
|
2719 |
+ unlink (name); |
|
2720 |
+#endif |
|
2721 |
+} |
|
2722 |
+ |
|
2723 |
+bool |
|
2724 |
+unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *gid) |
|
2725 |
+{ |
|
2726 |
+#ifdef HAVE_GETPEEREID |
|
2727 |
+ uid_t u; |
|
2728 |
+ gid_t g; |
|
2729 |
+ if (getpeereid (sd, &u, &g) == -1) |
|
2730 |
+ return false; |
|
2731 |
+ if (uid) |
|
2732 |
+ *uid = u; |
|
2733 |
+ if (gid) |
|
2734 |
+ *gid = g; |
|
2735 |
+ return true; |
|
2736 |
+#elif defined(SO_PEERCRED) |
|
2737 |
+ struct ucred peercred; |
|
2738 |
+ socklen_t so_len = sizeof(peercred); |
|
2739 |
+ if (getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) |
|
2740 |
+ return false; |
|
2741 |
+ if (uid) |
|
2742 |
+ *uid = peercred.uid; |
|
2743 |
+ if (gid) |
|
2744 |
+ *gid = peercred.gid; |
|
2745 |
+ return true; |
|
2746 |
+#else |
|
2747 |
+ return false; |
|
2748 |
+#endif |
|
2749 |
+} |
|
2750 |
+ |
|
2751 |
+#endif |
... | ... |
@@ -322,6 +322,8 @@ void frame_adjust_path_mtu (struct frame *frame, int pmtu, int proto); |
322 | 322 |
|
323 | 323 |
void link_socket_close (struct link_socket *sock); |
324 | 324 |
|
325 |
+void sd_close (socket_descriptor_t *sd); |
|
326 |
+ |
|
325 | 327 |
#define PS_SHOW_PORT_IF_DEFINED (1<<0) |
326 | 328 |
#define PS_SHOW_PORT (1<<1) |
327 | 329 |
#define PS_SHOW_PKTINFO (1<<2) |
... | ... |
@@ -408,6 +410,27 @@ socket_descriptor_t socket_do_accept (socket_descriptor_t sd, |
408 | 408 |
struct link_socket_actual *act, |
409 | 409 |
const bool nowait); |
410 | 410 |
|
411 |
+#if UNIX_SOCK_SUPPORT |
|
412 |
+ |
|
413 |
+socket_descriptor_t create_socket_unix (void); |
|
414 |
+ |
|
415 |
+void socket_bind_unix (socket_descriptor_t sd, |
|
416 |
+ struct sockaddr_un *local, |
|
417 |
+ const char *prefix); |
|
418 |
+ |
|
419 |
+socket_descriptor_t socket_accept_unix (socket_descriptor_t sd, |
|
420 |
+ struct sockaddr_un *remote); |
|
421 |
+ |
|
422 |
+void sockaddr_unix_init (struct sockaddr_un *local, const char *path); |
|
423 |
+ |
|
424 |
+const char *sockaddr_unix_name (const struct sockaddr_un *local, const char *null); |
|
425 |
+ |
|
426 |
+void socket_delete_unix (const struct sockaddr_un *local); |
|
427 |
+ |
|
428 |
+bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *gid); |
|
429 |
+ |
|
430 |
+#endif |
|
431 |
+ |
|
411 | 432 |
/* |
412 | 433 |
* DNS resolution |
413 | 434 |
*/ |
... | ... |
@@ -88,6 +88,10 @@ |
88 | 88 |
#include <sys/socket.h> |
89 | 89 |
#endif |
90 | 90 |
|
91 |
+#ifdef HAVE_SYS_UN_H |
|
92 |
+#include <sys/un.h> |
|
93 |
+#endif |
|
94 |
+ |
|
91 | 95 |
#ifdef HAVE_SYS_IOCTL_H |
92 | 96 |
#include <sys/ioctl.h> |
93 | 97 |
#endif |
... | ... |
@@ -516,6 +520,15 @@ socket_defined (const socket_descriptor_t sd) |
516 | 516 |
#endif |
517 | 517 |
|
518 | 518 |
/* |
519 |
+ * Do we support Unix domain sockets? |
|
520 |
+ */ |
|
521 |
+#if defined(PF_UNIX) && !defined(WIN32) |
|
522 |
+#define UNIX_SOCK_SUPPORT 1 |
|
523 |
+#else |
|
524 |
+#define UNIX_SOCK_SUPPORT 0 |
|
525 |
+#endif |
|
526 |
+ |
|
527 |
+/* |
|
519 | 528 |
* Don't compile the struct buffer_list code unless something needs it |
520 | 529 |
*/ |
521 | 530 |
#if defined(ENABLE_MANAGEMENT) || defined(ENABLE_PF) |