#include <signal.h>
#include <fnmatch.h>
+#include <openssl/rc4.h>
+
#include "server.cmdline.h"
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "string.h"
#include "afh.h"
#include "afs.h"
return strncmp(str1, str2, PARA_MIN(obj1->size, obj2->size));
}
-/*
- * write input from fd to dynamically allocated buffer,
- * but maximal max_size byte.
- */
-static int fd2buf(int fd, unsigned max_size, struct osl_object *obj)
-{
- const size_t chunk_size = 1024;
- size_t size = 2048, received = 0;
- int ret;
- char *buf = para_malloc(size);
-
- for (;;) {
- ret = recv_bin_buffer(fd, buf + received, chunk_size);
- if (ret <= 0)
- break;
- received += ret;
- if (received + chunk_size >= size) {
- size *= 2;
- ret = -E_INPUT_TOO_LARGE;
- if (size > max_size)
- break;
- buf = para_realloc(buf, size);
- }
- }
- obj->data = buf;
- obj->size = received;
- if (ret < 0)
- free(buf);
- return ret;
-}
-
-/**
- * Read data from a file descriptor, and send it to the afs process.
- *
- * \param fd File descriptor to read data from.
- * \param arg_obj Pointer to the arguments to \a f.
- * \param f The callback function.
- * \param max_len Don't read more than that many bytes from stdin.
- * \param result_handler See \ref send_callback_request.
- * \param private_result_data See \ref send_callback_request.
- *
- * This function is used by commands that wish to let para_server store
- * arbitrary data specified by the user (for instance the add_blob family of
- * commands). First, at most \a max_len bytes are read from \a fd, the result
- * is concatenated with the buffer given by \a arg_obj, and the combined buffer
- * is made available to the afs process via the callback method. See \ref
- * send_callback_request for details.
- *
- * \return Negative on errors, the return value of the underlying call to
- * send_callback_request() otherwise.
- */
-int stdin_command(int fd, struct osl_object *arg_obj, callback_function *f,
- unsigned max_len, callback_result_handler *result_handler,
- void *private_result_data)
-{
- struct osl_object query, stdin_obj;
- int ret;
-
- ret = send_buffer(fd, AWAITING_DATA_MSG);
- if (ret < 0)
- return ret;
- ret = fd2buf(fd, max_len, &stdin_obj);
- if (ret < 0)
- return ret;
- query.size = arg_obj->size + stdin_obj.size;
- query.data = para_malloc(query.size);
- memcpy(query.data, arg_obj->data, arg_obj->size);
- memcpy((char *)query.data + arg_obj->size, stdin_obj.data, stdin_obj.size);
- free(stdin_obj.data);
- ret = send_callback_request(f, &query, result_handler, private_result_data);
- free(query.data);
- return ret;
-}
-
static int pass_afd(int fd, char *buf, size_t size)
{
struct msghdr msg = {.msg_iov = NULL};
* Result handler for sending data to the para_client process.
*
* \param result The data to be sent.
- * \param fd_ptr Pointer to the file descriptor.
+ * \param private Pointer to rc4 context.
*
- * \return The return value of the underlying call to send_bin_buffer().
+ * \return The return value of the underlying call to rc4_send_bin_buffer().
*
- * \sa \ref callback_result_handler.
+ * \sa \ref callback_result_handler, \ref rc4_send_bin_buffer().
*/
-int send_result(struct osl_object *result, void *fd_ptr)
+int rc4_send_result(struct osl_object *result, void *private)
{
- int fd = *(int *)fd_ptr;
+ struct rc4_context *rc4c = private;
+
if (!result->size)
return 1;
- return send_bin_buffer(fd, result->data, result->size);
+ return rc4_send_bin_buffer(rc4c, result->data, result->size);
}
-int com_select(int fd, int argc, char * const * const argv)
+int com_select(struct rc4_context *rc4c, int argc, char * const * const argv)
{
struct osl_object query;
query.data = argv[1];
query.size = strlen(argv[1]) + 1;
return send_callback_request(com_select_callback, &query,
- &send_result, &fd);
+ &rc4_send_result, rc4c);
}
static void init_admissible_files(char *arg)
free(buf);
}
-int com_init(int fd, int argc, char * const * const argv)
+int com_init(struct rc4_context *rc4c, int argc, char * const * const argv)
{
int i, j, ret;
uint32_t table_mask = (1 << (NUM_AFS_TABLES + 1)) - 1;
return -E_BAD_TABLE_NAME;
}
}
- ret = send_callback_request(create_tables_callback, &query, &send_result, &fd);
+ ret = send_callback_request(create_tables_callback, &query,
+ rc4_send_result, rc4c);
if (ret < 0)
- return send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ return rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
CHECK_PLAYLISTS = 4
};
-int com_check(int fd, int argc, char * const * const argv)
+int com_check(struct rc4_context *rc4c, int argc, char * const * const argv)
{
unsigned flags = 0;
int i, ret;
if (!flags)
flags = ~0U;
if (flags & CHECK_AFT) {
- ret = send_callback_request(aft_check_callback, NULL, send_result, &fd);
+ ret = send_callback_request(aft_check_callback, NULL,
+ rc4_send_result, rc4c);
if (ret < 0)
return ret;
}
if (flags & CHECK_PLAYLISTS) {
- ret = send_callback_request(playlist_check_callback, NULL, send_result, &fd);
+ ret = send_callback_request(playlist_check_callback,
+ NULL, rc4_send_result, rc4c);
if (ret < 0)
return ret;
}
if (flags & CHECK_MOODS) {
- ret = send_callback_request(mood_check_callback, NULL, send_result, &fd);
+ ret = send_callback_request(mood_check_callback, NULL,
+ rc4_send_result, rc4c);
if (ret < 0)
return ret;
}
HC: Prototypes for the commands of the audio file selector.
CC: Array of commands for the audio file selector.
AT: server_command
-IN: para error string afh afs server list user_list
+SI: openssl/rc4
+IN: para error crypt command string afh afs server list user_list
SN: list of afs commands
TM: mood lyr img pl
---
---
N: lsatt
P: AFS_READ
-D: List attributes
+D: List attributes.
U: lsatt [-i] [-l] [-r] [pattern]
H: Print the list of all defined attributes which match the
H: given pattern. If no pattern is given, the full list is
---
T: add
N: add@member@
-O: int com_add@member@(int fd, int argc, char * const * const argv);
+O: int com_add@member@(struct rc4_context *rc4c, int argc, char * const * const argv);
P: AFS_READ | AFS_WRITE
D: Read data from stdin and add it as a blob to the @member@ table.
U: add@member@ @member@_name
---
T: cat
N: cat@member@
-O: int com_cat@member@(int fd, int argc, char * const * const argv);
+O: int com_cat@member@(struct rc4_context *rc4c, int argc, char * const * const argv);
P: AFS_READ
D: Dump the contents of a blob of type @member@ to stdout.
U: cat@member@ @member@_name
---
T: ls
N: ls@member@
-O: int com_ls@member@(int fd, int argc, char * const * const argv);
+O: int com_ls@member@(struct rc4_context *rc4c, int argc, char * const * const argv);
P: AFS_READ
D: List blobs of type @member@ matching a pattern.
U: ls@member@ [-i] [-l] [-r] [pattern]
---
T: rm
N: rm@member@
-O: int com_rm@member@(int fd, int argc, char * const * const argv);
+O: int com_rm@member@(struct rc4_context *rc4c, int argc, char * const * const argv);
P: AFS_READ | AFS_WRITE
D: Remove blob(s) of type @member@ from the @member@ table.
U: rm@member@ pattern...
---
T: mv
N: mv@member@
-O: int com_mv@member@(int fd, int argc, char * const * const argv);
+O: int com_mv@member@(struct rc4_context *rc4c, int argc, char * const * const argv);
P: AFS_READ | AFS_WRITE
D: Rename a blob of type @member@.
U: mv@member@ old_@member@_name new_@member@_name
* \sa \ref send_callback_request().
*/
typedef int callback_result_handler(struct osl_object *result, void *private);
-int send_result(struct osl_object *result, void *fd_ptr);
+int rc4_send_result(struct osl_object *result, void *private);
int pass_buffer_as_shm(char *buf, size_t size, void *fd_ptr);
__noreturn void afs_init(uint32_t cookie, int socket_fd);
int send_standard_callback_request(int argc, char * const * const argv,
callback_function *f, callback_result_handler *result_handler,
void *private_result_data);
-int stdin_command(int fd, struct osl_object *arg_obj, callback_function *f,
- unsigned max_len, callback_result_handler *result_handler,
- void *private_result_data);
int string_compare(const struct osl_object *obj1, const struct osl_object *obj2);
int for_each_matching_row(struct pattern_match_data *pmd);
/** \file aft.c Audio file table functions. */
#include <dirent.h> /* readdir() */
+#include <openssl/rc4.h>
+
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "string.h"
#include <sys/mman.h>
#include <fnmatch.h>
/*
* TODO: flags -h (sort by hash)
*/
-int com_ls(int fd, int argc, char * const * const argv)
+int com_ls(struct rc4_context *rc4c, int argc, char * const * const argv)
{
int i, ret;
unsigned flags = 0;
opts.mode = mode;
opts.num_patterns = argc - i;
ret = send_option_arg_callback_request(&query, opts.num_patterns,
- argv + i, com_ls_callback, send_result, &fd);
+ argv + i, com_ls_callback, rc4_send_result, rc4c);
return ret;
}
/** Used by com_add(). */
struct private_add_data {
- /** The socket file descriptor. */
- int fd;
+ /** The socket file descriptor, including rc4 keys. */
+ struct rc4_context *rc4c;
/** The given add flags. */
uint32_t flags;
};
ret = 1;
if (pb && (pad->flags & ADD_FLAG_LAZY)) { /* lazy is really cheap */
if (pad->flags & ADD_FLAG_VERBOSE)
- send_ret = send_va_buffer(pad->fd, "lazy-ignore: %s\n", path);
+ send_ret = rc4_send_va_buffer(pad->rc4c,
+ "lazy-ignore: %s\n", path);
goto out_free;
}
/* We still want to add this file. Compute its hash. */
ret = 1;
if (pb && hs && hs == pb && !(pad->flags & ADD_FLAG_FORCE)) {
if (pad->flags & ADD_FLAG_VERBOSE)
- send_ret = send_va_buffer(pad->fd,
+ send_ret = rc4_send_va_buffer(pad->rc4c,
"%s exists, not forcing update\n", path);
goto out_unmap;
}
munmap(map.data, map.size);
close(fd);
if (pad->flags & ADD_FLAG_VERBOSE) {
- send_ret = send_va_buffer(pad->fd, "adding %s\n", path);
+ send_ret = rc4_send_va_buffer(pad->rc4c, "adding %s\n", path);
if (send_ret < 0)
goto out_free;
}
save_add_callback_buffer(hash, path, afhi_ptr, pad->flags, format_num, &obj);
/* Ask afs to consider this entry for adding. */
- ret = send_callback_request(com_add_callback, &obj, send_result, &pad->fd);
+ ret = send_callback_request(com_add_callback, &obj, rc4_send_result, pad->rc4c);
goto out_free;
out_unmap:
munmap(map.data, map.size);
out_free:
if (ret < 0 && send_ret >= 0)
- send_ret = send_va_buffer(pad->fd, "failed to add %s (%s)\n", path,
- para_strerror(-ret));
+ send_ret = rc4_send_va_buffer(pad->rc4c,
+ "failed to add %s (%s)\n", path, para_strerror(-ret));
free(obj.data);
if (afhi_ptr) {
free(afhi_ptr->chunk_table);
return send_ret;
}
-int com_add(int fd, int argc, char * const * const argv)
+int com_add(struct rc4_context *rc4c, int argc, char * const * const argv)
{
int i, ret;
- struct private_add_data pad = {.fd = fd, .flags = 0};
+ struct private_add_data pad = {.rc4c = rc4c, .flags = 0};
struct stat statbuf;
for (i = 1; i < argc; i++) {
char *path;
ret = verify_path(argv[i], &path);
if (ret < 0) {
- ret = send_va_buffer(fd, "%s: %s\n", argv[i],
+ ret = rc4_send_va_buffer(rc4c, "%s: %s\n", argv[i],
para_strerror(-ret));
if (ret < 0)
return ret;
}
ret = stat(path, &statbuf);
if (ret < 0) {
- ret = send_va_buffer(fd, "failed to stat %s (%s)\n", path,
+ ret = rc4_send_va_buffer(rc4c, "failed to stat %s (%s)\n", path,
strerror(errno));
free(path);
if (ret < 0)
else
ret = add_one_audio_file(path, &pad);
if (ret < 0) {
- send_va_buffer(fd, "%s: %s\n", path, para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s: %s\n", path, para_strerror(-ret));
free(path);
return ret;
}
free(tad.pb.buf);
}
-int com_touch(int fd, int argc, char * const * const argv)
+int com_touch(struct rc4_context *rc4c, int argc, char * const * const argv)
{
struct com_touch_options cto = {
.num_played = -1,
if (i >= argc)
return -E_AFT_SYNTAX;
ret = send_option_arg_callback_request(&query, argc - i,
- argv + i, com_touch_callback, send_result, &fd);
+ argv + i, com_touch_callback, rc4_send_result, rc4c);
if (ret < 0)
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
}
/* TODO options: -r (recursive) */
-int com_rm(int fd, int argc, char * const * const argv)
+int com_rm(struct rc4_context *rc4c, int argc, char * const * const argv)
{
uint32_t flags = 0;
struct osl_object query = {.data = &flags, .size = sizeof(flags)};
if (i >= argc)
return -E_AFT_SYNTAX;
ret = send_option_arg_callback_request(&query, argc - i, argv + i,
- com_rm_callback, send_result, &fd);
+ com_rm_callback, rc4_send_result, rc4c);
if (ret < 0)
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
free(cad.pb.buf);
}
-int com_cpsi(int fd, int argc, char * const * const argv)
+int com_cpsi(struct rc4_context *rc4c, int argc, char * const * const argv)
{
unsigned flags = 0;
int i, ret;
if (!(flags & ~CPSI_FLAG_VERBOSE)) /* no copy flags given */
flags = ~(unsigned)CPSI_FLAG_VERBOSE | flags;
ret = send_option_arg_callback_request(&options, argc - i, argv + i,
- com_cpsi_callback, send_result, &fd);
+ com_cpsi_callback, rc4_send_result, rc4c);
if (ret < 0)
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
*/
/** \file attribute.c Attribute handling functions. */
+
+#include <openssl/rc4.h>
+
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "string.h"
#include "afh.h"
#include "afs.h"
free(laad.pb.buf);
}
-int com_lsatt(int fd, int argc, char * const * const argv)
+int com_lsatt(struct rc4_context *rc4c, int argc, char * const * const argv)
{
unsigned flags = 0;
struct osl_object options = {.data = &flags, .size = sizeof(flags)};
}
}
ret = send_option_arg_callback_request(&options, argc - i, argv + i,
- com_lsatt_callback, send_result, &fd);
+ com_lsatt_callback, rc4_send_result, rc4c);
if (!ret) {
if (argc > 1)
- ret = send_va_buffer(fd, "no matches\n");
+ ret = rc4_send_va_buffer(rc4c, "no matches\n");
} else if (ret < 0)
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
}
-int com_setatt(__a_unused int fd, int argc, char * const * const argv)
+int com_setatt(__a_unused struct rc4_context *rc4c, int argc, char * const * const argv)
{
if (argc < 3)
return -E_ATTR_SYNTAX;
free(pb.buf);
}
-int com_addatt(int fd, int argc, char * const * const argv)
+int com_addatt(struct rc4_context *rc4c, int argc, char * const * const argv)
{
int ret;
if (argc < 2)
return -E_ATTR_SYNTAX;
ret = send_standard_callback_request(argc - 1, argv + 1, com_addatt_callback,
- send_result, &fd);
+ rc4_send_result, rc4c);
if (ret < 0)
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
free(pb.buf);
}
-int com_mvatt(int fd, int argc, char * const * const argv)
+int com_mvatt(struct rc4_context *rc4c, int argc, char * const * const argv)
{
int ret;
if (argc != 3)
return -E_ATTR_SYNTAX;
ret = send_standard_callback_request(argc - 1, argv + 1, com_mvatt_callback,
- send_result, &fd);
+ rc4_send_result, rc4c);
if (ret < 0)
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
free(raad.pb.buf);
}
-int com_rmatt(int fd, int argc, char * const * const argv)
+int com_rmatt(struct rc4_context *rc4c, int argc, char * const * const argv)
{
int ret;
if (argc < 2)
return -E_ATTR_SYNTAX;
ret = send_standard_callback_request(argc - 1, argv + 1, com_rmatt_callback,
- send_result, &fd);
+ rc4_send_result, rc4c);
if (ret < 0)
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(rc4c, "%s\n", para_strerror(-ret));
return ret;
}
#include <sys/types.h>
#include <dirent.h>
#include <signal.h>
+#include <openssl/rc4.h>
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "audiod.cmdline.h"
#include "list.h"
#include "sched.h"
/** \file blob.c Macros and functions for blob handling. */
#include <fnmatch.h>
+#include <openssl/rc4.h>
+
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "string.h"
#include "afh.h"
#include "afs.h"
free(lbad.pb.buf);
}
-static int com_lsblob(callback_function *f, int fd, int argc, char * const * const argv)
+static int com_lsblob(callback_function *f, struct rc4_context *rc4c, int argc, char * const * const argv)
{
uint32_t flags = 0;
struct osl_object options = {.data = &flags, .size = sizeof(flags)};
// if (argc > i)
// return -E_BLOB_SYNTAX;
return send_option_arg_callback_request(&options, argc - i,
- argv + i, f, send_result, &fd);
+ argv + i, f, rc4_send_result, rc4c);
}
static int cat_blob(struct osl_table *table, struct osl_row *row,
for_each_matching_row(&pmd);
}
-static int com_catblob(callback_function *f, int fd, int argc,
+static int com_catblob(callback_function *f, struct rc4_context *rc4c, int argc,
char * const * const argv)
{
if (argc < 2)
return -E_BLOB_SYNTAX;
- return send_standard_callback_request(argc - 1, argv + 1, f, send_result, &fd);
+ return send_standard_callback_request(argc - 1, argv + 1, f,
+ rc4_send_result, rc4c);
}
/** Used for removing rows from a blob table. */
free(rmbd.pb.buf);
}
-static int com_rmblob(callback_function *f, int fd, int argc,
+static int com_rmblob(callback_function *f, struct rc4_context *rc4c, int argc,
char * const * const argv)
{
if (argc < 2)
return -E_MOOD_SYNTAX;
return send_option_arg_callback_request(NULL, argc - 1, argv + 1, f,
- send_result, &fd);
+ rc4_send_result, rc4c);
}
static void com_addblob_callback(struct osl_table *table, __a_unused int fd,
PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
}
-static int com_addblob(callback_function *f, int fd, int argc,
+/*
+ * write input from fd to dynamically allocated buffer,
+ * but maximal max_size byte.
+ */
+static int fd2buf(struct rc4_context *rc4c, unsigned max_size, struct osl_object *obj)
+{
+ const size_t chunk_size = 1024;
+ size_t size = 2048, received = 0;
+ int ret;
+ char *buf = para_malloc(size);
+
+ for (;;) {
+ ret = rc4_recv_bin_buffer(rc4c, buf + received, chunk_size);
+ if (ret <= 0)
+ break;
+ received += ret;
+ if (received + chunk_size >= size) {
+ size *= 2;
+ ret = -E_INPUT_TOO_LARGE;
+ if (size > max_size)
+ break;
+ buf = para_realloc(buf, size);
+ }
+ }
+ obj->data = buf;
+ obj->size = received;
+ if (ret < 0)
+ free(buf);
+ return ret;
+}
+
+/*
+ * Read data from a file descriptor, and send it to the afs process.
+ *
+ * \param rc4c crypt context containing the file descriptor to read data from.
+ * \param arg_obj Pointer to the arguments to \a f.
+ * \param f The callback function.
+ * \param max_len Don't read more than that many bytes from stdin.
+ * \param result_handler See \ref send_callback_request.
+ * \param private_result_data See \ref send_callback_request.
+ *
+ * This function is used by commands that wish to let para_server store
+ * arbitrary data specified by the user (for instance the add_blob family of
+ * commands). First, at most \a max_len bytes are read and decrypted from the
+ * file descriptor given by \a rc4c. The result is concatenated with the buffer
+ * given by \a arg_obj, and the combined buffer is made available to the afs
+ * process via the callback method. See \ref send_callback_request for details.
+ *
+ * \return Negative on errors, the return value of the underlying call to
+ * send_callback_request() otherwise.
+ */
+static int stdin_command(struct rc4_context *rc4c, struct osl_object *arg_obj,
+ callback_function *f, unsigned max_len,
+ callback_result_handler *result_handler,
+ void *private_result_data)
+{
+ struct osl_object query, stdin_obj;
+ int ret;
+
+ ret = rc4_send_buffer(rc4c, AWAITING_DATA_MSG);
+ if (ret < 0)
+ return ret;
+ ret = fd2buf(rc4c, max_len, &stdin_obj);
+ if (ret < 0)
+ return ret;
+ query.size = arg_obj->size + stdin_obj.size;
+ query.data = para_malloc(query.size);
+ memcpy(query.data, arg_obj->data, arg_obj->size);
+ memcpy((char *)query.data + arg_obj->size, stdin_obj.data, stdin_obj.size);
+ free(stdin_obj.data);
+ ret = send_callback_request(f, &query, result_handler, private_result_data);
+ free(query.data);
+ return ret;
+}
+
+static int com_addblob(callback_function *f, struct rc4_context *rc4c, int argc,
char * const * const argv)
{
struct osl_object arg_obj;
return -E_BLOB_SYNTAX;
arg_obj.size = strlen(argv[1]) + 1;
arg_obj.data = (char *)argv[1];
- return stdin_command(fd, &arg_obj, f, 10 * 1024 * 1024, NULL, NULL);
+ return stdin_command(rc4c, &arg_obj, f, 10 * 1024 * 1024, NULL, NULL);
}
/* FIXME: Print output to client, not to log file */
PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
}
-static int com_mvblob(callback_function *f, __a_unused int fd,
+static int com_mvblob(callback_function *f, __a_unused struct rc4_context *rc4c,
int argc, char * const * const argv)
{
if (argc != 3)
{ \
return com_ ## cmd_name ## blob_callback(table_name ## _table, fd, query); \
} \
- int com_ ## cmd_name ## cmd_prefix(int fd, int argc, char * const * const argv) \
+ int com_ ## cmd_name ## cmd_prefix(struct rc4_context *rc4c, int argc, char * const * const argv) \
{ \
- return com_ ## cmd_name ## blob(com_ ## cmd_name ## cmd_prefix ## _callback, fd, argc, argv); \
+ return com_ ## cmd_name ## blob(com_ ## cmd_name ## cmd_prefix ## _callback, rc4c, argc, argv); \
}
static int blob_get_name_by_id(struct osl_table *table, uint32_t id,
/** \file client.c the client program used to connect to para_server */
+#include <openssl/rc4.h>
+
#include "para.h"
#include "list.h"
#include "sched.h"
+#include "crypt.h"
#include "client.cmdline.h"
#include "string.h"
#include "stdin.h"
struct client_task {
/** the state of the connection */
int status;
- /** the file descriptor */
- int fd;
+ /** The file descriptor and the rc4 keys. */
+ struct rc4_context rc4c;
/** the configuration (including the command) */
struct client_args_info conf;
/** the config file for client options */
char *key_file;
/** paraslash user name */
char *user;
- /** session key for receiving data */
- RC4_KEY rc4_recv_key;
- /** session key for sending data */
- RC4_KEY rc4_send_key;
/** the client task structure */
struct task task;
/** the buffer used for handshake and receiving */
#include <sys/types.h>
#include <dirent.h>
+#include <openssl/rc4.h>
#include "para.h"
#include "error.h"
#include "client.cmdline.h"
#include "client.h"
-/*
- * Rc4-encrypt data before sending.
- *
- * \param len The number of bytes to encrypt.
- * \param indata Pointer to the input data of length \a len to be encrypted.
- * \param outdata Result-pointer that holds the encrypted data.
- * \param private_data Contains the rc4 key.
- */
-static void rc4_send(unsigned long len, const unsigned char *indata,
- unsigned char *outdata, void *private_data)
-{
- struct client_task *ct = private_data;
- RC4(&ct->rc4_send_key, len, indata, outdata);
-}
-
-/*
- * Rc4-decrypt received data.
- *
- * Parameters are identical to those of rc4_send.
- */
-static void rc4_recv(unsigned long len, const unsigned char *indata,
- unsigned char *outdata, void *private_data)
-{
- struct client_task *ct = private_data;
- RC4(&ct->rc4_recv_key, len, indata, outdata);
-}
-
/**
* Close the connection to para_server and free all resources.
*
{
if (!ct)
return;
- if (ct->fd >= 0) {
- disable_crypt(ct->fd);
- close(ct->fd);
- }
+ if (ct->rc4c.fd >= 0)
+ close(ct->rc4c.fd);
free(ct->buf);
free(ct->user);
free(ct->config_file);
ct->check_r = 0;
ct->check_w = 0;
- if (ct->fd < 0)
+ if (ct->rc4c.fd < 0)
return;
switch (ct->status) {
case CL_CONNECTED:
case CL_SENT_AUTH:
case CL_SENT_CH_RESPONSE:
case CL_SENT_COMMAND:
- para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
+ para_fd_set(ct->rc4c.fd, &s->rfds, &s->max_fileno);
ct->check_r = 1;
return;
case CL_RECEIVED_WELCOME:
case CL_RECEIVED_CHALLENGE:
case CL_RECEIVED_PROCEED:
- para_fd_set(ct->fd, &s->wfds, &s->max_fileno);
+ para_fd_set(ct->rc4c.fd, &s->wfds, &s->max_fileno);
ct->check_w = 1;
return;
case CL_RECEIVING:
if (ct->loaded < CLIENT_BUFSIZE - 1) {
- para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
+ para_fd_set(ct->rc4c.fd, &s->rfds, &s->max_fileno);
ct->check_r = 1;
}
return;
return;
if (*ct->in_loaded) {
PARA_INFO_LOG("loaded: %zd\n", *ct->in_loaded);
- para_fd_set(ct->fd, &s->wfds, &s->max_fileno);
+ para_fd_set(ct->rc4c.fd, &s->wfds, &s->max_fileno);
ct->check_w = 1;
} else {
if (*ct->in_error) {
static ssize_t client_recv_buffer(struct client_task *ct)
{
- ssize_t ret = recv_buffer(ct->fd, ct->buf + ct->loaded,
- CLIENT_BUFSIZE - ct->loaded);
+ ssize_t ret;
+
+ if (ct->status < CL_RECEIVED_PROCEED)
+ ret = recv_buffer(ct->rc4c.fd, ct->buf + ct->loaded,
+ CLIENT_BUFSIZE - ct->loaded);
+ else
+ ret = rc4_recv_buffer(&ct->rc4c, ct->buf + ct->loaded,
+ CLIENT_BUFSIZE - ct->loaded);
if (!ret)
return -E_SERVER_EOF;
if (ret > 0)
struct client_task *ct = container_of(t, struct client_task, task);
t->error = 0;
- if (ct->fd < 0)
+ if (ct->rc4c.fd < 0)
return;
if (!ct->check_r && !ct->check_w)
return;
- if (ct->check_r && !FD_ISSET(ct->fd, &s->rfds))
+ if (ct->check_r && !FD_ISSET(ct->rc4c.fd, &s->rfds))
return;
- if (ct->check_w && !FD_ISSET(ct->fd, &s->wfds))
+ if (ct->check_w && !FD_ISSET(ct->rc4c.fd, &s->wfds))
return;
switch (ct->status) {
case CL_CONNECTED: /* receive welcome message */
case CL_RECEIVED_WELCOME: /* send auth command */
sprintf(ct->buf, "auth rc4 %s", ct->user);
PARA_INFO_LOG("--> %s\n", ct->buf);
- t->error = send_buffer(ct->fd, ct->buf);
+ t->error = send_buffer(ct->rc4c.fd, ct->buf);
if (t->error >= 0)
ct->status = CL_SENT_AUTH;
return;
return;
case CL_RECEIVED_CHALLENGE: /* send decrypted challenge */
PARA_INFO_LOG("--> %lu\n", ct->challenge_nr);
- t->error = send_va_buffer(ct->fd, "%s%lu", CHALLENGE_RESPONSE_MSG,
+ t->error = send_va_buffer(ct->rc4c.fd, "%s%lu", CHALLENGE_RESPONSE_MSG,
ct->challenge_nr);
if (t->error > 0)
ct->status = CL_SENT_CH_RESPONSE;
bytes_received - PROCEED_MSG_LEN - 1);
if (t->error < 0)
return;
- RC4_set_key(&ct->rc4_send_key, RC4_KEY_LEN, rc4_buf);
- RC4_set_key(&ct->rc4_recv_key, RC4_KEY_LEN, rc4_buf + RC4_KEY_LEN);
- enable_crypt(ct->fd, rc4_recv, rc4_send, ct);
+ RC4_set_key(&ct->rc4c.send_key, RC4_KEY_LEN, rc4_buf);
+ RC4_set_key(&ct->rc4c.recv_key, RC4_KEY_LEN, rc4_buf + RC4_KEY_LEN);
ct->status = CL_RECEIVED_PROCEED;
return;
}
}
command = para_strcat(command, EOC_MSG "\n");
PARA_DEBUG_LOG("--> %s\n", command);
- t->error = send_buffer(ct->fd, command);
+ t->error = rc4_send_buffer(&ct->rc4c, command);
free(command);
if (t->error > 0)
ct->status = CL_SENT_COMMAND;
return;
case CL_SENDING: /* FIXME: might block */
PARA_INFO_LOG("loaded: %zd\n", *ct->in_loaded);
- t->error = send_bin_buffer(ct->fd, ct->inbuf, *ct->in_loaded);
+ t->error = rc4_send_bin_buffer(&ct->rc4c, ct->inbuf, *ct->in_loaded);
if (t->error < 0)
return;
*ct->in_loaded = 0;
{
int ret;
- ct->fd = -1;
+ ct->rc4c.fd = -1;
ret = makesock(AF_UNSPEC, IPPROTO_TCP, 0, ct->conf.hostname_arg,
ct->conf.server_port_arg);
if (ret < 0)
return ret;
- ct->fd = ret;
+ ct->rc4c.fd = ret;
ct->status = CL_CONNECTED;
- ret = mark_fd_nonblocking(ct->fd);
+ ret = mark_fd_nonblocking(ct->rc4c.fd);
if (ret < 0)
goto err_out;
ct->task.pre_select = client_pre_select;
register_task(&ct->task);
return 1;
err_out:
- close(ct->fd);
- ct->fd = -1;
+ close(ct->rc4c.fd);
+ ct->rc4c.fd = -1;
return ret;
}
ct->buf = para_malloc(CLIENT_BUFSIZE);
*ct_ptr = ct;
- ct->fd = -1;
+ ct->rc4c.fd = -1;
ret = -E_CLIENT_SYNTAX;
if (client_cmdline_parser(argc, argv, &ct->conf))
goto out;
#include "para.h"
#include "error.h"
+#include "crypt.h"
+#include "command.h"
#include "server.cmdline.h"
#include "string.h"
#include "afh.h"
/** Commands including options must be shorter than this. */
#define MAX_COMMAND_LEN 32768
-static RC4_KEY rc4_recv_key;
-static RC4_KEY rc4_send_key;
static unsigned char rc4_buf[2 * RC4_KEY_LEN];
extern int mmd_mutex;
extern struct misc_meta_data *mmd;
extern struct sender senders[];
+static void init_rc4_keys(struct rc4_context *rcc)
+{
+ get_random_bytes_or_die(rc4_buf, 2 * RC4_KEY_LEN);
+ RC4_set_key(&rcc->recv_key, RC4_KEY_LEN, rc4_buf);
+ RC4_set_key(&rcc->send_key, RC4_KEY_LEN, rc4_buf + RC4_KEY_LEN);
+}
+
static void dummy(__a_unused int s)
{
}
return 1;
}
-int com_sender(int fd, int argc, char * const * argv)
+int com_sender(struct rc4_context *rc4c, int argc, char * const * argv)
{
int i, ret;
struct sender_command_data scd;
free(msg);
msg = tmp;
}
- ret = send_buffer(fd, msg);
+ ret = rc4_send_buffer(rc4c, msg);
free(msg);
return ret;
}
if (scd.sender_num < 0)
return ret;
msg = senders[scd.sender_num].help();
- ret = send_buffer(fd, msg);
+ ret = rc4_send_buffer(rc4c, msg);
free(msg);
return ret;
}
}
/* server info */
-int com_si(int fd, int argc, __a_unused char * const * argv)
+int com_si(struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
int i, ret;
char *ut;
sender_list = para_strcat(sender_list, " ");
}
ut = uptime_str();
- ret = send_va_buffer(fd, "up: %s\nplayed: %u\n"
+ ret = rc4_send_va_buffer(rc4c, "up: %s\nplayed: %u\n"
"server_pid: %d\n"
"afs_pid: %d\n"
"connections (active/accepted/total): %u/%u/%u\n"
}
/* version */
-int com_version(int fd, int argc, __a_unused char * const * argv)
+int com_version(struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
- return send_buffer(fd, VERSION_TEXT("server")
+ return rc4_send_buffer(rc4c, VERSION_TEXT("server")
"built: " BUILD_DATE "\n"
UNAME_RS ", " CC_VERSION "\n"
);
}
/* stat */
-int com_stat(int fd, int argc, char * const * argv)
+int com_stat(struct rc4_context *rc4c, int argc, char * const * argv)
{
int ret, num = 0;/* status will be printed that many
* times. num <= 0 means: print forever
mmd_dup(nmmd);
s = get_status(nmmd);
- ret = send_buffer(fd, s);
+ ret = rc4_send_buffer(rc4c, s);
free(s);
if (ret < 0)
goto out;
return ret;
}
-static int send_list_of_commands(int fd, struct server_command *cmd,
+static int send_list_of_commands(struct rc4_context *rc4c, struct server_command *cmd,
const char *handler)
{
int ret, i;
for (i = 1; cmd->name; cmd++, i++) {
char *perms = cmd_perms_itohuman(cmd->perms);
- ret = send_va_buffer(fd, "%s\t%s\t%s\t%s\n", cmd->name,
+ ret = rc4_send_va_buffer(rc4c, "%s\t%s\t%s\t%s\n", cmd->name,
handler,
perms,
cmd->description);
}
/* help */
-int com_help(int fd, int argc, char * const * argv)
+int com_help(struct rc4_context *rc4c, int argc, char * const * argv)
{
struct server_command *cmd;
char *perms, *handler;
if (argc < 2) {
/* no argument given, print list of commands */
- if ((ret = send_list_of_commands(fd, server_cmds, "server")) < 0)
+ if ((ret = send_list_of_commands(rc4c, server_cmds, "server")) < 0)
return ret;
- return send_list_of_commands(fd, afs_cmds, "afs");
+ return send_list_of_commands(rc4c, afs_cmds, "afs");
}
/* argument given for help */
cmd = get_cmd_ptr(argv[1], &handler);
return -E_BAD_CMD;
}
perms = cmd_perms_itohuman(cmd->perms);
- ret = send_va_buffer(fd,
+ ret = rc4_send_va_buffer(rc4c,
"%s - %s\n\n"
"handler: %s\n"
"permissions: %s\n"
}
/* hup */
-int com_hup(__a_unused int fd, int argc, __a_unused char * const * argv)
+int com_hup(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
}
/* term */
-int com_term(__a_unused int fd, int argc, __a_unused char * const * argv)
+int com_term(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
return 1;
}
-int com_play(__a_unused int fd, int argc, __a_unused char * const * argv)
+int com_play(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
}
/* stop */
-int com_stop(__a_unused int fd, int argc, __a_unused char * const * argv)
+int com_stop(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
}
/* pause */
-int com_pause(__a_unused int fd, int argc, __a_unused char * const * argv)
+int com_pause(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
}
/* next */
-int com_next(__a_unused int fd, int argc, __a_unused char * const * argv)
+int com_next(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
}
/* nomore */
-int com_nomore(__a_unused int fd, int argc, __a_unused char * const * argv)
+int com_nomore(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
{
if (argc != 1)
return -E_COMMAND_SYNTAX;
}
/* ff */
-int com_ff(__a_unused int fd, int argc, char * const * argv)
+int com_ff(__a_unused struct rc4_context *rc4c, int argc, char * const * argv)
{
long promille;
int ret, backwards = 0;
}
/* jmp */
-int com_jmp(__a_unused int fd, int argc, char * const * argv)
+int com_jmp(__a_unused struct rc4_context *rc4c, int argc, char * const * argv)
{
long unsigned int i;
int ret;
return get_cmd_ptr(buf, NULL);
}
-static void init_rc4_keys(void)
-{
- get_random_bytes_or_die(rc4_buf, 2 * RC4_KEY_LEN);
- PARA_DEBUG_LOG("rc4 keys initialized (%u:%u)\n",
- (unsigned char) rc4_buf[0],
- (unsigned char) rc4_buf[RC4_KEY_LEN]);
- RC4_set_key(&rc4_recv_key, RC4_KEY_LEN, rc4_buf);
- RC4_set_key(&rc4_send_key, RC4_KEY_LEN, rc4_buf + RC4_KEY_LEN);
-}
-
-static void rc4_recv(unsigned long len, const unsigned char *indata,
- unsigned char *outdata, __a_unused void *private_data)
-{
- RC4(&rc4_recv_key, len, indata, outdata);
-}
-
-static void rc4_send(unsigned long len, const unsigned char *indata,
- unsigned char *outdata, __a_unused void *private_data)
-{
- RC4(&rc4_send_key, len, indata, outdata);
-}
-
-static int read_command(int fd, char **result)
+static int read_command(struct rc4_context *rc4c, char **result)
{
int ret;
char buf[4096];
size_t numbytes;
char *p;
- ret = recv_buffer(fd, buf, sizeof(buf));
+ ret = rc4_recv_buffer(rc4c, buf, sizeof(buf));
if (ret < 0)
goto out;
if (!ret)
char **argv = NULL;
char *p, *command = NULL;
size_t numbytes;
+ struct rc4_context rc4c = {.fd = fd};
reset_signals();
/* we need a blocking fd here as recv() might return EAGAIN otherwise. */
/* auth successful, send 'Proceed' message */
PARA_INFO_LOG("good auth for %s (%lu)\n", u->name, challenge_nr);
sprintf(buf, "%s", PROCEED_MSG);
- init_rc4_keys();
+ init_rc4_keys(&rc4c);
/* Should we also encrypt the proceed message? */
ret = para_encrypt_buffer(u->rsa, rc4_buf, 2 * RC4_KEY_LEN,
(unsigned char *)buf + PROCEED_MSG_LEN + 1);
ret = send_bin_buffer(fd, buf, numbytes);
if (ret < 0)
goto net_err;
- enable_crypt(fd, rc4_recv, rc4_send, NULL);
- ret = read_command(fd, &command);
+ ret = read_command(&rc4c, &command);
if (ret == -E_COMMAND_SYNTAX)
goto err_out;
if (ret < 0)
argc = split_args(command, &argv, "\n");
PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cmd->name, u->name,
peername);
- ret = cmd->handler(fd, argc, argv);
+ ret = cmd->handler(&rc4c, argc, argv);
mutex_lock(mmd_mutex);
mmd->num_commands++;
mutex_unlock(mmd_mutex);
if (ret >= 0)
goto out;
err_out:
- send_va_buffer(fd, "%s\n", para_strerror(-ret));
+ rc4_send_va_buffer(&rc4c, "%s\n", para_strerror(-ret));
net_err:
PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
out:
--- /dev/null
+/** \file command.h The structure of server and afs commands. */
+
+/**
+ * Defines one command of para_server.
+ */
+struct server_command {
+ /** The name of the command. */
+ const char *name;
+ /** Pointer to the function that handles the command. */
+ int (*handler)(struct rc4_context *, int, char * const * const);
+ /** The privileges a user must have to execute this command. */
+ unsigned int perms;
+ /** One-line description of the command. */
+ const char *description;
+ /** Summary of the command line options. */
+ const char *usage;
+ /** The long help text. */
+ const char *help;
+};
AT:)
array_type="$value"
;;
+ SI:)
+ for i in $value; do
+ system_includes="$system_includes
+#include <$i.h>"
+ done
+ ;;
IN:)
for i in $value; do
includes="$includes
echo '/**'
echo " * $desc_txt"
echo ' *'
- echo ' * \param fd The file descriptor to send output to.'
+ echo ' * \param rc4c The rc4 crypt context.'
if test $line_handler -eq 0; then
echo ' * \param argc The number of arguments.'
echo ' * \param argv The argument vector.'
com_c_file()
{
echo "/** \file $output_file.c $c_file_comment */"
+ echo "$system_includes"
echo "$includes"
echo "struct $array_type $array_name[] = {"
while : ; do
/** \file crypt.c openssl-based RSA encryption/decryption routines */
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/rc4.h>
+
#include "para.h"
#include "error.h"
#include "string.h"
#include "crypt.h"
-#include <openssl/rand.h>
-#include <openssl/err.h>
-
+#include "fd.h"
/**
* Fill a buffer with random content.
*
return ret;
}
+/**
+ * Encrypt and send a buffer.
+ *
+ * \param rc4c The rc4 crypt context.
+ * \param buf The buffer to send.
+ * \param len The size of \a buf in bytes.
+ *
+ * \return The return value of the underyling call to write_all().
+ *
+ * \sa \ref write_all(), RC4(3).
+ */
+int rc4_send_bin_buffer(struct rc4_context *rc4c, const char *buf, size_t len)
+{
+ int ret;
+ unsigned char *tmp;
+
+ assert(len);
+ tmp = para_malloc(len);
+ RC4(&rc4c->send_key, len, (const unsigned char *)buf, tmp);
+ ret = write_all(rc4c->fd, (char *)tmp, &len);
+ free(tmp);
+ return ret;
+}
+
+/**
+ * Encrypt and send a \p NULL-terminated buffer.
+ *
+ * \param rc4c The rc4 crypt context.
+ * \param buf The buffer to send.
+ *
+ * \return The return value of the underyling call to rc4_send_bin_buffer().
+ */
+int rc4_send_buffer(struct rc4_context *rc4c, const char *buf)
+{
+ return rc4_send_bin_buffer(rc4c, buf, strlen(buf));
+}
+
+/**
+ * Format, encrypt and send a buffer.
+ *
+ * \param rc4c The rc4 crypt context.
+ * \param fmt A format string.
+ *
+ * \return The return value of the underyling call to rc4_send_buffer().
+ */
+__printf_2_3 int rc4_send_va_buffer(struct rc4_context *rc4c, const char *fmt, ...)
+{
+ char *msg;
+ int ret;
+
+ PARA_VSPRINTF(fmt, msg);
+ ret = rc4_send_buffer(rc4c, msg);
+ free(msg);
+ return ret;
+}
+
+/**
+ * Receive a buffer and decrypt it.
+ *
+ * \param rc4c The rc4 crypt context.
+ * \param buf The buffer to write the decrypted data to.
+ * \param size The size of \a buf.
+ *
+ * \return The number of bytes received on success, negative on errors, zero if
+ * the peer has performed an orderly shutdown.
+ *
+ * \sa recv(2), RC4(3).
+ */
+int rc4_recv_bin_buffer(struct rc4_context *rc4c, char *buf, size_t size)
+{
+ unsigned char *tmp = para_malloc(size);
+ ssize_t ret = recv(rc4c->fd, tmp, size, 0);
+
+ if (ret > 0)
+ RC4(&rc4c->recv_key, ret, tmp, (unsigned char *)buf);
+ else if (ret < 0)
+ ret = -ERRNO_TO_PARA_ERROR(errno);
+ free(tmp);
+ return ret;
+}
+
+/**
+ * Receive a buffer, decrypt it and write terminating NULL byte.
+ *
+ * \param rc4c The rc4 crypt context.
+ * \param buf The buffer to write the decrypted data to.
+ * \param size The size of \a buf.
+ *
+ * Read at most \a size - 1 bytes from file descriptor given by \a rc4c,
+ * decrypt the received data and write a NULL byte at the end of the decrypted
+ * data.
+ *
+ * \return The return value of the underlying call to \ref
+ * rc4_recv_bin_buffer().
+ */
+int rc4_recv_buffer(struct rc4_context *rc4c, char *buf, size_t size)
+{
+ int n;
+
+ assert(size);
+ n = rc4_recv_bin_buffer(rc4c, buf, size - 1);
+ if (n >= 0)
+ buf[n] = '\0';
+ else
+ *buf = '\0';
+ return n;
+}
void get_random_bytes_or_die(unsigned char *buf, int num);
void init_random_seed_or_die(void);
+struct rc4_context {
+ int fd;
+ RC4_KEY recv_key;
+ RC4_KEY send_key;
+};
+int rc4_send_bin_buffer(struct rc4_context *rc4c, const char *buf, size_t len);
+int rc4_send_buffer(struct rc4_context *rc4c, const char *buf);
+__printf_2_3 int rc4_send_va_buffer(struct rc4_context *rc4c, const char *fmt, ...);
+int rc4_recv_bin_buffer(struct rc4_context *rcc, char *buf, size_t size);
+int rc4_recv_buffer(struct rc4_context *rcc, char *buf, size_t size);
+
/** \cond used to distinguish between loading of private/public key */
#define LOAD_PUBLIC_KEY 0
#define LOAD_PRIVATE_KEY 1
#include "error.h"
#include "string.h"
#include "fd.h"
-#include "crypt.h"
/** Grab clients that are not yet attached to a filter node. */
struct list_head inactive_grab_client_list;
#include <dirent.h>
#include <regex.h>
+#include <openssl/rc4.h>
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "net.h"
#include "string.h"
#include "fd.h"
-
-/** Information about one encrypted connection. */
-struct crypt_data {
- /** Function used to decrypt received data. */
- crypt_function *recv;
- /** Function used to encrypt data to be sent. */
- crypt_function *send;
- /**
- * Context-dependent data (crypt keys), passed verbatim to the above
- * crypt functions.
- */
- void *private_data;
-};
-/** Array holding per fd crypt data. */
-static struct crypt_data *crypt_data_array;
-/** Current size of the crypt data array. */
-static unsigned cda_size = 0;
-
-/**
- * Activate encryption for one file descriptor.
- *
- * \param fd The file descriptor.
- * \param recv_f The function used for decrypting received data.
- * \param send_f The function used for encrypting before sending.
- * \param private_data User data supplied by the caller.
- */
-void enable_crypt(int fd, crypt_function *recv_f, crypt_function *send_f,
- void *private_data)
-{
- if (fd + 1 > cda_size) {
- crypt_data_array = para_realloc(crypt_data_array,
- (fd + 1) * sizeof(struct crypt_data));
- memset(crypt_data_array + cda_size, 0,
- (fd + 1 - cda_size) * sizeof(struct crypt_data));
- cda_size = fd + 1;
- }
- crypt_data_array[fd].recv = recv_f;
- crypt_data_array[fd].send = send_f;
- crypt_data_array[fd].private_data = private_data;
- PARA_INFO_LOG("rc4 encryption activated for fd %d\n", fd);
-}
-
-/**
- * Deactivate encryption for a given fd.
- *
- * \param fd The file descriptor.
- *
- * This must be called if and only if \p fd was activated via enable_crypt().
- */
-void disable_crypt(int fd)
-{
- if (cda_size < fd + 1)
- return;
- crypt_data_array[fd].recv = NULL;
- crypt_data_array[fd].send = NULL;
- crypt_data_array[fd].private_data = NULL;
-}
-
/**
* Match string as a candidate IPv4 address.
*
}
/**
- * Encrypt and send a binary buffer.
+ * Send a binary buffer.
*
* \param fd The file descriptor.
- * \param buf The buffer to be encrypted and sent.
+ * \param buf The buffer to be sent.
* \param len The length of \a buf.
*
- * Check if encryption is available. If yes, encrypt the given buffer. Send
- * out the buffer, encrypted or not, and try to resend the remaining part in
- * case of short writes.
+ * Send out the buffer and try to resend the remaining part in case of short
+ * writes.
*
* \return Standard.
*/
int send_bin_buffer(int fd, const char *buf, size_t len)
{
- int ret;
- crypt_function *cf = NULL;
-
if (!len)
PARA_CRIT_LOG("len == 0\n");
- if (fd + 1 <= cda_size)
- cf = crypt_data_array[fd].send;
- if (cf) {
- void *private = crypt_data_array[fd].private_data;
- /* RC4 may write more than len to the output buffer */
- unsigned char *outbuf = para_malloc(ROUND_UP(len, 8));
- (*cf)(len, (unsigned char *)buf, outbuf, private);
- ret = write_all(fd, (char *)outbuf, &len);
- free(outbuf);
- } else
- ret = write_all(fd, buf, &len);
- return ret;
+ return write_all(fd, buf, &len);
}
/**
- * Encrypt and send null terminated buffer.
+ * Send a \p NULL-terminated buffer.
*
* \param fd The file descriptor.
* \param buf The null-terminated buffer to be send.
return send_bin_buffer(fd, buf, strlen(buf));
}
-
/**
- * Send and encrypt a buffer given by a format string.
+ * Send a buffer given by a format string.
*
* \param fd The file descriptor.
* \param fmt A format string.
}
/**
- * Receive and decrypt.
+ * Receive data from a file descriptor.
*
* \param fd The file descriptor.
- * \param buf The buffer to write the decrypted data to.
+ * \param buf The buffer to write the data to.
* \param size The size of \a buf.
*
- * Receive at most \a size bytes from file descriptor \a fd. If encryption is
- * available, decrypt the received buffer.
+ * Receive at most \a size bytes from file descriptor \a fd.
*
- * \return The number of bytes received on success, negative on errors.
+ * \return The number of bytes received on success, negative on errors, zero if
+ * the peer has performed an orderly shutdown.
*
- * \sa recv(2)
+ * \sa recv(2).
*/
__must_check int recv_bin_buffer(int fd, char *buf, size_t size)
{
ssize_t n;
- crypt_function *cf = NULL;
-
- if (fd + 1 <= cda_size)
- cf = crypt_data_array[fd].recv;
- if (cf) {
- unsigned char *tmp = para_malloc(size);
- void *private = crypt_data_array[fd].private_data;
- n = recv(fd, tmp, size, 0);
- if (n > 0) {
- size_t numbytes = n;
- unsigned char *b = (unsigned char *)buf;
- (*cf)(numbytes, tmp, b, private);
- }
- free(tmp);
- } else
- n = recv(fd, buf, size, 0);
+
+ n = recv(fd, buf, size, 0);
if (n == -1)
return -ERRNO_TO_PARA_ERROR(errno);
return n;
}
/**
- * Receive, decrypt and write terminating NULL byte.
+ * Receive and write terminating NULL byte.
*
* \param fd The file descriptor.
- * \param buf The buffer to write the decrypted data to.
+ * \param buf The buffer to write the data to.
* \param size The size of \a buf.
*
- * Read and decrypt at most \a size - 1 bytes from file descriptor \a fd and
+ * Read at most \a size - 1 bytes from file descriptor \a fd and
* write a NULL byte at the end of the received data.
*
* \return The return value of the underlying call to \a recv_bin_buffer().
extern char *local_name(int sockfd);
extern char *remote_name(int sockfd);
-/** used to crypt the communication between para_server and para_client */
-typedef void crypt_function(unsigned long len,
- const unsigned char *indata, unsigned char *outdata, void *private_data);
-
-int send_buffer(int, const char *);
int send_bin_buffer(int, const char *, size_t);
+int send_buffer(int, const char *);
__printf_2_3 int send_va_buffer(int fd, const char *fmt, ...);
-int recv_buffer(int fd, char *buf, size_t size);
+
int recv_bin_buffer(int fd, char *buf, size_t size);
+int recv_buffer(int fd, char *buf, size_t size);
+
int para_accept(int, void *addr, socklen_t size);
int create_local_socket(const char *name, struct sockaddr_un *unix_addr,
mode_t mode);
int recv_cred_buffer(int, char *, size_t);
ssize_t send_cred_buffer(int, char*);
int recv_pattern(int fd, const char *pattern, size_t bufsize);
-void enable_crypt(int fd, crypt_function *recv_f, crypt_function *send_f,
- void *private_data);
-void disable_crypt(int fd);
#include <signal.h>
#include <dirent.h>
#include <sys/time.h>
+#include <openssl/rc4.h>
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "server.cmdline.h"
#include "afh.h"
#include "string.h"
HC: prototypes for the server command handlers
CC: array of server commands
AT: server_command
-IN: para error string afh afs server list user_list
+SI: openssl/rc4
+IN: para error crypt command string afh afs server list user_list
SN: list of server commands
---
N: ff
/** The maximum length of the host component in an URL */
#define MAX_HOSTLEN 256
-/**
- * Defines one command of para_server.
- */
-struct server_command {
- /** The name of the command. */
- const char *name;
- /** Pointer to the function that handles the command. */
- int (*handler)(int, int, char * const * const);
- /** The privileges a user must have to execute this command. */
- unsigned int perms;
- /** One-line description of the command. */
- const char *description;
- /** Summary of the command line options. */
- const char *usage;
- /** The long help text. */
- const char *help;
-};
/** Holds the arguments for the para_server's sender command. */
struct sender_command_data{
#include <sys/types.h>
#include <dirent.h>
+#include <openssl/rc4.h>
#include "para.h"
#include "error.h"
+#include "crypt.h"
#include "fd.h"
#include "string.h"
#include "list.h"
/** \file user_list.h exported functions from user_list.c */
-#include "crypt.h"
-
/**
* permission flags that can be set individually for any server command
*