Annotation of embedaddon/mtr/packet/packet.c, revision 1.1.1.3

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: 
1.1.1.3 ! misho      38: /*  Drop SUID privileges.  To be used after acquiring raw sockets.  */
1.1       misho      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:     /*
1.1.1.3 ! misho      85:        To minimize security risk, the only thing done prior to
1.1       misho      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>