modules/pc/protocol_config.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- find_command
- show_commands
- command_execute
- command_help
- process_input
- authenticate_user
- 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