LCOV - code coverage report
Current view: top level - minipot/libsentinel_minipot - minipot.c (source / functions) Hit Total Coverage
Test: sentinel-minipot-2.3.0 Code Coverage Lines: 0 79 0.0 %
Date: 2022-11-27 17:36:11 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include <minipot.h>
       2             : #include <minipot_utils.h>
       3             : #include <unistd.h>
       4             : #include <stdlib.h>
       5             : #include <sys/prctl.h>
       6             : #include <signal.h>
       7             : #include <pwd.h>
       8             : #include <grp.h>
       9             : #include <string.h>
      10             : #include "log.h"
      11             : 
      12             : #define LISTEN_QUEUE_LIMIT 5
      13             : 
      14           0 : static void sigint_cb(evutil_socket_t fd, short events, void *arg) {
      15           0 :         minipot_stop((struct minipot *)arg);
      16           0 : }
      17             : 
      18           0 : static int port_bind(int sock, uint16_t port) {
      19           0 :         struct sockaddr_in6 listen_addr;
      20           0 :         memset(&listen_addr, 0, sizeof(listen_addr));
      21           0 :         listen_addr.sin6_family = AF_INET6;
      22           0 :         listen_addr.sin6_addr = in6addr_any;
      23           0 :         listen_addr.sin6_port = htons(port);
      24           0 :         if (bind(sock, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) != 0)
      25           0 :                 return -1;
      26             :         return 0;
      27             : }
      28             : 
      29           0 : static int create_sock() {
      30           0 :         int fd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
      31           0 :         if (fd < 0)
      32             :                 return -1;
      33           0 :         int flag = 1;
      34           0 :         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) != 0)
      35           0 :                 goto err;
      36           0 :         flag = 0;
      37           0 :         if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) != 0)
      38           0 :                 goto err;
      39             :         return fd;
      40           0 : err:
      41           0 :         close(fd);
      42           0 :         return -1;
      43             : }
      44             : 
      45           0 : static int drop_priviledges(const char *username) {
      46           0 :         if (geteuid()) {
      47           0 :                 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
      48           0 :                         return -1;
      49             :         } else {
      50             :                 // running under super-user
      51           0 :                 struct passwd *usr = getpwnam(username);
      52           0 :                 if (!usr || chroot("/var/empty")
      53           0 :                                 || chdir("/")
      54           0 :                                 || setresgid(usr->pw_gid, usr->pw_gid, usr->pw_gid)
      55           0 :                                 || setgroups(1, &usr->pw_gid)
      56           0 :                                 || setresuid(usr->pw_uid, usr->pw_uid, usr->pw_uid)
      57           0 :                                 || (geteuid() == 0)
      58           0 :                                 || (getegid() == 0))
      59           0 :                         return -1;
      60             :         }
      61             :         return 0;
      62             : }
      63             : 
      64             : void minipot_init(struct minipot *self, const struct minipot_config *config,
      65             :                 int pipe_write_fd, event_callback_fn accept_cb, void *accept_cb_arg) {
      66             : 
      67           0 :         self->ev_base = event_base_new();
      68           0 :         assert(self->ev_base);
      69             : 
      70           0 :         self->sigint_ev = event_new(self->ev_base, SIGINT, EV_SIGNAL, sigint_cb,
      71             :                 self);
      72           0 :         assert(self->sigint_ev);
      73           0 :         assert(event_add(self->sigint_ev, NULL) == 0);
      74             : 
      75           0 :         self->smsg_packer = minipot_sentinel_msg_packer_new();
      76           0 :         assert(self->smsg_packer);
      77             : 
      78           0 :         self->report_fd = pipe_write_fd;
      79             :         
      80           0 :         self->recv_buff = malloc(sizeof(*self->recv_buff) * MINIPOT_RECV_BUFF_LEN);
      81             : 
      82           0 :         self->ports_cnt = config->ports_cnt;
      83           0 :         self->listen_fds = malloc(sizeof(*self->listen_fds) * self->ports_cnt);
      84           0 :         self->accept_evs = malloc(sizeof(**self->accept_evs) * self->ports_cnt);
      85             : 
      86           0 :         for (size_t i = 0; i < self->ports_cnt; i++) {
      87           0 :                 self->listen_fds[i] = create_sock();
      88           0 :                 assert(self->listen_fds[i]);
      89           0 :                 assert(port_bind(self->listen_fds[i], config->ports[i]) == 0);
      90           0 :                 assert(listen(self->listen_fds[i], LISTEN_QUEUE_LIMIT) == 0);
      91           0 :                 self->accept_evs[i] = event_new(self->ev_base, self->listen_fds[i],
      92             :                         EV_READ | EV_PERSIST, accept_cb, accept_cb_arg);
      93           0 :                 assert(self->accept_evs[i]);
      94             :         }
      95           0 :         assert(drop_priviledges(config->user) == 0);
      96           0 : }
      97             : 
      98             : void minipot_destroy(struct minipot *self) {
      99           0 :         event_free(self->sigint_ev);
     100           0 :         free(self->recv_buff);
     101           0 :         for (size_t i = 0; i < self->ports_cnt; i++) {
     102           0 :                 event_free(self->accept_evs[i]);
     103           0 :                 close(self->listen_fds[i]);
     104             :         }
     105           0 :         free(self->listen_fds);
     106           0 :         free(self->accept_evs);
     107           0 :         event_base_free(self->ev_base);
     108           0 :         minipot_sentinel_msg_packer_free(self->smsg_packer);
     109           0 : }
     110             : 
     111             : int minipot_run(struct minipot *self) {
     112           0 :         return event_base_dispatch(self->ev_base);
     113             : }
     114             : 
     115             : int minipot_stop(struct minipot *self) {
     116           0 :         return event_base_loopbreak(self->ev_base);
     117             : }
     118             : 
     119             : int minipot_start_accept_new_conn(struct minipot *self) {
     120           0 :         int ret = 0;
     121           0 :         for (size_t i = 0; i < self->ports_cnt; i++)
     122           0 :                 if (event_add(self->accept_evs[i], NULL))
     123           0 :                         ret = -1;
     124           0 :         return ret;
     125             : }
     126             : 
     127             : int minipot_stop_accept_new_conn(struct minipot *self) {
     128           0 :         int ret = 0;
     129           0 :         for (size_t i = 0; i < self->ports_cnt; i++)
     130           0 :                 if (event_del(self->accept_evs[i]))
     131           0 :                         ret = -1;
     132           0 :         return ret;
     133             : }

Generated by: LCOV version 1.16