1/* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License as 4 * published by the Free Software Foundation; either version 2 of 5 * the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 15 * MA 02111-1307 USA 16 */ 17/* 18 * Part of Very Secure FTPd 19 * Licence: GPL v2 20 * Author: Chris Evans 21 * privsock.c 22 * 23 * This file contains code for a simple message and file descriptor passing 24 * API, over a pair of UNIX sockets. 25 * The messages are typically travelling across a privilege boundary, with 26 * heavy distrust of messages on the side of more privilege. 27 */ 28 29#include "privsock.h" 30 31#include "utility.h" 32#include "defs.h" 33#include "str.h" 34#include "netstr.h" 35#include "sysutil.h" 36#include "sysdeputil.h" 37#include "session.h" 38 39void 40priv_sock_init(struct vsf_session* p_sess) 41{ 42 const struct vsf_sysutil_socketpair_retval retval = 43 vsf_sysutil_unix_stream_socketpair(); 44 p_sess->parent_fd = retval.socket_one; 45 p_sess->child_fd = retval.socket_two; 46} 47 48void 49priv_sock_send_cmd(int fd, char cmd) 50{ 51 int retval = vsf_sysutil_write_loop(fd, &cmd, sizeof(cmd)); 52 if (retval != sizeof(cmd)) 53 { 54 die("priv_sock_send_cmd"); 55 } 56} 57 58void 59priv_sock_send_str(int fd, const struct mystr* p_str) 60{ 61 unsigned int len = str_getlen(p_str); 62 priv_sock_send_int(fd, (int) len); 63 if (len > 0) 64 { 65 str_netfd_write(p_str, fd); 66 } 67} 68 69char 70priv_sock_get_result(int fd) 71{ 72 char res; 73 int retval = vsf_sysutil_read_loop(fd, &res, sizeof(res)); 74 if (retval != sizeof(res)) 75 { 76 die("priv_sock_get_result"); 77 } 78 return res; 79} 80 81char 82priv_sock_get_cmd(int fd) 83{ 84 char res; 85 int retval = vsf_sysutil_read_loop(fd, &res, sizeof(res)); 86 if (retval != sizeof(res)) 87 { 88 die("priv_sock_get_cmd"); 89 } 90 return res; 91} 92 93void 94priv_sock_get_str(int fd, struct mystr* p_dest) 95{ 96 unsigned int len = (unsigned int) priv_sock_get_int(fd); 97 if (len > VSFTP_PRIVSOCK_MAXSTR) 98 { 99 die("priv_sock_get_str: too big"); 100 } 101 str_empty(p_dest); 102 if (len > 0) 103 { 104 int retval = str_netfd_read(p_dest, fd, len); 105 if ((unsigned int) retval != len) 106 { 107 die("priv_sock_get_str: read error"); 108 } 109 } 110} 111 112void 113priv_sock_send_result(int fd, char res) 114{ 115 int retval = vsf_sysutil_write_loop(fd, &res, sizeof(res)); 116 if (retval != sizeof(res)) 117 { 118 die("priv_sock_send_result"); 119 } 120} 121 122void 123priv_sock_send_fd(int fd, int send_fd) 124{ 125 vsf_sysutil_send_fd(fd, send_fd); 126} 127 128int 129priv_sock_recv_fd(int fd) 130{ 131 return vsf_sysutil_recv_fd(fd); 132} 133 134void 135priv_sock_send_int(int fd, int the_int) 136{ 137 int retval = vsf_sysutil_write_loop(fd, &the_int, sizeof(the_int)); 138 if (retval != sizeof(the_int)) 139 { 140 die("priv_sock_send_int"); 141 } 142} 143 144int 145priv_sock_get_int(int fd) 146{ 147 int the_int; 148 int retval = vsf_sysutil_read_loop(fd, &the_int, sizeof(the_int)); 149 if (retval != sizeof(the_int)) 150 { 151 die("priv_sock_get_int"); 152 } 153 return the_int; 154} 155 156