LCOV - code coverage report
Current view: top level - libpkg - ssh.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 0 78 0.0 %
Date: 2015-08-15 Functions: 0 1 0.0 %

          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/capability.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 <inttypes.h>
      40             : #define _WITH_GETLINE
      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[BUFSIZ];
      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             :         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 :                         chdir(restricted);
     142           0 :                         if (realpath(file, fpath) == NULL ||
     143           0 :                             realpath(restricted, rpath) == NULL ||
     144           0 :                             strncmp(fpath, rpath, strlen(rpath)) != 0) {
     145           0 :                                 printf("ko: file not found\n");
     146           0 :                                 continue;
     147             :                         }
     148             :                 }
     149             : 
     150           0 :                 if (fstatat(fd, file, &st, 0) == -1) {
     151           0 :                         pkg_debug(1, "SSH server> fstatat failed");
     152           0 :                         printf("ko: file not found\n");
     153           0 :                         continue;
     154             :                 }
     155             : 
     156           0 :                 if (!S_ISREG(st.st_mode)) {
     157           0 :                         printf("ko: not a file\n");
     158           0 :                         continue;
     159             :                 }
     160             : 
     161           0 :                 if (st.st_mtime <= mtime) {
     162           0 :                         printf("ok: 0\n");
     163           0 :                         continue;
     164             :                 }
     165             : 
     166           0 :                 if ((ffd = openat(fd, file, O_RDONLY)) == -1) {
     167           0 :                         printf("ko: file not found\n");
     168           0 :                         continue;
     169             :                 }
     170             : 
     171           0 :                 printf("ok: %" PRIdMAX "\n", (intmax_t)st.st_size);
     172           0 :                 pkg_debug(1, "SSH server> sending ok: %" PRIdMAX "", (intmax_t)st.st_size);
     173             : 
     174           0 :                 while ((r = read(ffd, buf, sizeof(buf))) > 0) {
     175           0 :                         pkg_debug(1, "SSH server> sending data");
     176           0 :                         fwrite(buf, 1, r, stdout);
     177             :                 }
     178             : 
     179           0 :                 pkg_debug(1, "SSH server> finished");
     180             : 
     181           0 :                 close(ffd);
     182           0 :         }
     183             : 
     184           0 :         free(line);
     185             : 
     186           0 :         return (EPKG_OK);
     187             : }

Generated by: LCOV version 1.10