X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=command.c;h=516a62fe520887e1b015ff8e159b8027dd86b232;hp=de56ce8296fdf5d451c5a16b7cd08f2cddc47e1a;hb=5f956b99f8f30642227686dd9341950f011512ae;hpb=77aa550660c490ef33bc42f7185516708908d022 diff --git a/command.c b/command.c index de56ce82..516a62fe 100644 --- a/command.c +++ b/command.c @@ -1,26 +1,17 @@ /* * Copyright (C) 1997-2007 Andre Noll * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file command.c does client authentication and executes server commands */ #include /* gettimeofday */ +#include "para.h" /* gettimeofday */ + #include "server.cmdline.h" -#include "afs.h" +#include "afs_common.h" +#include "afh.h" #include "server.h" #include "vss.h" #include "send.h" @@ -31,11 +22,13 @@ #include "daemon.h" #include "string.h" #include "fd.h" +#include "list.h" #include "user_list.h" #include "server_command_list.h" +#include "afs_command_list.h" /** commands including options must be shorter than this */ -#define MAX_COMMAND_LEN 4096 +#define MAX_COMMAND_LEN 32768 static RC4_KEY rc4_recv_key; static RC4_KEY rc4_send_key; @@ -151,7 +144,7 @@ static char *get_status(struct misc_meta_data *nmmd) bar = para_basename(nmmd->filename); gettimeofday(&now, NULL); ret = make_message( - "%s:%lu\n" "%s:%s\n" "%s:%i\n" "%s:%u\n" + "%s:%zu\n" "%s:%s\n" "%s:%lu\n" "%s:%u\n" "%s:%s\n" "%s:%s\n" "%s:%s\n" "%s:%s\n" "%s:%li\n" "%s:%s\n" "%s" "%s" "%s:%s\n" "%s:%lu.%lu\n" "%s:%lu.%lu\n", @@ -186,7 +179,7 @@ static char *get_status(struct misc_meta_data *nmmd) return ret; } -static int check_sender_args(int argc, char **argv, struct sender_command_data *scd) +static int check_sender_args(int argc, char * const * argv, struct sender_command_data *scd) { int i; /* this has to match sender.h */ @@ -252,7 +245,7 @@ static int check_sender_args(int argc, char **argv, struct sender_command_data * return 1; } -int com_sender(int fd, int argc, char **argv) +int com_sender(int fd, int argc, char * const * argv) { int i, ret; struct sender_command_data scd; @@ -294,7 +287,7 @@ int com_sender(int fd, int argc, char **argv) } /* server info */ -int com_si(int fd, int argc, __a_unused char **argv) +int com_si(int fd, int argc, __a_unused char * const * argv) { int i, ret; char *ut; @@ -343,7 +336,7 @@ int com_si(int fd, int argc, __a_unused char **argv) } /* version */ -int com_version(int fd, int argc, __a_unused char **argv) +int com_version(int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -354,7 +347,7 @@ int com_version(int fd, int argc, __a_unused char **argv) } /* sc */ -int com_sc(int fd, int argc, char **argv) +int com_sc(int fd, int argc, char * const * argv) { char *name = NULL; int ret, old = 0, count = -1; /* print af change forever */ @@ -382,7 +375,7 @@ repeat: } /* sb */ -int com_sb(int fd, int argc, char **argv) +int com_sb(int fd, int argc, char * const * argv) { char *sb; int ret, nr = -1; /* status bar will be printed that many @@ -409,7 +402,7 @@ int com_sb(int fd, int argc, char **argv) } /* stat */ -int com_stat(int fd, int argc, char **argv) +int com_stat(int fd, int argc, char * const * argv) { int ret, num = 0;/* status will be printed that many * times. num <= 0 means: print forever @@ -459,7 +452,7 @@ static int send_list_of_commands(int fd, struct server_command *cmd, } /* always returns string that must be freed by the caller in handler */ -static struct server_command *get_cmd_ptr(char *name, char **handler) +static struct server_command *get_cmd_ptr(const char *name, char **handler) { struct server_command *cmd; @@ -479,11 +472,15 @@ static struct server_command *get_cmd_ptr(char *name, char **handler) for (; cmd->name; cmd++) if (!strcmp(cmd->name, name)) return cmd; + /* not found, look for commands supported by afs */ + for (cmd = afs_cmds; cmd; cmd++) + if (!strcmp(cmd->name, name)) + return cmd; return NULL; } /* help */ -int com_help(int fd, int argc, char **argv) +int com_help(int fd, int argc, char * const * argv) { struct server_command *cmd; char *perms, *handler; @@ -499,7 +496,10 @@ int com_help(int fd, int argc, char **argv) mmd_unlock(); ret = send_list_of_commands(fd, cmd, handler); free(handler); - return ret; + if (ret < 0) + return ret; + cmd = afs_cmds; + return send_list_of_commands(fd, cmd, "afs"); } /* argument given for help */ cmd = get_cmd_ptr(argv[1], &handler); @@ -527,7 +527,7 @@ int com_help(int fd, int argc, char **argv) } /* hup */ -int com_hup(__a_unused int fd, int argc, __a_unused char **argv) +int com_hup(__a_unused int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -536,7 +536,7 @@ int com_hup(__a_unused int fd, int argc, __a_unused char **argv) } /* term */ -int com_term(__a_unused int fd, int argc, __a_unused char **argv) +int com_term(__a_unused int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -544,7 +544,7 @@ int com_term(__a_unused int fd, int argc, __a_unused char **argv) return 1; } -int com_play(__a_unused int fd, int argc, __a_unused char **argv) +int com_play(__a_unused int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -557,7 +557,7 @@ int com_play(__a_unused int fd, int argc, __a_unused char **argv) } /* stop */ -int com_stop(__a_unused int fd, int argc, __a_unused char **argv) +int com_stop(__a_unused int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -570,7 +570,7 @@ int com_stop(__a_unused int fd, int argc, __a_unused char **argv) } /* pause */ -int com_pause(__a_unused int fd, int argc, __a_unused char **argv) +int com_pause(__a_unused int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -583,7 +583,7 @@ int com_pause(__a_unused int fd, int argc, __a_unused char **argv) return 1; } -int com_chs(int fd, int argc, char **argv) +int com_chs(int fd, int argc, char * const * argv) { int i, ret; @@ -609,7 +609,7 @@ int com_chs(int fd, int argc, char **argv) } /* next */ -int com_next(__a_unused int fd, int argc, __a_unused char **argv) +int com_next(__a_unused int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -621,7 +621,7 @@ int com_next(__a_unused int fd, int argc, __a_unused char **argv) } /* nomore */ -int com_nomore(__a_unused int fd, int argc, __a_unused char **argv) +int com_nomore(__a_unused int fd, int argc, __a_unused char * const * argv) { if (argc != 1) return -E_COMMAND_SYNTAX; @@ -633,7 +633,7 @@ int com_nomore(__a_unused int fd, int argc, __a_unused char **argv) } /* ff */ -int com_ff(__a_unused int fd, int argc, char **argv) +int com_ff(__a_unused int fd, int argc, char * const * argv) { long promille; int ret, backwards = 0; @@ -672,7 +672,7 @@ out: } /* jmp */ -int com_jmp(__a_unused int fd, int argc, char **argv) +int com_jmp(__a_unused int fd, int argc, char * const * argv) { long unsigned int i; int ret; @@ -756,6 +756,42 @@ static void rc4_send(unsigned long len, const unsigned char *indata, RC4(&rc4_send_key, len, indata, outdata); } +static int read_command(int fd, char **result) +{ + int ret; + char buf[4096]; + char *command = NULL; + + for (;;) { + size_t numbytes; + char *p; + + ret = recv_buffer(fd, buf, sizeof(buf)); + if (ret < 0) + goto out; + if (!ret) + break; + numbytes = ret; + ret = -E_COMMAND_SYNTAX; + if (command && numbytes + strlen(command) > MAX_COMMAND_LEN) /* DOS */ + goto out; + command = para_strcat(command, buf); + p = strstr(command, EOC_MSG); + if (p) { + *p = '\0'; + break; + } + } + ret = command? 1 : -E_COMMAND_SYNTAX; +out: + if (ret < 0) + free(command); + else + *result = command; + return ret; + +} + /** * perform user authentication and execute a command * @@ -789,7 +825,7 @@ static void rc4_send(unsigned long len, const unsigned char *indata, */ int handle_connect(int fd, struct sockaddr_in *addr) { - int numbytes, ret, argc, use_rc4 = 0; + int ret, argc, use_rc4 = 0; char buf[4096]; unsigned char crypt_buf[MAXLINE]; struct user *u; @@ -797,6 +833,7 @@ int handle_connect(int fd, struct sockaddr_in *addr) long unsigned challenge_nr, chall_response; char **argv = NULL; char *p, *command = NULL; + size_t numbytes; signal(SIGCHLD, SIG_IGN); signal(SIGINT, SIG_DFL); @@ -839,23 +876,23 @@ int handle_connect(int fd, struct sockaddr_in *addr) if (ret <= 0) goto err_out; numbytes = ret; - PARA_DEBUG_LOG("sending %d byte challenge\n", numbytes); + PARA_DEBUG_LOG("sending %zu byte challenge\n", numbytes); /* We can't use send_buffer here since buf may contain null bytes */ ret = send_bin_buffer(fd,(char *) crypt_buf, numbytes); if (ret < 0) goto err_out; /* recv decrypted number */ - numbytes = recv_buffer(fd, buf, sizeof(buf)); - ret = numbytes; + ret = recv_buffer(fd, buf, sizeof(buf)); if (ret < 0) goto err_out; + numbytes = ret; ret = -E_AUTH; if (!numbytes) goto err_out; if (sscanf(buf, CHALLENGE_RESPONSE_MSG "%lu", &chall_response) < 1 || chall_response != challenge_nr) goto err_out; - /* auth successful. Send 'Proceed' message */ + /* auth successful, send 'Proceed' message */ PARA_INFO_LOG("good auth for %s (%lu)\n", u->name, challenge_nr); sprintf(buf, "%s", PROCEED_MSG); if (use_rc4) { @@ -872,24 +909,12 @@ int handle_connect(int fd, struct sockaddr_in *addr) goto err_out; if (use_rc4) enable_crypt(fd, rc4_recv, rc4_send, NULL); - /* read command */ - while ((numbytes = recv_buffer(fd, buf, sizeof(buf))) > 0) { -// PARA_INFO_LOG("recvd: %s (%d)\n", buf, numbytes); - ret = -E_COMMAND_SYNTAX; - if (command && numbytes + strlen(command) > MAX_COMMAND_LEN) /* DOS */ - goto err_out; - command = para_strcat(command, buf); - if ((p = strstr(command, EOC_MSG))) { - *p = '\0'; - break; - } - } - ret = numbytes; + ret = read_command(fd, &command); if (ret < 0) goto err_out; ret = -E_BAD_CMD; - /* parse command */ - if (!(cmd = parse_cmd(command))) + cmd = parse_cmd(command); + if (!cmd) goto err_out; /* valid command, check permissions */ ret = check_perms(u->perms, cmd); @@ -909,10 +934,9 @@ int handle_connect(int fd, struct sockaddr_in *addr) goto out; } err_out: - if (ret != -E_SEND && ret != -E_RECV) { - PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-ret)); + PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-ret)); + if (ret != -E_SEND && ret != -E_RECV) send_va_buffer(fd, "%s\n", PARA_STRERROR(-ret)); - } ret = EXIT_FAILURE; out: free(command);