/ src / ssh.c
ssh.c
 1  /*-
 2   * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
 3   * All rights reserved.
 4   *
 5   * Redistribution and use in source and binary forms, with or without
 6   * modification, are permitted provided that the following conditions
 7   * are met:
 8   * 1. Redistributions of source code must retain the above copyright
 9   *    notice, this list of conditions and the following disclaimer
10   *    in this position and unchanged.
11   * 2. Redistributions in binary form must reproduce the above copyright
12   *    notice, this list of conditions and the following disclaimer in the
13   *    documentation and/or other materials provided with the distribution.
14   *
15   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18   * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  #if __has_include(<sys/capsicum.h>)
28  #include <sys/capsicum.h>
29  #define HAVE_CAPSICUM 1
30  #endif
31  
32  #include <stdio.h>
33  #include <unistd.h>
34  #include <fcntl.h>
35  #include <err.h>
36  #include <errno.h>
37  
38  #include <pkg.h>
39  
40  #include "pkgcli.h"
41  
42  void
43  usage_ssh(void)
44  {
45  	fprintf(stderr, "Usage: pkg ssh\n\n");
46  	fprintf(stderr, "For more information see 'pkg help ssh'.\n");
47  }
48  
49  int
50  exec_ssh(int argc, char **argv __unused)
51  {
52  	int fd = -1;
53  	const char *restricted = NULL;
54  
55  #ifdef HAVE_CAPSICUM
56  	cap_rights_t rights;
57  #endif
58  
59  	if (argc > 1) {
60  		usage_ssh();
61  		return (EXIT_FAILURE);
62  	}
63  
64  	restricted = pkg_object_string(pkg_config_get("SSH_RESTRICT_DIR"));
65  	if (restricted == NULL)
66  		restricted = "/";
67  
68  	if ((fd = open(restricted, O_DIRECTORY|O_RDONLY|O_CLOEXEC)) < 0) {
69  		warn("Unable to open the restricted directory");
70  		return (EXIT_FAILURE);
71  	}
72  
73  #ifdef HAVE_CAPSICUM
74  	cap_rights_init(&rights, CAP_READ, CAP_FSTATAT, CAP_FCNTL);
75  	if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS ) {
76  		warn("cap_rights_limit() failed");
77  		close(fd);
78  		return (EXIT_FAILURE);
79  	}
80  
81  #ifndef COVERAGE
82  	if (cap_enter() < 0 && errno != ENOSYS) {
83  		warn("cap_enter() failed");
84  		close(fd);
85  		return (EXIT_FAILURE);
86  	}
87  #endif
88  
89  #endif
90  	if (pkg_sshserve(fd) != EPKG_OK) {
91  		close(fd);
92  		return (EXIT_FAILURE);
93  	}
94  
95  	close(fd);
96  	return (EXIT_SUCCESS);
97  }