Annotation of embedaddon/mtr/packet/packet.c, revision 1.1.1.2
1.1 misho 1: /*
2: mtr -- a network diagnostic tool
3: Copyright (C) 2016 Matt Kimball
4:
5: This program is free software; you can redistribute it and/or modify
6: it under the terms of the GNU General Public License version 2 as
7: published by the Free Software Foundation.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: GNU General Public License for more details.
13:
1.1.1.2 ! misho 14: You should have received a copy of the GNU General Public License along
! 15: with this program; if not, write to the Free Software Foundation, Inc.,
! 16: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1.1 misho 17: */
18:
19: #include "config.h"
20:
21: #include <errno.h>
1.1.1.2 ! misho 22: #ifdef HAVE_ERROR_H
! 23: #include <error.h>
! 24: #else
! 25: #include "portability/error.h"
! 26: #endif
1.1 misho 27: #include <stdio.h>
28: #include <stdlib.h>
29: #include <string.h>
30: #include <unistd.h>
31:
32: #ifdef HAVE_LIBCAP
33: #include <sys/capability.h>
34: #endif
35:
36: #include "wait.h"
37:
38: /* Drop SUID privileges. To be used after accquiring raw sockets. */
39: static
40: int drop_elevated_permissions(
41: void)
42: {
43: #ifdef HAVE_LIBCAP
44: cap_t cap;
45: #endif
46:
47: /* Drop any suid permissions granted */
48: if (setgid(getgid()) || setuid(getuid())) {
49: return -1;
50: }
51:
52: if (geteuid() != getuid() || getegid() != getgid()) {
53: return -1;
54: }
55:
56: /*
57: Drop all process capabilities.
58: This will revoke anything granted by a commandline 'setcap'
59: */
60: #ifdef HAVE_LIBCAP
61: cap = cap_get_proc();
62: if (cap == NULL) {
63: return -1;
64: }
65: if (cap_clear(cap)) {
66: return -1;
67: }
68: if (cap_set_proc(cap)) {
69: return -1;
70: }
71: #endif
72:
73: return 0;
74: }
75:
76: int main(
77: int argc,
78: char **argv)
79: {
80: bool command_pipe_open;
81: struct command_buffer_t command_buffer;
82: struct net_state_t net_state;
83:
84: /*
85: To minimize security risk, the only thing done prior to
86: dropping SUID should be opening the network state for
87: raw sockets.
88: */
89: init_net_state_privileged(&net_state);
90: if (drop_elevated_permissions()) {
1.1.1.2 ! misho 91: error(EXIT_FAILURE, errno, "Unable to drop elevated permissions");
1.1 misho 92: }
93: init_net_state(&net_state);
94:
95: init_command_buffer(&command_buffer, fileno(stdin));
96:
97: command_pipe_open = true;
98:
99: /*
100: Dispatch commands and respond to probe replies until the
101: command stream is closed.
102: */
103: while (true) {
104: /* Ensure any responses are written before waiting */
105: fflush(stdout);
106: wait_for_activity(&command_buffer, &net_state);
107:
108: /*
109: Receive replies first so that the timestamps are as
110: close to the response arrival time as possible.
111: */
112: receive_replies(&net_state);
113:
114: if (command_pipe_open) {
115: if (read_commands(&command_buffer)) {
116: if (errno == EPIPE) {
117: command_pipe_open = false;
118: }
119: }
120: }
121:
122: check_probe_timeouts(&net_state);
123:
124: /*
125: Dispatch commands late so that the window between probe
126: departure and arriving replies is as small as possible.
127: */
128: dispatch_buffer_commands(&command_buffer, &net_state);
129:
130: /*
131: If the command pipe has been closed, exit after all
132: in-flight probes have reported their status.
133: */
134: if (!command_pipe_open) {
135: if (net_state.outstanding_probe_count == 0) {
136: break;
137: }
138: }
139: }
140:
141: return 0;
142: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>