1/*
2 * Part of Very Secure FTPd
3 * Licence: GPL v2
4 * Author: Chris Evans
5 * privsock.c
6 *
7 * This file contains code for a simple message and file descriptor passing
8 * API, over a pair of UNIX sockets.
9 * The messages are typically travelling across a privilege boundary, with
10 * heavy distrust of messages on the side of more privilege.
11 */
12
13#include "privsock.h"
14
15#include "utility.h"
16#include "defs.h"
17#include "str.h"
18#include "netstr.h"
19#include "sysutil.h"
20#include "sysdeputil.h"
21#include "session.h"
22
23void
24priv_sock_init(struct vsf_session* p_sess)
25{
26  const struct vsf_sysutil_socketpair_retval retval =
27    vsf_sysutil_unix_stream_socketpair();
28  p_sess->parent_fd = retval.socket_one;
29  p_sess->child_fd = retval.socket_two;
30}
31
32void
33priv_sock_send_cmd(int fd, char cmd)
34{
35  int retval = vsf_sysutil_write_loop(fd, &cmd, sizeof(cmd));
36  if (retval != sizeof(cmd))
37  {
38    die("priv_sock_send_cmd");
39  }
40}
41
42void
43priv_sock_send_str(int fd, const struct mystr* p_str)
44{
45  unsigned int len = str_getlen(p_str);
46  priv_sock_send_int(fd, (int) len);
47  if (len > 0)
48  {
49    str_netfd_write(p_str, fd);
50  }
51}
52
53char
54priv_sock_get_result(int fd)
55{
56  char res;
57  int retval = vsf_sysutil_read_loop(fd, &res, sizeof(res));
58  if (retval != sizeof(res))
59  {
60    die("priv_sock_get_result");
61  }
62  return res;
63}
64
65char
66priv_sock_get_cmd(int fd)
67{
68  char res;
69  int retval = vsf_sysutil_read_loop(fd, &res, sizeof(res));
70  if (retval != sizeof(res))
71  {
72    die("priv_sock_get_cmd");
73  }
74  return res;
75}
76
77void
78priv_sock_get_str(int fd, struct mystr* p_dest)
79{
80  unsigned int len = (unsigned int) priv_sock_get_int(fd);
81  if (len > VSFTP_PRIVSOCK_MAXSTR)
82  {
83    die("priv_sock_get_str: too big");
84  }
85  str_empty(p_dest);
86  if (len > 0)
87  {
88    int retval = str_netfd_read(p_dest, fd, len);
89    if ((unsigned int) retval != len)
90    {
91      die("priv_sock_get_str: read error");
92    }
93  }
94}
95
96void
97priv_sock_send_result(int fd, char res)
98{
99  int retval = vsf_sysutil_write_loop(fd, &res, sizeof(res));
100  if (retval != sizeof(res))
101  {
102    die("priv_sock_send_result");
103  }
104}
105
106void
107priv_sock_send_fd(int fd, int send_fd)
108{
109  vsf_sysutil_send_fd(fd, send_fd);
110}
111
112int
113priv_sock_recv_fd(int fd)
114{
115  return vsf_sysutil_recv_fd(fd);
116}
117
118void
119priv_sock_send_int(int fd, int the_int)
120{
121  int retval = vsf_sysutil_write_loop(fd, &the_int, sizeof(the_int));
122  if (retval != sizeof(the_int))
123  {
124    die("priv_sock_send_int");
125  }
126}
127
128int
129priv_sock_get_int(int fd)
130{
131  int the_int;
132  int retval = vsf_sysutil_read_loop(fd, &the_int, sizeof(the_int));
133  if (retval != sizeof(the_int))
134  {
135    die("priv_sock_get_int");
136  }
137  return the_int;
138}
139
140