Changes for kernel and Busybox
[tomato.git] / release / src / router / bpalogin / protocol.c
blobeb51f025da0cb83611507d8ca9780b2b37cae32f
1 /*
2 ** BPALogin - lightweight portable BIDS2 login client
3 ** Copyright (c) 2001-3 Shane Hyde, and others.
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
21 #include "bpalogin.h"
22 #include "md5.h"
25 void genmd5(char *p,int len,char *digest)
27 MD5_CTX context;
28 MD5Init(&context);
29 MD5Update(&context, p, len);
30 MD5Final(digest, &context);
34 ** This functions makes the MD5 based data packet which is used to login,
35 ** logout and handle heartbeats
37 void makecredentials(char * credentials,struct session *s,INT2 msg,INT4 extra)
39 INT2 j = htons(msg);
40 int i=0;
41 char buffer[150];
42 INT4 ts = htonl(extra);
44 memcpy(buffer,s->nonce,16);
45 i += 16;
46 memcpy(buffer+i,s->password,strlen(s->password));
47 i += strlen(s->password);
48 memcpy(buffer+i,&(ts),sizeof(INT4));
49 i += sizeof(INT4);
50 memcpy(buffer+i,&j,sizeof(INT2));
51 i += sizeof(INT2);
53 genmd5(buffer,i,credentials);
57 ** Login to the Authentication server
59 ** Returns - 0 - failed to login for some reason.
60 ** 1 - Logged in successfully
62 int login(struct session * s)
64 int err;
65 char credentials[16];
66 time_t logintime;
68 int authsocket;
69 struct transaction t;
70 INT2 transactiontype;
71 int addrsize;
73 s->debug(0,"login(): init");
75 s->localaddr.sin_port = htons(0);
77 //=================================================================================================================
78 #if 0
79 syslog(LOG_DEBUG, "1=========================================T_MSG_LOGIN_REQ sending..."); //by tallest debug 0210
80 struct transaction ttt;
81 char datattt[]={0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x10
82 ,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x20
83 ,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x30
84 ,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x40
85 ,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x50
86 ,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x60
87 ,0x71,0x72,0x73,0x74};
88 ttt.length = 100;
89 memcpy(ttt.data, datattt, 100);
91 dump_transaction(s,&ttt);
92 s->debug(3, "2=========================================T_MSG_LOGIN_REQ sending..."); //by tallest debug 0210
93 #endif
94 //================================================================================================================
95 authsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
96 err = bind(authsocket,(struct sockaddr *)&s->localaddr,sizeof(struct sockaddr_in));
97 if(err)
99 socketerror(s,"Error binding auth socket");
100 closesocket(authsocket);
101 return 0;
104 err = connect(authsocket,(struct sockaddr *)&s->authhost,sizeof(struct sockaddr_in));
106 if(err)
108 socketerror(s,"Cant connect to auth server");
109 closesocket(authsocket);
110 return 0;
112 addrsize = sizeof(struct sockaddr_in);
113 err = getsockname(authsocket,(struct sockaddr *)&s->localipaddress,&addrsize);
116 ** start the negotiation
118 start_transaction(&t,T_MSG_PROTOCOL_NEG_REQ,s->sessionid);
119 add_field_INT2(s,&t,T_PARAM_CLIENT_VERSION,LOGIN_VERSION * 100);
120 add_field_string(s,&t,T_PARAM_OS_IDENTITY,s->osname);
121 add_field_string(s,&t,T_PARAM_OS_VERSION,s->osrelease);
122 add_field_INT2(s,&t,T_PARAM_PROTOCOL_LIST,T_PROTOCOL_CHAL);
124 s->debug(0,"tallest: T_MSG_PROTOCOL_NEG_REQ sending... "); //by tallest debug 0210
125 send_transaction(s,authsocket,&t);
127 transactiontype = receive_transaction(s,authsocket,&t);
128 if(transactiontype != T_MSG_PROTOCOL_NEG_RESP)
130 s->debug(0,"T_MSG_PROTOCOL_NEG_RESP - error transaction type (%d)",transactiontype);
131 return 0;
134 extract_valueINT2(s,&t,T_PARAM_STATUS_CODE,&s->retcode);
135 extract_valuestring(s,&t,T_PARAM_LOGIN_SERVER_HOST,s->loginserverhost);
136 extract_valueINT2(s,&t,T_PARAM_PROTOCOL_SELECT,&s->protocol);
138 if(s->protocol != T_PROTOCOL_CHAL)
140 s->debug(0,"T_MSG_PROTOCOL_NEG_RESP - Unsupported protocol (%d)",s->protocol);
141 return 0;
144 s->debug(0,"login(): retcode1 = [%d]\n", s->retcode);
146 switch(s->retcode)
148 case T_STATUS_SUCCESS:
149 case T_STATUS_LOGIN_SUCCESS_SWVER:
150 break;
151 case T_STATUS_LOGIN_FAIL_SWVER:
153 s->debug(0,"T_MSG_PROTOCOL_NEG_RESP - Login failure: software version");
154 return 0;
156 case T_STATUS_LOGIN_FAIL_INV_PROT:
158 s->debug(0,"T_MSG_PROTOCOL_NEG_RESP - Login failure: invalid protocol");
159 return 0;
161 case T_STATUS_LOGIN_UNKNOWN:
163 s->debug(0,"T_MSG_PROTOCOL_NEG_RESP - Login failure: unknown");
164 return 0;
168 closesocket(authsocket);
170 authsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
171 err = bind(authsocket,(struct sockaddr *)&s->localaddr,sizeof(struct sockaddr_in));
172 if(err)
174 socketerror(s,"Error binding auth socket 2");
175 closesocket(authsocket);
176 return 0;
178 err = connect(authsocket,(struct sockaddr *)&s->authhost,sizeof(struct sockaddr_in));
179 if(err)
181 socketerror(s,"Error connecting auth socket 2");
182 closesocket(authsocket);
183 return 0;
186 start_transaction(&t,T_MSG_LOGIN_REQ,s->sessionid);
187 add_field_string(s,&t,T_PARAM_USERNAME,s->username);
188 add_field_INT2(s,&t,T_PARAM_CLIENT_VERSION,LOGIN_VERSION * 100);
189 add_field_string(s,&t,T_PARAM_OS_IDENTITY,s->osname);
190 add_field_string(s,&t,T_PARAM_OS_VERSION,s->osrelease);
191 add_field_INT2(s,&t,T_PARAM_REASON_CODE,T_LOGIN_REASON_CODE_NORMAL);
192 add_field_INT2(s,&t,T_PARAM_REQ_PORT,s->listenport);
194 s->debug(0,"tallest: T_MSG_LOGIN_REQ sending... "); //by tallest debug 0210
195 send_transaction(s,authsocket,&t);
197 transactiontype = receive_transaction(s,authsocket,&t);
198 if(transactiontype == T_MSG_LOGIN_RESP)
199 goto skippo;
201 if(transactiontype != T_MSG_AUTH_RESP)
203 s->debug(0,"T_MSG_AUTH_RESP - error transaction type (%d)",transactiontype);
204 return 0;
207 if(!extract_valueINT2(s,&t,T_PARAM_HASH_METHOD,&s->hashmethod))
209 s->debug(0,"T_MSG_AUTH_RESP - no hashmethod provided");
210 return 0;
212 if(!extract_valuestring(s,&t,T_PARAM_NONCE,s->nonce))
214 s->debug(0,"T_MSG_AUTH_RESP - no nonce supplied");
215 return 0;
218 if(s->hashmethod == T_AUTH_MD5_HASH)
220 genmd5(s->password,strlen(s->password),s->password);
223 start_transaction(&t,T_MSG_LOGIN_AUTH_REQ,s->sessionid);
225 //s->timestamp = time(NULL);
226 s->timestamp = get_time(NULL);
227 makecredentials(credentials,s,T_MSG_LOGIN_AUTH_REQ,s->timestamp);
229 add_field_data(s,&t,T_PARAM_AUTH_CREDENTIALS,credentials,16);
230 add_field_INT4(s,&t,T_PARAM_TIMESTAMP,s->timestamp);
232 s->debug(0,"tallest: T_MSG_LOGIN_AUTH_REQ sending... "); //by tallest debug 0210
233 send_transaction(s,authsocket,&t);
235 transactiontype = receive_transaction(s,authsocket,&t);
236 skippo:
237 if(transactiontype != T_MSG_LOGIN_RESP)
239 s->debug(0,"T_MSG_LOGIN_RESP - error transaction type (%d)",transactiontype);
240 return 0;
243 extract_valueINT2(s,&t,T_PARAM_STATUS_CODE,&s->retcode);
244 s->debug(0,"login(): retcode2 = [%d]\n", s->retcode);
245 switch(s->retcode)
247 case T_STATUS_SUCCESS:
248 case T_STATUS_LOGIN_SUCCESSFUL_SWVER:
249 case T_STATUS_LOGIN_SUCCESSFUL_ALREADY_LOGGED_IN:
250 break;
251 case T_STATUS_USERNAME_NOT_FOUND:
253 s->debug(0,"T_MSG_LOGIN_RESP - Login failure: username not known");
254 log_to_file("AUTH_FAIL");
255 return 0;
257 case T_STATUS_INCORRECT_PASSWORD:
259 s->debug(0,"T_MSG_LOGIN_RESP - Login failure: incorrect password");
260 log_to_file("AUTH_FAIL");
261 return 0;
263 case T_STATUS_ACCOUNT_DISABLED:
265 s->debug(0,"T_MSG_LOGIN_RESP - Login failure: Account disabled");
266 log_to_file("AUTH_FAIL");
267 return 0;
269 case T_STATUS_LOGIN_RETRY_LIMIT:
270 case T_STATUS_USER_DISABLED:
271 case T_STATUS_FAIL_USERNAME_VALIDATE:
272 case T_STATUS_FAIL_PASSWORD_VALIDATE:
273 case T_STATUS_LOGIN_UNKNOWN:
275 s->debug(0,"T_MSG_LOGIN_RESP - Login failure: other error");
276 log_to_file("AUTH_FAIL");
277 return 0;
281 extract_valueINT2(s,&t,T_PARAM_LOGOUT_SERVICE_PORT,&s->logoutport);
282 extract_valueINT2(s,&t,T_PARAM_STATUS_SERVICE_PORT,&s->statusport);
283 extract_valuestring(s,&t,T_PARAM_TSMLIST,s->tsmlist);
284 extract_valuestring(s,&t,T_PARAM_RESPONSE_TEXT,s->resptext);
286 int i,n;
287 char * p = s->tsmlist;
288 char t[200];
289 char *tp = t;
290 s->tsmcount = 0;
292 while((n = strcspn(p," ,"))!=0)
294 strncpy(t,p,n);
295 t[n] = 0;
296 p += n +1;
297 strcpy(s->tsmlist_s[s->tsmcount],t);
298 strcat(s->tsmlist_s[s->tsmcount],s->authdomain);
299 s->tsmcount++;
301 for(i=0;i<s->tsmcount;i++)
303 struct hostent * he;
305 he = gethostbyname(s->tsmlist_s[i]);
306 if(he)
308 s->tsmlist_in[i].sin_addr.s_addr = *((int*)(he->h_addr_list[0]));
310 else
312 //s->tsmlist_in[i].sin_addr.s_addr = inet_addr(s->tsmlist_s[i]);
313 s->tsmlist_in[i].sin_addr.s_addr = inet_addr(s->authserver);
315 s->debug(1,"Will accept heartbeats from %s = %s\n",s->tsmlist_s[i],inet_ntoa(s->tsmlist_in[i].sin_addr));
318 logintime = get_time(NULL);
320 s->debug(0,"Logged on as %s - successful at %d\n",s->username, logintime);
321 s->sequence = 0;
322 //s->lastheartbeat = time(NULL);
323 s->lastheartbeat = get_time(NULL);
324 s->recenthb = 0;
326 closesocket(authsocket);
327 s->debug(0,"login(): end");
328 return 1;
331 //=========================== by tallest ==============================================
334 ** Login to the Authentication server
336 ** Returns - 0 - failed to reauth for some reason.
337 ** 1 - Logged in successfully
339 #if 1
340 int re_auth(struct session * s)
342 int err;
343 char credentials[16];
344 time_t logintime;
346 int authsocket;
347 struct transaction t;
348 INT2 transactiontype;
349 int addrsize;
351 s->debug(0,"Re-authentication(): init");
353 s->localaddr.sin_port = htons(0);
355 authsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
356 err = bind(authsocket,(struct sockaddr *)&s->localaddr,sizeof(struct sockaddr_in));
357 if(err)
359 socketerror(s,"Re-authentication Error binding auth socket");
360 closesocket(authsocket);
361 return 0;
364 err = connect(authsocket,(struct sockaddr *)&s->authhost,sizeof(struct sockaddr_in));
366 if(err)
368 socketerror(s,"Re-authentication Cant connect to auth server");
369 closesocket(authsocket);
370 return 0;
372 addrsize = sizeof(struct sockaddr_in);
373 err = getsockname(authsocket,(struct sockaddr *)&s->localipaddress,&addrsize);
375 authsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
376 err = bind(authsocket,(struct sockaddr *)&s->localaddr,sizeof(struct sockaddr_in));
377 if(err)
379 socketerror(s,"Re-authentication Error binding auth socket 2");
380 closesocket(authsocket);
381 return 0;
383 err = connect(authsocket,(struct sockaddr *)&s->authhost,sizeof(struct sockaddr_in));
384 if(err)
386 socketerror(s,"Re-authentication Error connecting auth socket 2");
387 closesocket(authsocket);
388 return 0;
391 start_transaction(&t,T_MSG_LOGIN_REQ,s->sessionid);
392 add_field_string(s,&t,T_PARAM_USERNAME,s->username);
393 add_field_INT2(s,&t,T_PARAM_CLIENT_VERSION,LOGIN_VERSION * 100);
394 add_field_string(s,&t,T_PARAM_OS_IDENTITY,s->osname);
395 add_field_string(s,&t,T_PARAM_OS_VERSION,s->osrelease);
396 add_field_INT2(s,&t,T_PARAM_REASON_CODE,T_LOGIN_REASON_CODE_NORMAL);
397 add_field_INT2(s,&t,T_PARAM_REQ_PORT,s->listenport);
399 s->debug(0,"tallest: Re-authentication T_MSG_LOGIN_REQ sending... "); //by tallest debug 0210
400 send_transaction(s,authsocket,&t);
402 transactiontype = receive_transaction(s,authsocket,&t);
403 if(transactiontype == T_MSG_LOGIN_RESP)
404 goto skip_re_auth;
406 if(transactiontype != T_MSG_AUTH_RESP)
408 s->debug(0,"Re-authentication T_MSG_AUTH_RESP - error transaction type (%d)",transactiontype);
409 return 0;
412 if(!extract_valueINT2(s,&t,T_PARAM_HASH_METHOD,&s->hashmethod))
414 s->debug(0,"Re-authentication T_MSG_AUTH_RESP - no hashmethod provided");
415 return 0;
417 if(!extract_valuestring(s,&t,T_PARAM_NONCE,s->nonce))
419 s->debug(0,"Re-authentication T_MSG_AUTH_RESP - no nonce supplied");
420 return 0;
423 if(s->hashmethod == T_AUTH_MD5_HASH)
425 genmd5(s->password,strlen(s->password),s->password);
428 start_transaction(&t,T_MSG_LOGIN_AUTH_REQ,s->sessionid);
430 s->timestamp = get_time(NULL);
431 makecredentials(credentials,s,T_MSG_LOGIN_AUTH_REQ,s->timestamp);
433 add_field_data(s,&t,T_PARAM_AUTH_CREDENTIALS,credentials,16);
434 add_field_INT4(s,&t,T_PARAM_TIMESTAMP,s->timestamp);
436 s->debug(0,"tallest:Re-authentication T_MSG_LOGIN_AUTH_REQ sending... "); //by tallest debug 0210
437 send_transaction(s,authsocket,&t);
439 transactiontype = receive_transaction(s,authsocket,&t);
440 skip_re_auth:
441 if(transactiontype != T_MSG_LOGIN_RESP)
443 s->debug(0,"Re-authentication T_MSG_LOGIN_RESP - error transaction type (%d)",transactiontype);
444 return 0;
447 extract_valueINT2(s,&t,T_PARAM_STATUS_CODE,&s->retcode);
448 s->debug(0,"Re-authentication(): retcode2 = [%d]\n", s->retcode);
449 switch(s->retcode)
451 case T_STATUS_SUCCESS:
452 case T_STATUS_LOGIN_SUCCESSFUL_SWVER:
453 case T_STATUS_LOGIN_SUCCESSFUL_ALREADY_LOGGED_IN:
454 break;
455 case T_STATUS_USERNAME_NOT_FOUND:
457 s->debug(0,"Re-authentication T_MSG_LOGIN_RESP - Login failure: username not known");
458 log_to_file("AUTH_FAIL");
459 return 0;
461 case T_STATUS_INCORRECT_PASSWORD:
463 s->debug(0,"Re-authentication T_MSG_LOGIN_RESP - Login failure: incorrect password");
464 log_to_file("AUTH_FAIL");
465 return 0;
467 case T_STATUS_ACCOUNT_DISABLED:
469 s->debug(0,"Re-authentication T_MSG_LOGIN_RESP - Login failure: Account disabled");
470 log_to_file("AUTH_FAIL");
471 return 0;
473 case T_STATUS_LOGIN_RETRY_LIMIT:
474 case T_STATUS_USER_DISABLED:
475 case T_STATUS_FAIL_USERNAME_VALIDATE:
476 case T_STATUS_FAIL_PASSWORD_VALIDATE:
477 case T_STATUS_LOGIN_UNKNOWN:
479 s->debug(0,"Re-authentication T_MSG_LOGIN_RESP - Login failure: other error");
480 log_to_file("AUTH_FAIL");
481 return 0;
485 extract_valueINT2(s,&t,T_PARAM_LOGOUT_SERVICE_PORT,&s->logoutport);
486 extract_valueINT2(s,&t,T_PARAM_STATUS_SERVICE_PORT,&s->statusport);
487 extract_valuestring(s,&t,T_PARAM_TSMLIST,s->tsmlist);
488 extract_valuestring(s,&t,T_PARAM_RESPONSE_TEXT,s->resptext);
490 int i,n;
491 char * p = s->tsmlist;
492 char t[200];
493 char *tp = t;
494 s->tsmcount = 0;
496 while((n = strcspn(p," ,"))!=0)
498 strncpy(t,p,n);
499 t[n] = 0;
500 p += n +1;
501 strcpy(s->tsmlist_s[s->tsmcount],t);
502 strcat(s->tsmlist_s[s->tsmcount],s->authdomain);
503 s->tsmcount++;
505 for(i=0;i<s->tsmcount;i++)
507 struct hostent * he;
509 he = gethostbyname(s->tsmlist_s[i]);
510 if(he)
512 s->tsmlist_in[i].sin_addr.s_addr = *((int*)(he->h_addr_list[0]));
514 else
516 s->tsmlist_in[i].sin_addr.s_addr = inet_addr(s->authserver);
518 s->debug(1,"Re-authentication Will accept heartbeats from %s = %s\n",s->tsmlist_s[i],inet_ntoa(s->tsmlist_in[i].sin_addr));
521 logintime = get_time(NULL);
523 s->debug(0,"Re-authentication as %s - successful at %d\n",s->username, logintime);
524 s->lastheartbeat = get_time(NULL);
525 s->recenthb = 0;
527 closesocket(authsocket);
528 s->debug(0,"Re-authentication (): end");
529 return 1;
531 #endif
533 //=========================================================================
536 ** Handle heartbeats, wait for the following events to happen -
538 ** 1. A heartbeat packet arrives, in which case we reply correctly
539 ** 2. A timeout occured (ie no heartbeat arrived within 7 minutes)
540 ** 3. The socket was closed.
542 ** Returns - 0 - Heartbeat timeout, and subsequent login failed to connect
543 ** 1 - Socket closed on us, presuming the user wants to shut down.
545 int handle_heartbeats(struct session *s)
547 INT2 transactiontype;
548 struct transaction t;
550 while(1)
552 transactiontype = receive_udp_transaction(s,s->listensock,&t,&s->fromaddr);
554 if(transactiontype == 0xffff)
556 s->debug(0,"Timed out waiting for heartbeat - logging on\n");
557 //if(!login(s))
558 if(!re_auth(s))
559 return 0;
561 else if(transactiontype == 0xfffd)
563 s->debug(0,"Badly structured packet received - discarding\n");
565 else if(transactiontype == 0xfffe)
567 s->debug(0,"Socket closed - shutting down\n");
568 return 1;
570 else if(transactiontype == T_MSG_STATUS_REQ)
572 char buf[16];
574 start_transaction(&t,T_MSG_STATUS_RESP,s->sessionid);
575 add_field_INT2(s,&t,T_PARAM_STATUS_CODE,T_STATUS_TRANSACTION_OK);
577 s->sequence++;
578 makecredentials(buf,s,T_MSG_STATUS_RESP,s->sequence);
579 add_field_data(s,&t,T_PARAM_STATUS_AUTH,buf,16);
580 add_field_INT4(s,&t,T_PARAM_SEQNUM,s->sequence);
582 s->debug(1,"tallest: T_MSG_STATUS_RESP(UDP) sending...\n"); //by tallest debug 0210
583 send_udp_transaction(s,&t);
585 //s->lastheartbeat = time(NULL);
586 s->lastheartbeat = get_time(NULL);
588 s->debug(1,"Responded to heartbeat at %d\n", s->lastheartbeat);
590 else if(transactiontype == T_MSG_RESTART_REQ)
592 s->debug(0,"Restart request - unimplemented");
593 return 0;
595 else
598 ** Melbourne servers were sending spurious UDP packets after authentication
599 ** This works around it.
601 s->debug(0,"Unknown heartbeat message %d ",transactiontype);
605 ** Should never get here
607 return 0;
611 ** Logout of the BIDS2 system
613 ** Returns - 0 - Could not connect to logout.
614 ** 1 - Logout successful.
616 int logout(INT2 reason,struct session * s)
618 int err;
619 char credentials[16];
620 time_t logintime;
622 int authsocket;
623 struct transaction t;
624 INT2 transactiontype;
626 s->debug(0,"logout(): init");
628 s->localaddr.sin_port = htons(0);
629 authsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
630 err = bind(authsocket,(struct sockaddr *)&s->localaddr,sizeof(struct sockaddr_in));
631 if(err)
633 socketerror(s,"Error binding logout auth socket");
634 closesocket(authsocket);
635 return 0;
637 err = connect(authsocket,(struct sockaddr *)&s->authhost,sizeof(struct sockaddr_in));
638 if(err)
640 socketerror(s,"Error connecting logout auth socket");
641 closesocket(authsocket);
642 return 0;
646 ** start the negotiation
648 start_transaction(&t,T_MSG_LOGOUT_REQ,s->sessionid);
649 add_field_string(s,&t,T_PARAM_USERNAME,s->username);
650 add_field_INT2(s,&t,T_PARAM_CLIENT_VERSION,LOGIN_VERSION * 100);
651 add_field_string(s,&t,T_PARAM_OS_IDENTITY,s->osname);
652 add_field_string(s,&t,T_PARAM_OS_VERSION,s->osrelease);
653 add_field_INT2(s,&t,T_PARAM_REASON_CODE,reason);
655 s->debug(0,"tallest: T_MSG_LOGOUT_REQ sending... "); //by tallest debug 0210
656 send_transaction(s,authsocket,&t);
658 transactiontype = receive_transaction(s,authsocket,&t);
659 if(transactiontype != T_MSG_AUTH_RESP)
661 s->critical("logic error");
664 if(!extract_valueINT2(s,&t,T_PARAM_HASH_METHOD,&s->hashmethod))
666 s->critical("AUTH: no hashmethod");
668 if(!extract_valuestring(s,&t,T_PARAM_NONCE,s->nonce))
670 s->critical("Auth: no nonce");
673 if(s->hashmethod == T_AUTH_MD5_HASH)
675 genmd5(s->password,strlen(s->password),s->password);
678 start_transaction(&t,T_MSG_LOGOUT_AUTH_RESP,s->sessionid);
680 //s->timestamp = time(NULL);
681 s->timestamp = get_time(NULL);
682 makecredentials(credentials,s,T_MSG_LOGOUT_AUTH_RESP,s->timestamp);
684 add_field_data(s,&t,T_PARAM_AUTH_CREDENTIALS,credentials,16);
685 add_field_INT4(s,&t,T_PARAM_TIMESTAMP,s->timestamp);
687 s->debug(0,"tallest: T_MSG_LOGOUT_AUTH_RESP sending... "); //by tallest debug 0210
688 send_transaction(s,authsocket,&t);
690 transactiontype = receive_transaction(s,authsocket,&t);
691 if(transactiontype != T_MSG_LOGOUT_RESP)
693 s->critical("logic error");
696 extract_valueINT2(s,&t,T_PARAM_STATUS_CODE,&s->retcode);
698 s->debug(0,"logout(): retcode = [%d]", s->retcode);
699 switch(s->retcode)
701 case T_STATUS_SUCCESS:
702 case T_STATUS_LOGOUT_SUCCESSFUL_ALREADY_DISCONNECTED:
703 break;
704 case T_STATUS_USERNAME_NOT_FOUND:
705 s->critical("Login failure: username not known");
706 case T_STATUS_INCORRECT_PASSWORD:
707 s->critical("Login failure: incorrect password");
708 case T_STATUS_ACCOUNT_DISABLED:
709 s->critical("Login failure: disabled");
710 case T_STATUS_LOGIN_RETRY_LIMIT:
711 case T_STATUS_USER_DISABLED:
712 case T_STATUS_FAIL_USERNAME_VALIDATE:
713 case T_STATUS_FAIL_PASSWORD_VALIDATE:
714 case T_STATUS_LOGIN_UNKNOWN:
715 s->critical("Login failure: other error");
718 extract_valueINT2(s,&t,T_PARAM_LOGOUT_SERVICE_PORT,&s->logoutport);
719 extract_valueINT2(s,&t,T_PARAM_STATUS_SERVICE_PORT,&s->statusport);
720 extract_valuestring(s,&t,T_PARAM_TSMLIST,s->tsmlist);
721 extract_valuestring(s,&t,T_PARAM_RESPONSE_TEXT,s->resptext);
723 //logintime = time(NULL);
724 logintime = get_time(NULL);
726 s->debug(0,"Logged out successful at %d\n",logintime);
728 closesocket(authsocket);
730 s->debug(0,"logout(): end");
732 return 1;