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 |