1    | /***************************************
2    |   $Revision: 1.19 $
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   | 
49   | #include "mysql_driver.h"
50   | #include "constants.h"
51   | #include "properties.h"
52   | #include "thread.h"
53   | #include "protocol_config.h"
54   | #include "access_control.h"
55   | #include "socket.h"
56   | 
57   | /*+ Each command has a +*/
58   | typedef struct _command {
59   |   const char *name;                          /*+ Name to be invoked. +*/
60   |   char *(*function)(char *, sk_conn_st *);   /*+ Function to be invoked. +*/
61   |   const char *help;                                /*+ Command help. +*/
62   | } Command;
63   | 
64   | /*
65   |  * Forward declarations
66   |  */
67   | static char *command_help(char *input, sk_conn_st *condat);
68   | static char *command_quit(char *input, sk_conn_st *condat);
69   | static char *command_show(char *input, sk_conn_st *condat);
70   | static char *command_repeat(char *input, sk_conn_st *condat);
71   | static char *show_const(char *input, sk_conn_st *condat);
72   | static char *show_consts(char *input, sk_conn_st *condat);
73   | static char *show_props(char *input, sk_conn_st *condat);
74   | static char *show_thread(char *input, sk_conn_st *condat);
75   | static char *show_whois(char *input, sk_conn_st *condat);
76   | static char *show_access(char *input, sk_conn_st *condat);
77   | static char *show_acl(char *input, sk_conn_st *condat);
78   | static char *command_set(char *input, sk_conn_st *condat);
79   | static char *set_const(char *input, sk_conn_st *condat);
80   | static char *set_consts(char *input, sk_conn_st *condat);
81   | static char *set_props(char *input, sk_conn_st *condat);
82   | static char *command_sql(char *input, sk_conn_st *condat);
83   | static char *set_ban(char *input, sk_conn_st *condat);
84   | 
85   | /*+
86   |  * Contains the command definitions
87   | +*/
88   | static struct _command command[] = {
89   |   {"help"   , command_help   , HELP_HELP   },
90   |   {"quit"   , command_quit   , HELP_QUIT   },
91   |   {"show"   , command_show   , HELP_SHOW   },
92   |   {"repeat" , command_repeat , HELP_REPEAT },
93   |   {"set"    , command_set    , HELP_SET    },
94   |   {"sql"    , command_sql    , HELP_SQL    },
95   |   {NULL     , NULL           , NULL        }
96   | };
97   | 
98   | /*+
99   |  * Contains the show commands
100  | +*/
101  | static struct _command show[] = {
102  |   {"const"   , show_const   , HELP_SHOW_CONST   },
103  |   {"consts"  , show_consts  , HELP_SHOW_CONSTS  },
104  |   {"props"   , show_props   , HELP_SHOW_PROPS   },
105  |   {"thread"  , show_thread  , HELP_SHOW_THREAD  },
106  |   {"whois"   , show_whois   , HELP_SHOW_WHOIS   },
107  |   {"access"  , show_access  , HELP_SHOW_ACCESS  },
108  |   {"acl"     , show_acl     , HELP_SHOW_ACL     },
109  |   {NULL      , NULL         , NULL              }
110  | };
111  | 
112  | /*+
113  |  * Contains the set commands
114  | +*/
115  | static struct _command set[] = {
116  |   {"const"  , set_const  , HELP_SET_CONST  },
117  |   {"consts" , set_consts , HELP_SET_CONSTS },
118  |   {"props"  , set_props  , HELP_SET_PROPS  },
119  |   {"ban"    , set_ban    , HELP_SET_BAN    },
120  |   {NULL     , NULL       , NULL            }
121  | };
122  | 
123  | static int find_command(char *comm_name, Command *comm) {
124  |   int i, index;
125  |   char comm_buffer[STR_L];
126  | 
127  |   if (comm_name != NULL) {
128  |     strcpy(comm_buffer, comm_name);
129  |     strtok(comm_buffer, " \t");
130  |     for (i=0, index=-1; comm[i].name != NULL; i++) {
131  |       if ( strcmp(comm_buffer, comm[i].name) == 0) {
132  |         index = i;
133  |         break;
134  |       }
135  |     }
136  |   }
137  |   else {
138  |     index = -2;
139  |   }
140  | 
141  |   return index;
142  | } /* find_command() */
143  | 
144  | static char *show_commands(Command *comm) {
145  |   char *str;
146  |   char help_buffer[STR_XL];
147  |   char help_comm[STR_M];
148  |   int i;
149  | 
150  |   sprintf(help_buffer, " commands are:\n\n");
151  |   i = 0;
152  |   while (comm[i].name != NULL) {
153  |     sprintf(help_comm, "%s\t%s\n", comm[i].name, comm[i].help);
154  |     strcat(help_buffer, help_comm);
155  |     i++;
156  |   }
157  | 
158  |   /* str = (char *)calloc(1, strlen(help_buffer)+1); */
159  |   dieif( wr_malloc((void **)&str, strlen(help_buffer)+1) != UT_OK);  
160  |   strcpy(str, help_buffer);
161  | 
162  |   return str;
163  | } /* show_commands() */
164  | 
165  | 
166  | /*
167  |  * Command functions
168  |  */
169  | static char *command_help(char *input, sk_conn_st *condat) {
170  |   char *str;
171  |   char *str1;
172  |   char output_buffer[STR_XXL];
173  |   char *command_name;
174  |   int index;
175  | 
176  |   strcpy(output_buffer, "");
177  | 
178  |   strtok(input, " \t");
179  |   command_name = (char *)strtok(NULL, " \t");
180  | 
181  |   index = find_command(command_name, command);
182  | 
183  |   switch (index) {
184  |     case -2:
185  |       strcat(output_buffer, "Main");
186  |       str1 = show_commands(command);
187  |       strcat(output_buffer, str1);
188  |       wr_free(str1);
189  |       break;
190  | 
191  |     case -1:
192  |       strcat(output_buffer, HELP_ERROR);
193  |       strcat(output_buffer, command_name);
194  |       break;
195  | 
196  |     default: 
197  |       strcat(output_buffer, command[index].help);
198  |   }
199  | 
200  |   /*
201  |   str = (char *)CopyString(output_buffer);
202  |   */
203  |   /*  str = (char *)calloc(1, strlen(output_buffer)+1); */
204  |   dieif( wr_malloc((void **)&str, strlen(output_buffer)+1) != UT_OK);  
205  |   strcpy(str, output_buffer);
206  | 
207  |   return str;
208  | } /* command_help() */
209  | 
210  | static char *command_quit(char *input, sk_conn_st *condat) {
211  |     /* Administrator wishes to quit. */
212  |   return NULL;
213  | } /* command_quit() */
214  | 
215  | static char *show_const(char *input, sk_conn_st *condat) {
216  |   /* Administrator wishes to show constants. */
217  |   char *result;
218  |   char *name;
219  |   char *tmp_input;
220  | 
221  |   /* tmp_input = (char *)calloc(1, strlen(input)+1); */
222  |   dieif( wr_malloc((void **)&tmp_input, strlen(input)+1) != UT_OK);  
223  |   strcpy(tmp_input, input);
224  | 
225  |   /* The name will be the third token in stuff */
226  |   strtok(tmp_input, " ");
227  |   strtok(NULL, " ");
228  |   name = (char *)strtok(NULL, " ");
229  | 
230  |   result = CO_const_to_string(name);
231  | 
232  |   wr_free(tmp_input);
233  |   return result;
234  | 
235  | } /* show_const() */
236  | 
237  | static char *show_consts(char *input, sk_conn_st *condat) {
238  |   /* Administrator wishes to show constants. */
239  |   return CO_to_string();
240  | 
241  | } /* show_consts() */
242  | 
243  | static char *show_props(char *input, sk_conn_st *condat) {
244  |   /* Administrator wishes to show properties. */
245  |   return PR_to_string();
246  | 
247  | } /* show_props() */
248  | 
249  | static char *show_thread(char *input, sk_conn_st *condat) {
250  |   /* Administrator wishes to show thread information. */
251  |   return TH_to_string();
252  | 
253  | } /* show_thread() */
254  | 
255  | static char *show_whois(char *input, sk_conn_st *condat) {
256  |   /* Administrator wishes to show whois query information. */
257  |   return wr_string("WQ_to_string();");
258  | 
259  | } /* show_whois() */
260  | 
261  | static char *show_access(char *input, sk_conn_st *condat) {
262  |   /* Administrator wishes to show whois query information. */
263  |   
264  |   char line[128];
265  |   int cnt;
266  |   er_ret_t err; 
267  | 
268  |   if( act_runtime->top_ptr != NULL ) {
269  |     char *header = AC_to_string_header();
270  |     
271  |     /* print header */
272  |     SK_cd_puts(condat,header);
273  |     wr_free(header);
274  | 
275  |     cnt = rx_walk_tree(act_runtime->top_ptr, AC_rxwalkhook_print, 
276  | 		       RX_WALK_SKPGLU,  /* print no glue nodes */
277  | 		       255, 0, 0, condat, &err);
278  |     sprintf(line,"Found %d nodes\n", cnt);
279  |     SK_cd_puts(condat,line);
280  |   }
281  |   
282  |   return wr_string("");
283  | 
284  | } /* show_access() */
285  | 
286  | static char *show_acl(char *input, sk_conn_st *condat) {
287  |   /* Administrator wishes to show access control list. */
288  |   
289  |   char line[128];
290  |   int cnt;
291  |   er_ret_t err; 
292  | 
293  |   if( act_acl->top_ptr != NULL ) {
294  |     char *header = AC_acl_to_string_header();
295  |     
296  |     /* print header */
297  |     SK_cd_puts(condat,header);
298  |     wr_free(header);
299  | 
300  |     cnt = rx_walk_tree(act_acl->top_ptr, AC_rxwalkhook_print_acl, 
301  | 		       RX_WALK_SKPGLU,  /* print no glue nodes */
302  | 		       255, 0, 0, condat, &err);
303  |     sprintf(line,"Found %d nodes\n", cnt);
304  |     SK_cd_puts(condat,line);
305  |   }
306  |   
307  |   return wr_string("");
308  | 
309  | } /* show_acl() */
310  | 
311  | static char *command_execute(char *input, char *comm_name, 
312  | 			     Command *comm, sk_conn_st *condat) {
313  |   char *str;
314  |   char *str1;
315  |   char output_buffer[STR_XXL];
316  |   char *name;
317  |   int index;
318  |   char *tmp_input;
319  | 
320  |   /* Make a copy of the input */
321  |   /* tmp_input = (char *)calloc(1, strlen(input)+1); */
322  |   dieif( wr_malloc((void **)&tmp_input, strlen(input)+1) != UT_OK);  
323  |   strcpy(tmp_input, input);
324  | 
325  |   strtok(tmp_input, " \t");
326  |   name = (char *)strtok(NULL, " \t");
327  | 
328  |   index = find_command(name, comm);
329  | 
330  |   switch (index) {
331  |     case -2:
332  |       str1 = show_commands(comm);
333  |       sprintf(output_buffer, "%s%s", comm_name, str1);
334  |       wr_free(str1);
335  |       break;
336  | 
337  |     case -1:
338  |       sprintf(output_buffer, "%s invalid command: %s", comm_name, name);
339  |       break;
340  | 
341  |     default: 
342  |       sprintf(output_buffer, "%s", comm[index].function(input, condat));
343  |   }
344  | 
345  |   /*
346  |   str = (char *)CopyString(output_buffer);
347  |   */
348  |   /* str = (char *)calloc(1, strlen(output_buffer)+1); */
349  |   dieif( wr_malloc((void **)&str, strlen(output_buffer)+1) != UT_OK);  
350  |   strcpy(str, output_buffer);
351  | 
352  |   wr_free(tmp_input);
353  | 
354  |   return str;
355  | } /* command_execute() */
356  | 
357  | static char *command_show(char *input, sk_conn_st *condat) {
358  |   return command_execute(input, "Show", show, condat);
359  | } /* command_show() */
360  | 
361  | static char *command_repeat(char *input, sk_conn_st *condat) {
362  |   char *command_ptr;
363  | 
364  |   /* Goto the bit after "repeat n " */
365  |   for (command_ptr=input+7; command_ptr[0] != ' ' || (command_ptr[0] >= '0' && command_ptr[0] <= '9'); command_ptr++);
366  | 
367  |   return command_ptr+1;
368  | 
369  | } /* command_show() */
370  | 
371  | static char *set_const(char *input, sk_conn_st *condat) {
372  |   /* Administrator wishes to set a constant. */
373  |   char *result;
374  |   char result_buf[STR_M];
375  |   char *tmp_input;
376  |   char *name;
377  |   char *value;
378  |   int value_len;
379  |   char *stuff;
380  |   char *str;
381  | 
382  |   /* tmp_input = (char *)calloc(1, strlen(input)+1); */
383  |   dieif( wr_malloc((void **)&tmp_input, strlen(input)+1) != UT_OK);  
384  |   strcpy(tmp_input, input);
385  | 
386  |   stuff = (char *)strtok(tmp_input, "=");
387  | 
388  |   /* The value will be after the '=' */
389  |   value = (char *)strtok(NULL, "=");
390  | 
391  |   /* The name will be the third token in stuff */
392  |   strtok(stuff, " ");
393  |   strtok(NULL, " ");
394  |   name = (char *)strtok(NULL, " ");
395  | 
396  |   /* Remove any quotes */
397  |   if (value[0] == '"') {
398  |     value++;
399  |   }
400  |   value_len=strlen(value);
401  |   if (value[value_len-1] == '"') {
402  |     value[value_len-1]='\0';
403  |   }
404  | 
405  |   printf("set_const name=(%s), value=(%s)\n", name, value);
406  |   if (CO_set_const(name, value) == 0) {
407  |     strcpy(result_buf, "Constant successfully set\n");
408  |   }
409  |   else {
410  |     str = CO_const_to_string(name);
411  |     sprintf(result_buf, "Constant not successfully set\nReverting to:   %s=%s\n", name, str);
412  |     wr_free(str);
413  |   }
414  | 
415  |   /* result = (char *)calloc(1, strlen(result_buf)+1); */
416  |   dieif( wr_malloc((void **)&result, strlen(result_buf)+1) != UT_OK);  
417  |   strcpy(result, result_buf);
418  | 
419  |   wr_free(tmp_input);
420  |   return result;
421  | } /* set_const() */
422  | 
423  | static char *set_consts(char *input, sk_conn_st *condat) {
424  |   /* Administrator wishes to set constants. */
425  |   return CO_set();
426  | } /* set_consts() */
427  | 
428  | static char *set_props(char *input, sk_conn_st *condat) {
429  |   /* Administrator wishes to set properties. */
430  |   return PR_set();
431  | } /* set_props() */
432  | 
433  | static char *set_ban(char *input, sk_conn_st *condat) {
434  |   int flag;
435  |   char addrstr[128];
436  | 
437  |   if( sscanf(input,"set ban %d %127s", &flag, addrstr) < 2) {
438  |     return wr_string("Invalid arguments");
439  |   }
440  |   else {
441  |     if( ! NOERR( AC_asc_ban_set( addrstr, "Manual", (flag!=0) ))) {
442  |       return wr_string("Error\n");
443  |     }
444  |     else {
445  |       return wr_string("OK");
446  |     }
447  |   }
448  | }
449  | 
450  | static char *command_set(char *input, sk_conn_st *condat) {
451  |   return command_execute(input, "Set", set, condat);
452  | } /* command_set() */
453  | 
454  | static char *command_sql(char *input, sk_conn_st *condat) {
455  |   char *str;
456  |   char output_buffer[STR_XXL];
457  |   char *sql_str;
458  | 
459  |   char *res=NULL;
460  | 
461  |   SQ_result_set_t *sql_result=NULL;
462  |   SQ_connection_t *sql_connection;
463  | 
464  |   sql_connection = SQ_get_connection(CO_get_host(), CO_get_database_port(), CO_get_database(), CO_get_user(), CO_get_password() );
465  | 
466  |   if (sql_connection == NULL) {
467  |     printf("/* Check for errors */\n");
468  |   }
469  | 
470  |   /* skip over the "sql" */
471  |   sql_str = input+3;
472  |   /* skip over white space */
473  |   while (sql_str[0] == ' ') {
474  |     sql_str++;
475  |   }
476  | 
477  |   strcpy(output_buffer, "");
478  | 
479  |   if (sql_connection != NULL) {
480  |     if (strcmp(sql_str, "status") == 0) {
481  |       /* Get the status of the database */
482  |       res = SQ_info_to_string(sql_connection);
483  |     }
484  |     else {
485  |       if (strcmp(sql_str, "") == 0) {
486  |         /* Execute the default query (from the properties file) */
487  | 	  SQ_execute_query(sql_connection, CO_get_query(), &sql_result);
488  |       }
489  |       else {
490  |         /* Execute an sql query */
491  | 	  SQ_execute_query(sql_connection, sql_str, &sql_result);
492  |       }
493  |       if (sql_result != NULL) {
494  |         res = SQ_result_to_string(sql_result);
495  |       }
496  |       else {
497  |         printf("no results\n");
498  |       }
499  |     }
500  |     if (res != NULL) {
501  |       sprintf(output_buffer, "%s", res);
502  |     }
503  |     else {
504  |       printf("empty results\n");
505  |     }
506  |   }
507  |   else {
508  |     printf("Failed to make connection\n");
509  |   }
510  | 
511  |   /*
512  |   strcat(output_buffer, mysql_info(sql_connection));
513  |   */
514  | 
515  |   strcat(output_buffer, "XXX Results from mysql_info(sql_connection) is meant to go here.  But it's not working!");
516  | 
517  |   /*
518  |   str = (char *)CopyString(output_buffer);
519  |   */
520  |   /* str = (char *)calloc(1, strlen(output_buffer)+1); */
521  |   dieif( wr_malloc((void **)&str, strlen(output_buffer)+1) != UT_OK);  
522  |   strcpy(str, output_buffer);
523  | 
524  |   wr_free(res);
525  |   SQ_free_result(sql_result);
526  | 
527  |   SQ_close_connection(sql_connection);
528  | 
529  |   return str;
530  | 
531  | } /* command_sql() */
532  | 
533  | 
534  | /* process_input() */
535  | /*++++++++++++++++++++++++++++++++++++++
536  | 
537  |   Process the input.
538  | 
539  |   sk_conn_st *condat         connection data    
540  | 
541  |   More:
542  |   +html+ <PRE>
543  |   Author:
544  |         ottrey
545  |   +html+ </PRE>
546  |   ++++++++++++++++++++++++++++++++++++++*/
547  | static int process_input(char *input, sk_conn_st *condat) {
548  |   int connected = 1;
549  |   char *input_ptr;
550  |   char *output;
551  |   int  index;
552  |   int repeat=0;
553  | 
554  |   input_ptr = input;
555  | 
556  |   if (strncmp(input, "repeat", 6) == 0) {
557  |     /* XXX This is a really dodgy call, that hopefully converts
558  |     the string to the value of the first found integer. */
559  |     repeat = atoi(input+7);
560  |     input_ptr= command_repeat(input, condat);
561  |   }
562  | 
563  |   index = find_command(input_ptr, command);
564  | 
565  |   do {
566  |     switch (index) {
567  |       case -1:
568  |         /* Command not found */
569  |         output = command_help(NULL, condat);
570  |         break;
571  | 
572  |       default: 
573  |         output = command[index].function(input_ptr, condat);
574  |     }
575  | 
576  |     if(output == NULL) {
577  |       connected = 0;
578  |     } else {
579  |       /*
580  |       printf("thread output=\n%s\n", output);
581  |       */
582  |       if ( CO_get_clear_screen() == 1 ) {
583  |         SK_cd_puts(condat, CLEAR_SCREEN);
584  |       }
585  |       SK_cd_puts(condat,  output);
586  |       SK_cd_puts(condat, "\n");
587  |       SK_cd_puts(condat, CO_get_prompt());
588  |       
589  |       wr_free(output);
590  |     }
591  | 
592  |     if (repeat > 0) {
593  |       repeat--;
594  |       sleep(CO_get_sleep_time());
595  |     }
596  | 
597  |   } while (repeat > 0);
598  | 
599  |   return connected;
600  | 
601  | } /* process_input() */
602  | 
603  | static void log_config(const char *user, const char *status) {
604  |   FILE *logf;
605  |   time_t now;
606  |   char timebuf[26];
607  | 
608  |   time(&now);
609  | 
610  |   if (CO_get_config_logging() == 1) {
611  |     
612  |     if (strcmp(CO_get_config_logfile(), "stdout") == 0) {
613  |       printf(LOG_CONFIG, TH_get_id(), user, status, ctime_r(&now, timebuf));
614  |     }
615  |     else {
616  |       logf = fopen(CO_get_config_logfile(), "a");
617  |       fprintf(logf, LOG_CONFIG, TH_get_id(), user, status, ctime_r(&now, timebuf));
618  |       fclose(logf);
619  |     }
620  |   }
621  | 
622  | } /* log_config() */
623  |  
624  | /* XXX Doh! These only change the server's terminal.  We need some
625  |    tricky escape sequence to send over the socket.
626  | static void echo_off(int sock) {
627  |   struct termio state;
628  | 
629  |   ioctl(0, TIOCGETP, &state);
630  |   state.c_lflag &= ~ECHO;
631  |   ioctl(0, TIOCSETP, &state);
632  | } echo_off() */
633  | 
634  | /* XXX Doh! These only change the server's terminal.  We need some
635  |    tricky escape sequence to send over the socket.
636  | static void echo_on(int sock) {
637  |   struct termio state;
638  | 
639  |   ioctl(0, TIOCGETP, &state);
640  |   state.c_lflag |= ECHO;
641  |   ioctl(0, TIOCSETP, &state);
642  | } echo_on() */
643  | 
644  | static char *authenticate_user(sk_conn_st *condat) {
645  |   char *user = NULL;
646  |   const char Salt[2] = "DB";
647  |   char input[MAX_INPUT_SIZE];
648  |   int read_result;
649  |   char *password=NULL;
650  |   char *user_password=NULL;
651  |   char user_buf[10];
652  | 
653  |   SK_cd_puts(condat, LOGIN_PROMPT);
654  |   read_result = SK_cd_gets(condat, input, MAX_INPUT_SIZE);
655  | 
656  |   strncpy(user_buf, input, 10);
657  | 
658  |   SK_cd_puts(condat, PASSWD_PROMPT);
659  |   /* XXX These aren't working.
660  |   SK_puts(sock, ECHO_ON);
661  |   echo_off(sock);
662  |   */
663  |   read_result = SK_cd_gets(condat, input, MAX_INPUT_SIZE);
664  |   /* XXX These aren't working.
665  |   echo_on(sock);
666  |   SK_puts(sock, ECHO_OFF);
667  |   */
668  | 
669  |   password = crypt(input, Salt);
670  | 
671  |   user_password = PR_get_property(user_buf, DEFAULT_USER_NAME);
672  | 
673  |   if (user_password != NULL) {
674  |     if (strcmp(password, user_password) == 0) {
675  |       /*user = (char *)calloc(1, strlen(user_buf)+1);*/
676  |       dieif( wr_malloc((void **)&user, strlen(user_buf)+1) != UT_OK);  
677  |       strcpy(user, user_buf);
678  |     }
679  |   }
680  | 
681  |   if (user == NULL) {
682  |     log_config(user_buf, "unsuccesful login attempt");
683  |   }
684  | 
685  |   return user;
686  | 
687  | } /* authenticate_user() */
688  | 
689  | void PC_interact(int sock) {
690  |   char input[MAX_INPUT_SIZE];
691  |   int connected = 1;
692  |   char *user=NULL;
693  |   sk_conn_st condat;
694  | 
695  |   memset( &condat, 0, sizeof(condat));
696  |   condat.sock = sock;
697  |   SK_getpeerip(sock, &(condat.rIP));
698  |   condat.ip = SK_getpeername(sock); /* XXX *alloc involved */
699  |   
700  |   /* Welcome the client */
701  |   SK_cd_puts(&condat, CO_get_welcome());
702  | 
703  |   /* Authenticate the user */
704  |   if (CO_get_authenticate() == 1) {
705  |     user = authenticate_user(&condat);
706  |   }
707  |   else {
708  |     user="nobody";
709  |   }
710  | 
711  |   if (user != NULL) {
712  |     
713  | 
714  |     /* Log admin logging on */
715  |     log_config(user, "logged on");
716  | 
717  |     
718  |     {
719  |       char timestring[26];
720  |       extern time_t SV_starttime;
721  |       
722  |       ctime_r(&SV_starttime, timestring); 
723  |       SK_cd_printf(&condat, 
724  | 		   "System running since %sUptime in seconds: %ld \n\n",
725  | 		   timestring,		  
726  | 		   time(NULL) - SV_starttime);
727  |     }
728  |     
729  |     SK_cd_puts(&condat, CO_get_prompt());
730  | 
731  |     while (condat.rtc==0 && connected) {
732  |       /* Read input */
733  |       SK_cd_gets(&condat, input, MAX_INPUT_SIZE);
734  |       connected = process_input(input, &condat);
735  |     }
736  |     
737  |     /* Log admin logging off */
738  |     log_config(user, "logged off");
739  |   }
740  |   
741  |   /* Close the socket */
742  |   SK_close(sock);
743  | 
744  |   wr_free(condat.ip);
745  | } /* PC_interact() */
746  |