client_common.c: clean up log messages
[paraslash.git] / net.c
1 /*
2  * Copyright (C) 2005-2006 Andre Noll <maan@systemlinux.org>
3  *
4  *     This program is free software; you can redistribute it and/or modify
5  *     it under the terms of the GNU General Public License as published by
6  *     the Free Software Foundation; either version 2 of the License, or
7  *     (at your option) any later version.
8  *
9  *     This program is distributed in the hope that it will be useful,
10  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *     GNU General Public License for more details.
13  *
14  *     You should have received a copy of the GNU General Public License
15  *     along with this program; if not, write to the Free Software
16  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17  */
18
19 /** \file net.c networking-related helper functions */
20
21 #include "para.h"
22 #include "net.h"
23 #include "string.h"
24 #include "error.h"
25
26 struct crypt_data {
27         crypt_function *recv;
28         crypt_function *send;
29         void *private_data;
30 };
31
32 static struct crypt_data *crypt_data_array;
33 static unsigned cda_size = 0;
34
35 void enable_crypt(int fd, crypt_function *recv, crypt_function *send,
36         void *private_data)
37 {
38         if (fd + 1 > cda_size) {
39                 crypt_data_array = para_realloc(crypt_data_array,
40                         (fd + 1) * sizeof(struct crypt_data));
41                 memset(crypt_data_array + cda_size * sizeof(struct crypt_data), 0,
42                         (fd + 1 - cda_size) * sizeof(struct crypt_data));
43                 cda_size = fd + 1;
44         }
45         crypt_data_array[fd].recv = recv;
46         crypt_data_array[fd].send = send;
47         crypt_data_array[fd].private_data = private_data;
48         PARA_INFO_LOG("rc4 encryption activated for fd %d\n", fd);
49 }
50
51 void disable_crypt(int fd)
52 {
53         if (cda_size < fd + 1)
54                 return;
55         crypt_data_array[fd].recv = NULL;
56         crypt_data_array[fd].send = NULL;
57         crypt_data_array[fd].private_data = NULL;
58 }
59
60
61 /**
62  * initialize a struct sockaddr_in
63  * @param addr A pointer to the struct to be initialized
64  * @param port The port number to use
65  * @param he The address to use
66  *
67  * If \a he is null (server mode), \a addr->sin_addr is initialized with \p INADDR_ANY.
68  * Otherwise, the address given by \a he is copied to addr.
69  */
70 void init_sockaddr(struct sockaddr_in *addr, int port, const struct hostent *he)
71 {
72         /* host byte order */
73         addr->sin_family = AF_INET;
74         /* short, network byte order */
75         addr->sin_port = htons(port);
76         if (he)
77                 addr->sin_addr = *((struct in_addr *)he->h_addr);
78         else
79                 addr->sin_addr.s_addr = INADDR_ANY;
80         /* zero the rest of the struct */
81         memset(&addr->sin_zero, '\0', 8);
82 }
83
84 /*
85  * send out a buffer, resend on short writes
86  * @param fd the file descriptor
87  * @param buf The buffer to be sent
88  * @len The length of \a buf
89  *
90  * Due to circumstances beyond your control, the kernel might not send all the
91  * data out in one chunk, and now, my friend, it's up to us to get the data out
92  * there (Beej's Guide to Network Programming).
93  */
94 static int sendall(int fd, const char *buf, size_t *len)
95 {
96         int total = 0;        /* how many bytes we've sent */
97         int bytesleft = *len; /* how many we have left to send */
98         int n = -1;
99
100         while (total < *len) {
101                 n = send(fd, buf + total, bytesleft, 0);
102                 if (n == -1)
103                         break;
104                 total += n;
105                 bytesleft -= n;
106                 if (total < *len)
107                         PARA_DEBUG_LOG("short write (%zd byte(s) left)",
108                                 *len - total);
109         }
110         *len = total; /* return number actually sent here */
111         return n == -1? -E_SEND : 1; /* return 1 on success */
112 }
113
114 /**
115  * encrypt and send buffer
116  * @param fd:  the file descriptor
117  * @param buf the buffer to be encrypted and sent
118  * @param len the length of \a buf
119  *
120  * Check if encrytion is available. If yes, encrypt the given buffer.  Send out
121  * the buffer, encrypted or not, and try to resend the remaing part in case of
122  * short writes.
123  *
124  * @return Positive on success, \p -E_SEND on errors.
125  */
126 int send_bin_buffer(int fd, const char *buf, size_t len)
127 {
128         int ret;
129         crypt_function *cf = NULL;
130
131         if (!len)
132                 PARA_CRIT_LOG("%s", "len == 0\n");
133         if (fd + 1 <= cda_size)
134                 cf = crypt_data_array[fd].send;
135         if (cf) {
136                 void *private = crypt_data_array[fd].private_data;
137                 unsigned char *outbuf = para_malloc(len);
138                 (*cf)(len, (unsigned char *)buf, outbuf, private);
139                 ret = sendall(fd, (char *)outbuf, &len);
140                 free(outbuf);
141         } else
142                 ret = sendall(fd, buf, &len);
143         return ret;
144 }
145
146 /**
147  * encrypt and send null terminated buffer.
148  * @param fd the file descriptor
149  * @param buf the null-terminated buffer to be send
150  *
151  * This is equivalent to send_bin_buffer(fd, buf, strlen(buf)).
152  *
153  * @return Positive on success, \p -E_SEND on errors.
154  */
155 int send_buffer(int fd, const char *buf)
156 {
157         return send_bin_buffer(fd, buf, strlen(buf));
158 }
159
160
161 /**
162  * send and encrypt a buffer given by a format string
163  * @param fd the file descriptor
164  * @param fmt a format string
165  *
166  * @return Positive on success, \p -E_SEND on errors.
167  */
168 __printf_2_3 int send_va_buffer(int fd, const char *fmt, ...)
169 {
170         char *msg;
171         int ret;
172
173         PARA_VSPRINTF(fmt, msg);
174         ret = send_buffer(fd, msg);
175         free(msg);
176         return ret;
177 }
178
179 /**
180  * receive and decrypt.
181  *
182  * @param fd the file descriptor
183  * @param buf the buffer to write the decrypted data to
184  * @param size the size of @param buf
185  *
186  * Receive at most \a size bytes from filedescriptor fd. If encrytion is
187  * available, decrypt the received buffer.
188  *
189  * @return the number of bytes received on success. On receive errors, -E_RECV
190  * is returned. On crypt errors, the corresponding crypt error number is
191  * returned.
192  * \sa recv(2)
193  */
194 __must_check int recv_bin_buffer(int fd, char *buf, ssize_t size)
195 {
196         int n;
197         crypt_function *cf = NULL;
198
199         if (fd + 1 <= cda_size)
200                 cf = crypt_data_array[fd].recv;
201         if (cf) {
202                 unsigned char *tmp = para_malloc(size);
203                 void *private = crypt_data_array[fd].private_data;
204                 n = recv(fd, tmp, size, 0);
205                 if (n > 0)
206                         (*cf)(n, tmp, (unsigned char *)buf, private);
207                 free(tmp);
208         } else
209                 n = recv(fd, buf, size, 0);
210         if (n == -1)
211                 n = -E_RECV;
212         return n;
213 }
214
215 /**
216  * receive, decrypt and write terminating NULL byte
217  *
218  * @param fd the file descriptor
219  * @param buf the buffer to write the decrypted data to
220  * @param size the size of \a buf
221  *
222  * Read and decrypt at most size - 1 bytes from file descriptor \a fd and write
223  * a NULL byte at the end of the received data.
224  *
225 */
226 int recv_buffer(int fd, char *buf, ssize_t size)
227 {
228         int n;
229
230         n = recv_bin_buffer(fd, buf, size - 1);
231         if (n >= 0)
232                 buf[n] = '\0';
233         else
234                 *buf = '\0';
235         return n;
236 }
237
238 /**
239  * wrapper around gethostbyname
240  *
241  * \param host hostname or IPv4 address
242  * \param ret the hostent structure is returned here
243  *
244  * \return positive on success, negative on errors. On success, \a ret
245  * contains the return value of the underlying gethostbyname() call.
246  *
247  * \sa gethostbyname(2)
248  */
249 int get_host_info(char *host, struct hostent **ret)
250 {
251         PARA_INFO_LOG("getting host info of %s\n", host);
252         /* FIXME: gethostbyname() is obsolete */
253         *ret = gethostbyname(host);
254         return *ret? 1 : -E_HOST_INFO;
255 }
256
257 /**
258  * a wrapper around socket(2)
259  *
260  * Create an IPv4 socket for sequenced, reliable, two-way, connection-based
261  * byte streams.
262  *
263  * @return The socket fd on success, -E_SOCKET on errors.
264  * \sa socket(2)
265  */
266 int get_socket(void)
267 {
268         int socket_fd;
269
270         if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
271                 return -E_SOCKET;
272         return socket_fd;
273 }
274
275 /**
276  * a wrapper around connect(2)
277  *
278  * @param fd the file descriptor
279  * @param their_addr the address to connect
280  *
281  * @return \p -E_CONNECT on errors, 1 on success
282  * \sa connect(2)
283  */
284 int para_connect(int fd, struct sockaddr_in *their_addr)
285 {
286         int ret;
287
288         if ((ret = connect(fd, (struct sockaddr *)their_addr,
289                         sizeof(struct sockaddr))) == -1)
290                 return -E_CONNECT;
291         return 1;
292 }
293
294 /**
295  * paraslash's wrapper around the accept system call
296  *
297  * @param fd the listening socket
298  * @param addr structure which is filled in with the address of the peer socket
299  * @param size should contain the size of the structure pointed to by \a addr
300  *
301  * \sa accept(2).
302  */
303 int para_accept(int fd, void *addr, socklen_t size)
304 {
305         int new_fd;
306
307         new_fd = accept(fd, (struct sockaddr *) addr, &size);
308         return new_fd == -1? -E_ACCEPT : new_fd;
309 }
310
311 static int setserversockopts(int socket_fd)
312 {
313         int yes = 1;
314
315         if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes,
316                         sizeof(int)) == -1)
317                 return -E_SETSOCKOPT;
318         return 1;
319 }
320
321 /**
322  * prepare a structure for \p AF_UNIX socket addresses
323  *
324  * \param u pointer to the struct to be prepared
325  * \param name the socket pathname
326  *
327  * This just copies \a name to the sun_path component of \a u.
328  *
329  * \return Positive on success, \p -E_NAME_TOO_LONG if \a name is longer
330  * than \p UNIX_PATH_MAX.
331  */
332 int init_unix_addr(struct sockaddr_un *u, const char *name)
333 {
334         if (strlen(name) >= UNIX_PATH_MAX)
335                 return -E_NAME_TOO_LONG;
336         memset(u->sun_path, 0, UNIX_PATH_MAX);
337         u->sun_family = PF_UNIX;
338         strcpy(u->sun_path, name);
339         return 1;
340 }
341
342 /**
343  * prepare, create, and bind and socket for local communication
344  *
345  * \param name the socket pathname
346  * \param unix_addr pointer to the \p AF_UNIX socket structure
347  * \param mode the desired mode of the socket
348  *
349  * This functions creates a local socket for sequenced, reliable,
350  * two-way, connection-based byte streams.
351  * \sa socket(2)
352  * \sa bind(2)
353  * \sa chmod(2)
354  */
355 int create_pf_socket(const char *name, struct sockaddr_un *unix_addr, int mode)
356 {
357         int fd, ret;
358
359         fd = socket(PF_UNIX, SOCK_STREAM, 0);
360         if (fd < 0)
361                 return -E_SOCKET;
362 //      unlink(name);
363         ret = init_unix_addr(unix_addr, name);
364         if (ret < 0)
365                 return ret;
366         if (bind(fd, (struct sockaddr *) unix_addr, UNIX_PATH_MAX) < 0)
367                 return -E_BIND;
368         if (chmod(name, mode) < 0)
369                 return -E_CHMOD;
370         return fd;
371 }
372
373 #ifndef HAVE_UCRED
374         struct ucred {
375         uid_t uid, pid, gid;
376 };
377 ssize_t send_cred_buffer(int sock, char *buf)
378 {
379         return send_buffer(sock, buf);
380 }
381 int recv_cred_buffer(int fd, char *buf, size_t size)
382 {
383         return recv_buffer(fd, buf, size) > 0? 1 : -E_RECVMSG;
384 }
385 #else /* HAVE_UCRED */
386 /**
387  * send NULL terminated buffer and Unix credentials of the current process
388  *
389  * \param sock the socket file descriptor
390  * \param buf the buffer to be sent
391  *
392  * \return On success, this call returns the number of characters sent.  On
393  * error, \p -E_SENDMSG ist returned.
394  * \sa  okir's Black Hats Manual
395  * \sa sendmsg(2)
396  */
397 ssize_t send_cred_buffer(int sock, char *buf)
398 {
399         char control[sizeof(struct cmsghdr) + 10];
400         struct msghdr msg;
401         struct cmsghdr *cmsg;
402         static struct iovec iov;
403         struct ucred c;
404         int ret;
405
406         /* Response data */
407         iov.iov_base = buf;
408         iov.iov_len  = strlen(buf);
409         c.pid = getpid();
410         c.uid = getuid();
411         c.gid = getgid();
412         /* compose the message */
413         memset(&msg, 0, sizeof(msg));
414         msg.msg_iov = &iov;
415         msg.msg_iovlen = 1;
416         msg.msg_control = control;
417         msg.msg_controllen = sizeof(control);
418         /* attach the ucred struct */
419         cmsg = CMSG_FIRSTHDR(&msg);
420         cmsg->cmsg_level = SOL_SOCKET;
421         cmsg->cmsg_type = SCM_CREDENTIALS;
422         cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
423         *(struct ucred *)CMSG_DATA(cmsg) = c;
424         msg.msg_controllen = cmsg->cmsg_len;
425         ret = sendmsg(sock, &msg, 0);
426         if (ret  < 0)
427                 ret = -E_SENDMSG;
428         return ret;
429 }
430
431 static void dispose_fds(int *fds, int num)
432 {
433         int i;
434
435         for (i = 0; i < num; i++)
436                 close(fds[i]);
437 }
438
439 /**
440  * receive a buffer and the Unix credentials of the sending process
441  *
442  * \param fd the socket file descriptor
443  * \param buf the buffer to store the message
444  * \param size the size of \a buffer
445  *
446  * \return negative on errors, the user id on success.
447  *
448  * \sa okir's Black Hats Manual
449  * \sa recvmsg(2)
450  */
451 int recv_cred_buffer(int fd, char *buf, size_t size)
452 {
453         char control[255];
454         struct msghdr msg;
455         struct cmsghdr *cmsg;
456         struct iovec iov;
457         int result = 0;
458         int yes = 1;
459         struct ucred cred;
460
461         setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &yes, sizeof(int));
462         memset(&msg, 0, sizeof(msg));
463         memset(buf, 0, size);
464         iov.iov_base = buf;
465         iov.iov_len = size;
466         msg.msg_iov = &iov;
467         msg.msg_iovlen = 1;
468         msg.msg_control = control;
469         msg.msg_controllen = sizeof(control);
470         if (recvmsg(fd, &msg, 0) < 0)
471                 return -E_RECVMSG;
472         result = -E_SCM_CREDENTIALS;
473         cmsg = CMSG_FIRSTHDR(&msg);
474         while (cmsg) {
475                 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type
476                                 == SCM_CREDENTIALS) {
477                         memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred));
478                         result = cred.uid;
479                 } else
480                         if (cmsg->cmsg_level == SOL_SOCKET
481                                         && cmsg->cmsg_type == SCM_RIGHTS) {
482                                 dispose_fds((int *) CMSG_DATA(cmsg),
483                                         (cmsg->cmsg_len - CMSG_LEN(0))
484                                         / sizeof(int));
485                         }
486                 cmsg = CMSG_NXTHDR(&msg, cmsg);
487         }
488         return result;
489 }
490 #endif /* HAVE_UCRED */
491
492 /** how many pending connections queue will hold */
493 #define BACKLOG 10
494
495 /**
496  * create a socket, bind it and listen
497  * \param port the tcp port to listen on
498  *
499  * \return The file descriptor of the created socket, negative
500  * on errors.
501  *
502  * \sa get_socket()
503  * \sa setsockopt(2)
504  * \sa bind(2)
505  * \sa listen(2)
506  */
507 int init_tcp_socket(int port)
508 {
509         struct sockaddr_in my_addr;
510         int fd, ret = get_socket();
511
512         if (ret < 0)
513                 return ret;
514         fd = ret;
515         ret = setserversockopts(fd);
516         if (ret < 0)
517                 goto err;
518         init_sockaddr(&my_addr, port, NULL);
519         ret = -E_BIND;
520         if (bind(fd, (struct sockaddr *)&my_addr,
521                         sizeof(struct sockaddr)) == -1) {
522                 PARA_CRIT_LOG("bind error: %s\n", strerror(errno));
523                 goto err;
524         }
525         ret = -E_LISTEN;
526         if (listen(fd, BACKLOG) == -1)
527                 goto err;
528         PARA_INFO_LOG("listening on port %d, fd %d\n", port, fd);
529         return fd;
530 err:
531         close(fd);
532         return ret;
533 }
534
535 /**
536  * receive a buffer and check for a pattern
537  *
538  * \param fd the file descriptor to receive from
539  * \param pattern the expected pattern
540  * \param bufsize the size of the internal buffer
541  *
542  * \return Positive if \a pattern was received, negative otherwise.
543  *
544  * This function creates a buffer of size \a bufsize and tries
545  * to receive at most \a bufsize bytes from file descriptor \a fd.
546  * If at least \p strlen(\a pattern) bytes were received, the beginning of
547  * the received buffer is compared with \a pattern, ignoring case.
548  * \sa recv_buffer()
549  * \sa strncasecmp(3)
550  */
551 int recv_pattern(int fd, const char *pattern, size_t bufsize)
552 {
553         size_t len = strlen(pattern);
554         char *buf = para_malloc(bufsize + 1);
555         int ret = -E_RECV_PATTERN, n = recv_buffer(fd, buf, bufsize);
556
557         if (n < len)
558                 goto out;
559         if (strncasecmp(buf, pattern, len))
560                 goto out;
561         ret = 1;
562 out:
563         if (ret < 0)
564                 PARA_NOTICE_LOG("did not receive pattern '%s'\n", pattern);
565         free(buf);
566         return ret;
567 }