Source File modules/pc/protocol_config.c

    1    | /***************************************
    2    |   $Revision: 1.29 $
    3    |
    4    |   Protocol config module (pc).  This is the protocol that the admin uses to
    5    |   talk to the server.
    6    |
    7    |   Status: NOT REVUED, NOT TESTED
    8    |
    9    |   ******************/ /******************
    10   |   Filename            : protocol_config.c
    11   |   Authors             : ottrey@ripe.net
    12   |                         marek@ripe.net
    13   |   To Do               : Add a facility to take callbacks instead of
    14   |                         hard-coding menu options.
    15   |                         Add in all the menu support provided by the GLib
    16   |                         libraries.
    17   |                         (Remove strtok if multiple threads are to be used.)
    18   | 			use gnu readline with expansion and history
    19   |   ******************/ /******************
    20   |   Copyright (c) 1999                              RIPE NCC
    21   |
    22   |   All Rights Reserved
    23   |
    24   |   Permission to use, copy, modify, and distribute this software and its
    25   |   documentation for any purpose and without fee is hereby granted,
    26   |   provided that the above copyright notice appear in all copies and that
    27   |   both that copyright notice and this permission notice appear in
    28   |   supporting documentation, and that the name of the author not be
    29   |   used in advertising or publicity pertaining to distribution of the
    30   |   software without specific, written prior permission.
    31   |
    32   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
    33   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
    34   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    35   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    36   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    37   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    38   |   ***************************************/
    39   | #include <stdio.h>
    40   | #include <stdlib.h>
    41   | /*** solaris' header file doesn't contain the crypt definition...
    42   |      #include <unistd.h> */
    43   |
    44   | extern char* crypt(const char *, const char *);   /* crypt stuff */
    45   | #include <time.h>       /* Time stuff */
    46   | #include <sys/ioctl.h>  /* Terminal control stuff */
    47   | #include <termio.h>     /* Terminal control stuff */
    48   | #include "thread.h"
    49   | #include "constants.h"
    50   | #include "properties.h"
    51   | #include <glib.h>
    52   |
    53   | #include "sk.h"
    54   | #include "ta.h"
    55   |
    56   | #include "pc_commands.h"
    57   |
    58   | #define PC_IMPL
    59   | #include "protocol_config.h"
    60   |
    61   | static
    62   | int find_command(char *comm_name, Command *comm)
    63   | {
    64   |   int i;
    65   |   char *comm_buffer = wr_string(comm_name);
    66   |   char *token, *cursor;
    67   |   int index = -1;
    68   |
    69   |   cursor = comm_buffer;
    70   |   if( (token = strsep(&cursor, " \t")) != NULL) {
    71   |     for (i=0; comm[i].name != NULL; i++) {
    72   |       if ( strcmp(token, comm[i].name) == 0) {
    73   | 	index = i;
    74   | 	break;
    75   |       }
    76   |     }
    77   |   }
    78   |
    79   |   wr_free(comm_buffer);
    80   |
    81   |   return index; /* returns -1 when command not found */
    82   | } /* find_command() */
    83   |
    84   | static
    85   | int show_commands(Command *comm, char *comm_name, GString *output)
    86   | {
    87   |   int i = 0;
    88   |
    89   |   g_string_sprintfa(output, "%scommands are:\n\n", comm_name);
    90   |   while (comm[i].name != NULL) {
    91   |     g_string_sprintfa(output, "%s\t%s\n", comm[i].name, comm[i].help);
    92   |     i++;
    93   |   }
    94   |
    95   |   return 1;
    96   | } /* show_commands() */
    97   |
    98   |
    99   | int command_execute(Command *comm, char *comm_name,
    100  | 		    char *input, GString *output, sk_conn_st *condat)
    101  | {
    102  |   char *name, *next_word, *tmp_input;
    103  |   int index, result=0;
    104  |
    105  |   /* find the command in the string - first whitespace delimited word */
    106  |   /* make a copy of the input */
    107  |   dieif( (tmp_input = wr_string(input)) == NULL );
    108  |   next_word = tmp_input;
    109  |
    110  |   /* find the first word and set the pointer to the rest of the string */
    111  |   name = strsep(&next_word, " \t");
    112  |
    113  |   if( name != NULL && strlen(name) != 0 ) {
    114  |     index = find_command(name, comm);
    115  |     if( index != -1 ) {
    116  |       if( next_word != NULL ) {
    117  | 	/* advance the input pointer to the next word */
    118  | 	while(  *next_word != '\0' && isspace(*next_word) ) {
    119  | 	  next_word++;
    120  | 	}
    121  |       }
    122  |       else {
    123  | 	next_word = "";
    124  |       }
    125  |
    126  |       /* run, Forrest, run...*/
    127  |       result = comm[index].function(next_word, output, condat);
    128  |     }
    129  |     else {
    130  |       g_string_sprintfa(output, "invalid %scommand: %s\n", comm_name, name);
    131  |       show_commands(comm, comm_name, output);
    132  |       result = 2;
    133  |     }
    134  |   }
    135  |   else {
    136  |     show_commands(comm, comm_name, output);
    137  |     result = 2;
    138  |   }
    139  |
    140  |   free(tmp_input);
    141  |
    142  |   return result;
    143  | } /* command_execute() */
    144  |
    145  |
    146  | static
    147  | int command_help(char *input, GString *output, sk_conn_st *condat)
    148  | {
    149  |   /* by the time it came here, the "help" bit is already taken away. */
    150  |   return show_commands(command, "", output);
    151  |
    152  | }
    153  |
    154  |
    155  |
    156  |
    157  |
    158  |
    159  | /* proces_input() */
    160  | /*++++++++++++++++++++++++++++++++++++++
    161  |
    162  |   Process the input.
    163  |
    164  |   sk_conn_st *condat         connection data
    165  |
    166  |   More:
    167  |   +html+ <PRE>
    168  |   Author:
    169  |         ottrey
    170  |   +html+ </PRE>
    171  |   ++++++++++++++++++++++++++++++++++++++*/
    172  | static
    173  | int process_input(char *input, sk_conn_st *condat)
    174  | {
    175  |   int  index;
    176  |   int res=0;
    177  |   GString *output = g_string_new("");
    178  |
    179  |   index = find_command(input, command);
    180  |
    181  |   switch (index) {
    182  |   case -1:
    183  |     /* Command not found */
    184  |     command_help(NULL, output, condat);
    185  |     break;
    186  |
    187  |   default:
    188  |     res = command_execute(command, "", input, output, condat);
    189  |   }
    190  |
    191  |   if(res != PC_RET_QUIT) {
    192  |     /*
    193  |       printf("thread output=\n%s\n", output);
    194  |     */
    195  |     if ( CO_get_clear_screen() == 1 ) {
    196  |       SK_cd_puts(condat, CLEAR_SCREEN);
    197  |     }
    198  |     SK_cd_puts(condat,  output->str);
    199  |     SK_cd_printf(condat, "\n\n=%d= %s", res, CO_get_prompt());
    200  |
    201  |   }
    202  |
    203  |   g_string_free( output, TRUE );
    204  |
    205  |   /* the return value is the connection state: 1=still open, 0=to be closed
    206  |    */
    207  |
    208  |   return (res != PC_RET_QUIT);
    209  | } /* process_input() */
    210  |
    211  |
    212  | static
    213  | char *authenticate_user(sk_conn_st *condat)
    214  | {
    215  |   char *user = NULL;
    216  |   const char Salt[2] = "DB";
    217  |   char input[MAX_INPUT_SIZE];
    218  |   int read_result;
    219  |   char *password=NULL;
    220  |   char *user_password=NULL;
    221  |   char user_buf[10];
    222  |
    223  |   SK_cd_puts(condat, LOGIN_PROMPT);
    224  |   read_result = SK_cd_gets(condat, input, MAX_INPUT_SIZE);
    225  |
    226  |   strncpy(user_buf, input, 10);
    227  |
    228  |   SK_cd_puts(condat, PASSWD_PROMPT);
    229  |   /* XXX These aren't working.
    230  |   SK_puts(sock, ECHO_ON);
    231  |   echo_off(sock);
    232  |   */
    233  |   read_result = SK_cd_gets(condat, input, MAX_INPUT_SIZE);
    234  |   /* XXX These aren't working.
    235  |   echo_on(sock);
    236  |   SK_puts(sock, ECHO_OFF);
    237  |   */
    238  |
    239  |   password = crypt(input, Salt);
    240  |
    241  |   user_password = PR_get_property(user_buf, DEFAULT_USER_NAME);
    242  |
    243  |   if (user_password != NULL) {
    244  |     if (strcmp(password, user_password) == 0) {
    245  |       /*user = (char *)calloc(1, strlen(user_buf)+1);*/
    246  |       dieif( wr_malloc((void **)&user, strlen(user_buf)+1) != UT_OK);
    247  |       strcpy(user, user_buf);
    248  |     }
    249  |   }
    250  |
    251  |
    252  |   return user;
    253  |
    254  | } /* authenticate_user() */
    255  |
    256  | void PC_interact(int sock) {
    257  |   char input[MAX_INPUT_SIZE];
    258  |   int connected = 1;
    259  |   char *user=NULL;
    260  |   sk_conn_st condat;
    261  |
    262  |   memset( &condat, 0, sizeof(condat));
    263  |   condat.sock = sock;
    264  |   SK_getpeerip(sock, &(condat.rIP));
    265  |   condat.ip = SK_getpeername(sock); /* XXX *alloc involved */
    266  |
    267  |   /* Welcome the client */
    268  |   SK_cd_puts(&condat, CO_get_welcome());
    269  |
    270  |   /* Authenticate the user */
    271  |   if (CO_get_authenticate() == 1) {
    272  |     user = authenticate_user(&condat);
    273  |
    274  |     if (user == NULL) {
    275  |       ER_inf_va(FAC_PC, ASP_PC_I_SESSION,
    276  | 		"unsuccesful login attempt from %s", condat.ip );
    277  |     }
    278  |   }
    279  |   else {
    280  |     user="nobody";
    281  |   }
    282  |
    283  |   if (user != NULL) {
    284  |
    285  |     /* Log admin logging on */
    286  |     ER_inf_va(FAC_PC, ASP_PC_I_SESSION,
    287  | 		"user %s from %s logged on", user, condat.ip );
    288  |
    289  |     {
    290  |       char timestring[26];
    291  |       extern time_t SV_starttime;
    292  |
    293  |       ctime_r(&SV_starttime, timestring);
    294  |       SK_cd_printf(&condat,
    295  | 		   "System running since %sUptime in seconds: %ld \n\n",
    296  | 		   timestring,
    297  | 		   time(NULL) - SV_starttime);
    298  |     }
    299  |
    300  |     SK_cd_puts(&condat, CO_get_prompt());
    301  |
    302  |     while (condat.rtc==0 && connected) {
    303  |       char *ichr;
    304  |       char *icopy;
    305  |       char *chr;
    306  |       /* Read input. Quit if no input (socket closed) */
    307  |       if( SK_cd_gets(&condat, input, MAX_INPUT_SIZE) <= 0 ) {
    308  | 	break;
    309  |       }
    310  |
    311  |       /* filter junk out: leading/trailing whitespaces */
    312  |
    313  |
    314  |
    315  |       /* 1. advance to non-whitespace */
    316  |       for(ichr=input; *ichr != 0 && isspace(*ichr); ichr++) {
    317  | 	/* EMPTY */
    318  |       }
    319  |
    320  |       /* 2. copy the rest (even if empty) */
    321  |       dieif( (icopy = strdup(ichr)) == NULL);
    322  |
    323  |       if( *ichr != '\0') {
    324  | 	/* 3. chop trailing spaces */
    325  | 	for( chr = icopy + strlen(icopy)-1 ;
    326  | 	     chr != icopy && isspace(*chr);
    327  | 	     chr--) {
    328  | 	  *chr = 0;
    329  | 	}
    330  |       }
    331  |
    332  |       /* set thread accounting */
    333  |       TA_setactivity(icopy);
    334  |       TA_increment();
    335  |
    336  |       /*      if( strlen(icopy) > 0 ) {*/
    337  |       {
    338  | 	ER_inf_va(FAC_PC, ASP_PC_I_COMMAND, icopy);
    339  |
    340  | 	connected = process_input(icopy, &condat);
    341  |       }
    342  |
    343  |       TA_setactivity("");
    344  |
    345  |       free(icopy);
    346  |     }
    347  |
    348  |     /* Log admin logging off */
    349  |     ER_inf_va(FAC_PC, ASP_PC_I_SESSION,
    350  | 		"user %s from %s logged off", user, condat.ip );
    351  |
    352  |   }
    353  |
    354  |   /* Close the socket */
    355  |   SK_close(sock);
    356  |
    357  |   wr_free(condat.ip);
    358  | } /* PC_interact() */
    359  |