LCOV - code coverage report
Current view: top level - libpkg - ssh.c (source / functions) Hit Total Coverage
Test: rapport Lines: 0 82 0.0 %
Date: 2021-12-10 16:22:55 Functions: 0 1 0.0 %
Branches: 0 50 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2013-2014 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
       4                 :            :  * All rights reserved.
       5                 :            :  * 
       6                 :            :  * Redistribution and use in source and binary forms, with or without
       7                 :            :  * modification, are permitted provided that the following conditions
       8                 :            :  * are met:
       9                 :            :  * 1. Redistributions of source code must retain the above copyright
      10                 :            :  *    notice, this list of conditions and the following disclaimer
      11                 :            :  *    in this position and unchanged.
      12                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer in the
      14                 :            :  *    documentation and/or other materials provided with the distribution.
      15                 :            :  * 
      16                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      17                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19                 :            :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      20                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26                 :            :  */
      27                 :            : 
      28                 :            : #ifdef HAVE_CONFIG_H
      29                 :            : #include "pkg_config.h"
      30                 :            : #endif
      31                 :            : #ifdef HAVE_CAPSICUM
      32                 :            : #include <sys/capsicum.h>
      33                 :            : #endif
      34                 :            : #include <sys/types.h>
      35                 :            : #include <sys/param.h>
      36                 :            : #include <sys/stat.h>
      37                 :            : 
      38                 :            : #include <ctype.h>
      39                 :            : #include <stdlib.h>
      40                 :            : #include <inttypes.h>
      41                 :            : #include <stdio.h>
      42                 :            : #include <string.h>
      43                 :            : #include <unistd.h>
      44                 :            : #include <fcntl.h>
      45                 :            : 
      46                 :            : #include <bsd_compat.h>
      47                 :            : 
      48                 :            : #include "pkg.h"
      49                 :            : #include "private/event.h"
      50                 :            : 
      51                 :            : int
      52                 :          0 : pkg_sshserve(int fd)
      53                 :            : {
      54                 :            :         struct stat st;
      55                 :          0 :         char *line = NULL;
      56                 :            :         char *file, *age;
      57                 :          0 :         size_t linecap = 0, r;
      58                 :            :         ssize_t linelen;
      59                 :          0 :         time_t mtime = 0;
      60                 :            :         const char *errstr;
      61                 :            :         int ffd;
      62                 :            :         char buf[32768];
      63                 :            :         char fpath[MAXPATHLEN];
      64                 :            :         char rpath[MAXPATHLEN];
      65                 :          0 :         const char *restricted = NULL;
      66                 :            : 
      67                 :          0 :         restricted = pkg_object_string(pkg_config_get("SSH_RESTRICT_DIR"));
      68                 :            : 
      69                 :          0 :         printf("ok: pkg "PKGVERSION"\n");
      70                 :          0 :         for (;;) {
      71         [ #  # ]:          0 :                 if ((linelen = getline(&line, &linecap, stdin)) < 0)
      72                 :          0 :                         break;
      73                 :            : 
      74         [ #  # ]:          0 :                 if (linelen == 0)
      75                 :          0 :                         continue;
      76                 :            : 
      77                 :            :                 /* trim cr */
      78         [ #  # ]:          0 :                 if (line[linelen - 1] == '\n')
      79                 :          0 :                         line[linelen - 1] = '\0';
      80                 :            : 
      81         [ #  # ]:          0 :                 if (strcmp(line, "quit") == 0)
      82                 :          0 :                         return (EPKG_OK);
      83                 :            : 
      84         [ #  # ]:          0 :                 if (strncmp(line, "get ", 4) != 0) {
      85                 :          0 :                         printf("ko: unknown command '%s'\n", line);
      86                 :          0 :                         continue;
      87                 :            :                 }
      88                 :            : 
      89                 :          0 :                 file = line + 4;
      90                 :            : 
      91         [ #  # ]:          0 :                 if (*file == '/')
      92                 :          0 :                         file++;
      93         [ #  # ]:          0 :                 else if (*file == '\0') {
      94                 :          0 :                         printf("ko: bad command get, expecting 'get file age'\n");
      95                 :          0 :                         continue;
      96                 :            :                 }
      97                 :            : 
      98                 :          0 :                 pkg_debug(1, "SSH server> file requested: %s", file);
      99                 :            : 
     100                 :          0 :                 age = file;
     101         [ #  # ]:          0 :                 while (!isspace(*age)) {
     102         [ #  # ]:          0 :                         if (*age == '\0') {
     103                 :          0 :                                 age = NULL;
     104                 :          0 :                                 break;
     105                 :            :                         }
     106                 :          0 :                         age++;
     107                 :            :                 }
     108                 :            : 
     109         [ #  # ]:          0 :                 if (age == NULL) {
     110                 :          0 :                         printf("ko: bad command get, expecting 'get file age'\n");
     111                 :          0 :                         continue;
     112                 :            :                 }
     113                 :            : 
     114                 :          0 :                 *age = '\0';
     115                 :          0 :                 age++;
     116                 :            : 
     117         [ #  # ]:          0 :                 while (isspace(*age)) {
     118         [ #  # ]:          0 :                         if (*age == '\0') {
     119                 :          0 :                                 age = NULL;
     120                 :          0 :                                 break;
     121                 :            :                         }
     122                 :          0 :                         age++;
     123                 :            :                 }
     124                 :            : 
     125         [ #  # ]:          0 :                 if (age == NULL) {
     126                 :          0 :                         printf("ko: bad command get, expecting 'get file age'\n");
     127                 :          0 :                         continue;
     128                 :            :                 }
     129                 :            : 
     130                 :          0 :                 mtime = strtonum(age, 0, LONG_MAX, &errstr);
     131         [ #  # ]:          0 :                 if (errstr) {
     132                 :          0 :                         printf("ko: bad number %s: %s\n", age, errstr);
     133                 :          0 :                         continue;
     134                 :            :                 }
     135                 :            : 
     136                 :            : #ifdef HAVE_CAPSICUM
     137   [ #  #  #  # ]:          0 :                 if (!cap_sandboxed() && restricted != NULL) {
     138                 :            : #else
     139                 :            :                 if (restricted != NULL) {
     140                 :            : #endif
     141         [ #  # ]:          0 :                         if (chdir(restricted)) {
     142                 :          0 :                                 printf("ko: chdir failed (%s)\n", restricted);
     143                 :          0 :                                 continue;
     144                 :            :                         }
     145                 :            : 
     146   [ #  #  #  # ]:          0 :                         if (realpath(file, fpath) == NULL ||
     147         [ #  # ]:          0 :                             realpath(restricted, rpath) == NULL ||
     148                 :          0 :                             strncmp(fpath, rpath, strlen(rpath)) != 0) {
     149                 :          0 :                                 printf("ko: file not found\n");
     150                 :          0 :                                 continue;
     151                 :            :                         }
     152                 :          0 :                 }
     153                 :            : 
     154         [ #  # ]:          0 :                 if (fstatat(fd, file, &st, 0) == -1) {
     155                 :          0 :                         pkg_debug(1, "SSH server> fstatat failed");
     156                 :          0 :                         printf("ko: file not found\n");
     157                 :          0 :                         continue;
     158                 :            :                 }
     159                 :            : 
     160         [ #  # ]:          0 :                 if (!S_ISREG(st.st_mode)) {
     161                 :          0 :                         printf("ko: not a file\n");
     162                 :          0 :                         continue;
     163                 :            :                 }
     164                 :            : 
     165         [ #  # ]:          0 :                 if (st.st_mtime <= mtime) {
     166                 :          0 :                         printf("ok: 0\n");
     167                 :          0 :                         continue;
     168                 :            :                 }
     169                 :            : 
     170         [ #  # ]:          0 :                 if ((ffd = openat(fd, file, O_RDONLY)) == -1) {
     171                 :          0 :                         printf("ko: file not found\n");
     172                 :          0 :                         continue;
     173                 :            :                 }
     174                 :            : 
     175                 :          0 :                 printf("ok: %" PRIdMAX "\n", (intmax_t)st.st_size);
     176                 :          0 :                 pkg_debug(1, "SSH server> sending ok: %" PRIdMAX "", (intmax_t)st.st_size);
     177                 :            : 
     178         [ #  # ]:          0 :                 while ((r = read(ffd, buf, sizeof(buf))) > 0) {
     179                 :          0 :                         pkg_debug(1, "SSH server> sending data");
     180                 :          0 :                         fwrite(buf, 1, r, stdout);
     181                 :            :                 }
     182                 :            : 
     183                 :          0 :                 pkg_debug(1, "SSH server> finished");
     184                 :            : 
     185                 :          0 :                 close(ffd);
     186                 :            :         }
     187                 :            : 
     188                 :          0 :         free(line);
     189                 :            : 
     190                 :          0 :         return (EPKG_OK);
     191                 :          0 : }

Generated by: LCOV version 1.15