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