## modules/pc/protocol_config.c

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. find_command
2. show_commands
3. command_execute
4. command_help
5. process_input
6. authenticate_user
7. PC_interact

       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)
         /* [<][>][^][v][top][bottom][index][help] */
      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)
         /* [<][>][^][v][top][bottom][index][help] */
      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,
         /* [<][>][^][v][top][bottom][index][help] */
     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)
         /* [<][>][^][v][top][bottom][index][help] */
     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)
         /* [<][>][^][v][top][bottom][index][help] */
     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)
         /* [<][>][^][v][top][bottom][index][help] */
     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) {
         /* [<][>][^][v][top][bottom][index][help] */
     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

/* [<][>][^][v][top][bottom][index][help] */