comparison src/g23m-fad/ppp/ppp_capf.c @ 174:90eb61ecd093

src/g23m-fad: initial import from TCS3.2/LoCosto
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 12 Oct 2016 05:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
173:bf64d785238a 174:90eb61ecd093
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul :
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This modul is part of the entity PPP and implements all
18 | procedures and functions as described in the
19 | SDL-documentation (CHAP-statemachine)
20 +-----------------------------------------------------------------------------
21 */
22
23 #ifndef PPP_CAPF_C
24 #define PPP_CAPF_C
25 #endif /* !PPP_CAPF_C */
26
27 #define ENTITY_PPP
28
29 /*==== INCLUDES =============================================================*/
30
31 #include "typedefs.h" /* to get Condat data types */
32 #include "vsi.h" /* to get a lot of macros */
33 #include "macdef.h" /* to get a lot of macros */
34 #include "custom.h" /* to get a lot of macros */
35 #include "gsm.h" /* to get a lot of macros */
36 #include "cnf_ppp.h" /* to get cnf-definitions */
37 #include "mon_ppp.h" /* to get mon-definitions */
38 #include "prim.h" /* to get the definitions of used SAP and directions */
39 #include "dti.h" /* to get the DTILIB definitions */
40 #include "ppp.h" /* to get the global entity definitions */
41
42 #include "ppp_arbf.h" /* to get function interface from arb */
43 #include <string.h> /* to get memcpy */
44 #include <stdlib.h> /* to get rand */
45 #include "cl_md5.h" /* to get MD5 routine from common library */
46
47 #ifdef _SIMULATION_
48 #include <stdio.h> /* to get sprintf */
49 #endif /* _SIMULATION_ */
50
51 /*==== CONST ================================================================*/
52
53 #define CHAP_SUCCESS_LENGTH (4)
54 #define CHAP_CHALLENGE_HEADER_SIZE (5)
55
56 /*
57 * maximum value length is 64 octets and additional packet header is 5 octets
58 */
59 #define CHAP_CHALLENGE_LEN_MAX_SERVER_MODE (64 + CHAP_CHALLENGE_HEADER_SIZE)
60 /*
61 * maximum value length is 5 octets for packet header + 16 octets for hash value
62 * calculated by MD5 algorithm + login name length
63 */
64
65 #define CHAP_RESPONSE_LEN_MAX_CLIENT_MODE (CHAP_CHALLENGE_HEADER_SIZE + \
66 CHAP_MSG_DIGEST_LEN + \
67 PPP_LOGIN_NAME_LENGTH)
68
69 /*
70 * the response packet must be passable to the ISP in protocol configuration
71 * options (pco). The maximum length of pco is
72 * 251 octets (253 - 2 (identification overhead) = 251). There must also be
73 * space for other protocol packet, like LCP and IPCP.
74 * LCP needs
75 * 15 octets (3 (overhead pco) + 4 (overhead packet) + 4 (mru) + 4
76 * (authentication protocol PAP) = 15) for server packet and
77 * 11 octets (3 (overhead pco) + 4 (overhead packet) + 4 (mru) = 11) for
78 * client packet.
79 * IPCP needs
80 * 31 octets (3 (overhead pco) + 4 (overhead packet) + 6 (IP address) + 6
81 * (VJ header compression) + 6 (primary DNS) + 6 (secondary DNS) = 31) for
82 * client packet and
83 * 13 octets (3 (overhead pco) + 4 (overhead packet) + 6
84 * (Gateway address) = 13) for gateway address packet.
85 * CHAP needs
86 * 3 octets for pco overhead and
87 * CHAP_CHALLENGE_LENGTH_MAX for challenge packet and
88 * 3 octets for pco overhead for response packet.
89 * The max. user login name legth is
90 * - for client mode 25 octets
91 * - for server mode
92 */
93 #define CHAP_RESPONSE_LEN_MAX_SERVER_MODE (251 - 15 - 11 - 31 - 13 - 3 - \
94 CHAP_CHALLENGE_LEN_MAX_SERVER_MODE\
95 - 3)
96 #define CHAP_CHALLENGE_LEN_MAX_CLIENT_MODE (251 - 15 - 11 - 31 - 13 - 3 - \
97 CHAP_RESPONSE_LEN_MAX_CLIENT_MODE\
98 - 3)
99
100
101 #define CHAP_FAILURE_TEXT "response packet to long"
102 #define CHAP_FAILURE_TEXT_LENGTH sizeof(CHAP_FAILURE_TEXT)
103 #define CHAP_FAILURE_LENGTH (4 + CHAP_FAILURE_TEXT_LENGTH)
104
105
106 /*==== LOCAL VARS ===========================================================*/
107
108 /*==== PRIVATE FUNCTIONS ====================================================*/
109
110 /*==== PUBLIC FUNCTIONS =====================================================*/
111
112
113
114 /*
115 +------------------------------------------------------------------------------
116 | Function : chap_init
117 +------------------------------------------------------------------------------
118 | Description : The function chap_init() initializes Challenge Handshake
119 | Authentication Protocol
120 |
121 | Parameters : no parameter
122 |
123 +------------------------------------------------------------------------------
124 */
125 GLOBAL void chap_init ()
126 {
127 T_TIME time_val;
128
129 TRACE_FUNCTION( "chap_init" );
130
131 /*
132 * initialize random generator
133 */
134 vsi_t_time (VSI_CALLER &time_val);
135 srand((USHORT) time_val);
136 /*
137 * initialize values
138 */
139 ppp_data->chap.counter = 0; /* counter for timer restart */
140 ppp_data->chap.nci = 0; /* new challenge identifier */
141 ppp_data->chap.sc = FALSE; /* indic. for sending of Challenge packet*/
142 ppp_data->chap.rc = FALSE; /* indic. for receiving of Challenge pack*/
143 ppp_data->chap.sr = FALSE; /* indic. for sending of Respons packet */
144 ppp_data->chap.rs = FALSE; /* indic. for receiving of Success packet */
145 ppp_data->chap.c_packet = NULL; /* CHAP Challenge packet (server mode) */
146 ppp_data->chap.r_packet = NULL; /* CHAP Response packet (server mode) */
147 /* CHAP and PAP authentication values */
148 memset((UBYTE*)&ppp_data->login, 0, sizeof(T_login));
149
150 /*
151 * Set CHAP service state to CHAP_DOWN
152 */
153 INIT_STATE( PPP_SERVICE_CHAP , CHAP_DOWN );
154
155 } /* chap_init() */
156
157
158
159 /*
160 +------------------------------------------------------------------------------
161 | Function : chap_fill_out_packet
162 +------------------------------------------------------------------------------
163 | Description : The function chap_fill_out_packet() puts a CHAP Challenge and
164 | a CHAP Response packet into the protocol configuration list
165 |
166 | Parameters : pco_buf - pco list buffer
167 | ptr_pos - position where to write the CHAP packets, this value
168 | must get back to the calling funtion
169 |
170 +------------------------------------------------------------------------------
171 */
172 GLOBAL void chap_fill_out_packet (UBYTE pco_buf[], USHORT* ptr_pos)
173 {
174 USHORT pos;
175
176 TRACE_FUNCTION( "chap_fill_out_packet" );
177
178 #ifdef _SIMULATION_
179 TRACE_EVENT_P3("parameters: pco_buf[]: %08x, ptr_pos: %08x, pos: %d",
180 pco_buf, ptr_pos, *ptr_pos);
181 #endif /* _SIMULATION_ */
182 /*
183 * copy stored challenge packet
184 */
185 /*
186 * Protocol ID
187 */
188 pos = *ptr_pos;
189 pco_buf[pos] = PROTOCOL_CHAP_MSB;
190 pos++;
191 pco_buf[pos] = PROTOCOL_CHAP_LSB;
192 pos++;
193 /*
194 * Length of Protocol contents
195 */
196 pco_buf[pos] = (UBYTE)ppp_data->chap.c_packet->len;
197 pos++;
198 /*
199 * copy packet
200 */
201 memcpy(&pco_buf[pos],
202 ppp_data->chap.c_packet->buffer,
203 ppp_data->chap.c_packet->len);
204 pos += ppp_data->chap.c_packet->len;
205 /*
206 * copy stored response packet
207 */
208 /*
209 * Protocol ID
210 */
211 pco_buf[pos] = PROTOCOL_CHAP_MSB;
212 pos++;
213 pco_buf[pos] = PROTOCOL_CHAP_LSB;
214 pos++;
215 /*
216 * Length of Protocol contents
217 */
218 pco_buf[pos] = (UBYTE)ppp_data->chap.r_packet->len;
219 pos++;
220 /*
221 * copy packet
222 */
223 memcpy(&pco_buf[pos],
224 ppp_data->chap.r_packet->buffer,
225 ppp_data->chap.r_packet->len);
226 pos += ppp_data->chap.r_packet->len;
227 /*
228 * Free memory and clear flags
229 */
230 arb_discard_packet(ppp_data->chap.r_packet);
231 ppp_data->chap.r_packet = NULL;
232 ppp_data->chap.sr = FALSE;
233 arb_discard_packet(ppp_data->chap.c_packet);
234 ppp_data->chap.c_packet = NULL;
235 ppp_data->chap.rc = FALSE;
236
237 /*
238 * return new position
239 */
240 *ptr_pos=pos;
241 } /* chap_fill_out_packet() */
242
243
244
245 /*
246 +------------------------------------------------------------------------------
247 | Function : chap_get_sc
248 +------------------------------------------------------------------------------
249 | Description : The function chap_get_sc() returns a CHAP Challenge packet and
250 | stores a copy of this packet.
251 |
252 | Parameters : ptr_packet - returns the Challenge packet
253 | THE MEMORY FOR THE PACKET WILL BE ALLOCATED BY
254 | THIS FUNCTION
255 |
256 +------------------------------------------------------------------------------
257 */
258 GLOBAL void chap_get_sc (T_desc2** ptr_packet)
259 {
260 T_desc2* ret_desc;
261 USHORT len_pos;
262 USHORT pos;
263 UBYTE i;
264 UBYTE value_size;
265
266 TRACE_FUNCTION( "chap_get_sc" );
267 /*
268 * set new identifier
269 */
270 ppp_data->chap.nci++;
271 /*
272 * random value length 16 to 64 octets
273 */
274 #ifdef _SIMULATION_
275 value_size = 16;
276 #else /* _SIMULATION_ */
277 value_size = (UBYTE)(rand() % 49) + 16;
278 #endif /* _SIMULATION_ */
279 /*
280 * Allocate the necessary size for the data descriptor. The size is
281 * calculated as follows:
282 * - take the size of a descriptor structure
283 * - subtract one because of the array buffer[1] to get the size of
284 * descriptor control information
285 * - add number of octets of descriptor data (value+header)
286 */
287 MALLOC(ret_desc, (USHORT)(sizeof(T_desc2) - 1
288 + value_size + CHAP_CHALLENGE_HEADER_SIZE));
289 /*
290 * fill the packet
291 */
292 ret_desc->next = (ULONG)NULL;
293 pos = 0;
294 /*
295 * Code field
296 */
297 ret_desc->buffer[pos] = CODE_CHALLENGE;
298 pos++;
299 /*
300 * Identifier field
301 */
302 ret_desc->buffer[pos] = ppp_data->chap.nci;/*lint !e415 (Warning -- access of out-of-bounds pointer) */
303 pos++;
304 /*
305 * Length field (store the position)
306 */
307 len_pos = pos;
308 pos++;
309 pos++;
310 /*
311 * value length
312 */
313 ret_desc->buffer[pos] = value_size;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
314 pos++;
315 /*
316 * values
317 */
318 for(i=0; i < value_size; i++)
319 {
320 #ifdef _SIMULATION_
321 ret_desc->buffer[pos] = (UBYTE)(i);
322 #else /* _SIMULATION_ */
323 ret_desc->buffer[pos] = (UBYTE)(rand() & 0xff);/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */
324 #endif /* _SIMULATION_ */
325 pos++;
326 }
327 /*
328 * insert packet length
329 */
330 ret_desc->len = pos;
331 ret_desc->buffer[len_pos] = (UBYTE)(pos >> 8);/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */
332 len_pos++;
333 ret_desc->buffer[len_pos] = (UBYTE)(pos & 0x00ff);/*lint !e661 !e662 (Warning -- Possible access/creation of out-of-bounds pointer) */
334 /*
335 * create second packet to store the values
336 */
337 arb_discard_packet(ppp_data->chap.c_packet);
338 MALLOC (ppp_data->chap.c_packet, (USHORT)(sizeof(T_desc2) - 1
339 + value_size + CHAP_CHALLENGE_HEADER_SIZE));
340 /*
341 * make a copy of the first packet
342 */
343 ppp_data->chap.c_packet->next = ret_desc->next;
344 ppp_data->chap.c_packet->len = ret_desc->len;
345 memcpy(ppp_data->chap.c_packet->buffer, ret_desc->buffer, ret_desc->len);
346 /*
347 * return the first packet
348 */
349 ppp_data->chap.sc = TRUE;
350 *ptr_packet = ret_desc;
351
352 } /* chap_get_sc() */
353
354 /*
355 +------------------------------------------------------------------------------
356 | Function : chap_get_sr
357 +------------------------------------------------------------------------------
358 | Description : The function chap_get_sr() returns a CHAP Response packet and
359 | stores a copy of this packet.
360 |
361 | Parameters : ptr_packet - returns the Response packet
362 | THE MEMORY FOR THE PACKET WILL BE ALLOCATED BY
363 | THIS FUNCTION
364 |
365 +------------------------------------------------------------------------------
366 */
367 GLOBAL void chap_get_sr (T_desc2** ptr_packet)
368 {
369 T_desc2 *ret_packet, *md5_pack;
370 USHORT len_pos;
371 USHORT md5_len;
372 USHORT pos;
373 UBYTE value_size;
374 T_desc2* packet = *ptr_packet;
375
376 TRACE_FUNCTION( "chap_get_sr" );
377
378 /*
379 * Allocate the necessary size for the data descriptor. The size is
380 * calculated as follows:
381 * - take the size of a descriptor structure
382 * - subtract one because of the array buffer[1] to get the size of
383 * descriptor control information
384 * - add number of octets of descriptor data
385 */
386 MALLOC(ret_packet, (USHORT)(sizeof(T_desc2) - 1 + CHAP_MSG_DIGEST_LEN
387 + ppp_data->login.name_len));
388 /*
389 * fill the packet
390 */
391 ret_packet->next = (ULONG)NULL;
392 pos = 0;
393 /*
394 * Code field
395 */
396 ret_packet->buffer[pos] = CODE_RESPONSE;
397 pos++;
398 /*
399 * Identifier field
400 */
401 ret_packet->buffer[pos] = ppp_data->chap.nci;/*lint !e415 (Warning -- access of out-of-bounds pointer) */
402 pos++;
403 /*
404 * Length field (store the position)
405 */
406 len_pos = pos;
407 pos++;
408 pos++;
409 /*
410 * Value length: output of MD5 routine is always
411 * CHAP_MSG_DIGEST_LEN := 16 Bytes
412 */
413 value_size = CHAP_MSG_DIGEST_LEN;
414 ret_packet->buffer[pos] = value_size;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
415 pos++;
416
417 /*
418 * Values
419 * Message digest
420 */
421 md5_len = 1 + ppp_data->login.password_len + packet->buffer[4];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
422 MALLOC(md5_pack, (USHORT)(sizeof(T_desc2) - 1 + md5_len));
423
424 /*
425 * Build string to pass to MD5 routine:
426 * identifier + user password + challenge message
427 */
428 md5_pack->buffer[0] = ppp_data->chap.nci;
429 memcpy(&md5_pack->buffer[1], ppp_data->login.password,
430 ppp_data->login.password_len);
431 memcpy(&md5_pack->buffer[ppp_data->login.password_len+1],
432 &packet->buffer[5], packet->buffer[4]);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
433 /*
434 * Call MD5 routine
435 */
436 cl_md5(md5_pack->buffer, md5_len, &ret_packet->buffer[pos]);/*lint !e416 (Warning -- creation of out-of-bounds pointer) */
437 pos += CHAP_MSG_DIGEST_LEN;
438 MFREE(md5_pack);
439 /*
440 * insert user name
441 */
442 memcpy(&ret_packet->buffer[pos], ppp_data->login.name,
443 ppp_data->login.name_len);/*lint !e416 (Warning -- creation of out-of-bounds pointer) */
444 pos += ppp_data->login.name_len;
445 /*
446 * insert packet length
447 */
448 ret_packet->len = pos;
449 ret_packet->buffer[len_pos] = (UBYTE)(pos >> 8);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
450 len_pos++;
451 ret_packet->buffer[len_pos] = (UBYTE)(pos & 0x00ff);/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
452
453 /*
454 * return the first packet
455 */
456 ppp_data->chap.sr = TRUE;
457 *ptr_packet = ret_packet;
458
459 } /* chap_get_sr() */
460
461
462 /*
463 +------------------------------------------------------------------------------
464 | Function : chap_get_ss
465 +------------------------------------------------------------------------------
466 | Description : The function chap_get_ss() returns a CHAP Success packet.
467 |
468 | Parameters : ptr_packet - returns the CHAP Success packet
469 | THE MEMORY FOR THE PACKET WILL BE ALLOCATED BY
470 | THIS FUNCTION
471 |
472 +------------------------------------------------------------------------------
473 */
474 GLOBAL void chap_get_ss (T_desc2** ptr_packet)
475 {
476 T_desc2* packet;
477 USHORT pos;
478
479 TRACE_FUNCTION( "chap_get_ss" );
480
481 /*
482 * Allocate the necessary size for the data descriptor. The size is
483 * calculated as follows:
484 * - take the size of a descriptor structure
485 * - subtract one because of the array buffer[1] to get the size of
486 * descriptor control information
487 * - add number of octets of descriptor data
488 */
489 MALLOC (packet, (USHORT)(sizeof(T_desc2) - 1 + CHAP_SUCCESS_LENGTH));
490 packet->len = CHAP_SUCCESS_LENGTH;
491 packet->next=(ULONG)NULL;
492 pos=0;
493 /*
494 * code field
495 */
496 packet->buffer[pos] = CODE_SUCCESS;
497 pos++;
498 /*
499 * identifier field
500 */
501 packet->buffer[pos] = ppp_data->chap.nci;/*lint !e415 (Warning -- creation of out-of-bounds pointer) */
502 pos++;
503 /*
504 * length field
505 */
506 packet->buffer[pos] = 0;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
507 pos++;
508 packet->buffer[pos] = CHAP_SUCCESS_LENGTH;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
509 /*
510 * return created packet
511 */
512 *ptr_packet = packet;
513 /*
514 * Announce successful CHAP authentification
515 */
516 TRACE_EVENT("PPP CHAP: authentification successful");
517 } /* chap_get_ss() */
518
519
520
521 /*
522 +------------------------------------------------------------------------------
523 | Function : chap_rc
524 +------------------------------------------------------------------------------
525 | Description : The function chap_rc() checks whether the given Challenge
526 | packet is valid and if so it returns FORWARD_RC and a
527 | Response packet.
528 |
529 | Parameters : ptr_packet - Challenge packet
530 | forward - returns result of analysis
531 |
532 +------------------------------------------------------------------------------
533 */
534 GLOBAL void chap_rc (T_desc2** ptr_packet, UBYTE* forward)
535 {
536 T_desc2* packet;
537 USHORT packet_len;
538 USHORT pos;
539
540 TRACE_FUNCTION( "chap_rc" );
541
542 /*
543 * this packet can only be reveiced in client mode
544 */
545 if(ppp_data->mode NEQ PPP_CLIENT)
546 {
547 TRACE_EVENT("PPP CHAP: unexpected CHAP challenge packet in client mode");
548 *forward=FORWARD_DISCARD;
549 return;
550 }
551 /*
552 * check correct length
553 */
554 packet = *ptr_packet;
555 packet_len = packet->buffer[2] << 8;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
556 packet_len |= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
557 if((packet_len < 5) || (packet_len > packet->len))
558 {
559 TRACE_EVENT("PPP CHAP: invalid CHAP challenge packet length");
560 *forward=FORWARD_DISCARD;
561 return;
562 }
563 /*
564 * check consistence of length of packet and length of log on information,
565 */
566 pos=4;
567 pos+= packet->buffer[pos];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
568 pos++;
569 if(pos > packet_len || packet_len > CHAP_CHALLENGE_LEN_MAX_CLIENT_MODE)
570 {
571 TRACE_EVENT_P1("PPP CHAP: invalid value size %d in CHAP challenge packet",
572 packet_len);
573 *forward=FORWARD_DISCARD;
574 return;
575 }
576 /*
577 * Check if challenge was received already, the length are equal,
578 * the identifier wasn't change or if the challenge value is the same
579 * to the packet before.
580 */
581 if((ppp_data->chap.rc) &&
582 (packet->buffer[4] EQ ppp_data->chap.c_packet->buffer[4]))/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
583 {
584 if((ppp_data->chap.nci EQ packet->buffer[1]) ||
585 (!memcmp(&packet->buffer[5],
586 &ppp_data->chap.c_packet->buffer[5],
587 packet->buffer[4])))/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
588 {
589 TRACE_EVENT("PPP CHAP: repeated CHAP challenge packet");
590 *forward=FORWARD_DISCARD;
591 return;
592 }
593 }
594
595 /*
596 * store identifier
597 */
598 ppp_data->chap.nci = packet->buffer[1];/*lint !e415 (Warning -- creation of out-of-bounds pointer) */
599 /*
600 * store challenge packet
601 */
602 arb_discard_packet(ppp_data->chap.c_packet);
603 ppp_data->chap.c_packet = packet;
604 /*
605 * set indicators
606 */
607 ppp_data->chap.rc = TRUE;
608 ppp_data->chap.sr = FALSE;
609 ppp_data->chap.rs = FALSE;
610 /*
611 * create Response packet and
612 * set return values
613 */
614 chap_get_sr(ptr_packet);
615 *forward=FORWARD_RC;
616
617 } /* chap_rc() */
618
619
620
621 /*
622 +------------------------------------------------------------------------------
623 | Function : chap_rr
624 +------------------------------------------------------------------------------
625 | Description : The function chap_rr() checks whether the given Response
626 | packet is valid and if so it returns FORWARD_RRP and a
627 | Success packet.
628 |
629 | Parameters : ptr_packet - Response packet
630 | forward - returns result of analysis
631 |
632 +------------------------------------------------------------------------------
633 */
634 GLOBAL void chap_rr (T_desc2** ptr_packet, UBYTE* forward)
635 {
636 T_desc2* packet;
637 USHORT packet_len;
638 USHORT pos;
639
640 TRACE_FUNCTION( "chap_rr" );
641 /*
642 * this packet can only reveiced in server mode
643 */
644 if(ppp_data->mode NEQ PPP_SERVER)
645 {
646 TRACE_EVENT("PPP CHAP: unexpected CHAP Response Packet in client mode");
647 *forward=FORWARD_DISCARD;
648 return;
649 }
650 /*
651 * check correct length
652 */
653 packet = *ptr_packet;
654 packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
655 packet_len = packet_len << 8;
656 packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
657 if((packet_len < 5) || (packet_len > packet->len))
658 {
659 *forward=FORWARD_DISCARD;
660 TRACE_EVENT_P1("PPP CHAP: invalid Response Packet length %d",packet_len);
661 return;
662 }
663
664 /*
665 * check consistence of length of packet and length of log on information,
666 * check for identifier field and whether a Challenge packet was sent
667 *
668 */
669 pos=4;
670 pos+= packet->buffer[pos];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
671 pos++;
672 #ifdef TRACE_USER_NAME
673 {
674 UBYTE *user_name;
675 USHORT i;
676 USHORT name_len = packet_len - 5 - packet->buffer[4];
677 MALLOC(user_name, name_len);
678 memcpy(user_name, &packet->buffer[packet_len - name_len - 1], name_len);
679 TRACE_EVENT("PPP CHAP: user name:");
680 for(i = 0; i < name_len; i++)
681 {
682 TRACE_EVENT_P1(" *%c* ", user_name[i]);
683 }
684 }
685 #endif /*TRACE_USER_NAME */
686 if((pos > packet_len) ||
687 (packet->buffer[1] NEQ ppp_data->chap.nci) ||
688 (ppp_data->chap.sc EQ FALSE))/*lint !e415 (Warning -- creation of out-of-bounds pointer) */
689 {
690 TRACE_EVENT("PPP CHAP: invalid value size or unexpected Response Packet");
691 *forward=FORWARD_DISCARD;
692 return;
693 }
694
695 #ifdef TEST_MD5
696 {
697 /*
698 * For testing set dual-up connection password to "test password"
699 */
700 UBYTE test_pwd[14] = "test password";
701 T_desc2 *md5_pack, *c_pack;
702 USHORT md5_len;
703 UBYTE digest[16];
704 /*
705 * Values
706 * Message digest
707 */
708 c_pack = ppp_data->chap.c_packet;
709 md5_len = 1 + 13 + c_pack->buffer[4];
710 MALLOC(md5_pack, (USHORT)(sizeof(T_desc2) - 1 + md5_len));
711 /*
712 * Build string to pass to MD5 routine:
713 * identifier + user password + challenge message
714 */
715 md5_pack->buffer[0] = ppp_data->chap.nci;
716 memcpy(&md5_pack->buffer[1], test_pwd, 14);
717 memcpy(&md5_pack->buffer[14+1], &c_pack->buffer[5], c_pack->buffer[4]);
718 /*
719 * Call MD5 routine
720 */
721 cl_md5(md5_pack->buffer, md5_len, &digest[0]);
722 if(memcmp(&packet->buffer[5], digest, 16))
723 {
724 TRACE_EVENT("CHAP ERROR: invalid msg digest in received response");
725 } else {
726 TRACE_EVENT("CHAP INFO: MD5 test OK");
727 }
728 MFREE(md5_pack);
729 }
730 #endif /* TEST_MD5 */
731
732
733 /*
734 * store authentication packet
735 */
736 if(packet_len > CHAP_RESPONSE_LEN_MAX_SERVER_MODE)
737 {
738 TRACE_EVENT_P1("PPP CHAP: invalid Response Packet length %d, send failure",
739 packet_len);
740 /*
741 * create Failure packet
742 */
743 /*
744 * change code field
745 */
746 packet->buffer[0] = CODE_FAILURE;
747 /*
748 * change length field
749 */
750 packet->buffer[2] = 0;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
751 packet->buffer[3] = CHAP_FAILURE_LENGTH;/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
752 packet->len = CHAP_FAILURE_LENGTH;
753 /*
754 * fill out Message
755 */
756 /*lint -e419 (Warning -- data overrun) */
757 memcpy(&packet->buffer[4], CHAP_FAILURE_TEXT, CHAP_FAILURE_TEXT_LENGTH);/*lint !e416 (Warning -- creation of out-of-bounds pointer) */
758 /*lint +e419 (Warning -- data overrun) */
759 /*
760 * set return values
761 */
762 *forward=FORWARD_RRN;
763 *ptr_packet = packet;
764 return;
765 }
766 arb_discard_packet(ppp_data->chap.r_packet);
767 ppp_data->chap.r_packet = packet;
768 /*
769 * create Success packet and
770 * set return values
771 */
772 chap_get_ss(ptr_packet);
773 *forward=FORWARD_RRP;
774 } /* chap_rr() */
775
776
777
778 /*
779 +------------------------------------------------------------------------------
780 | Function : chap_rs
781 +------------------------------------------------------------------------------
782 | Description : The function chap_rs() checks whether the given Success
783 | packet is valid and if so it returns FORWARD_RS.
784 |
785 | Parameters : packet - Success packet
786 | forward - returns result of analysis
787 |
788 +------------------------------------------------------------------------------
789 */
790 GLOBAL void chap_rs (T_desc2* packet, UBYTE* forward)
791 {
792 USHORT packet_len;
793
794 TRACE_FUNCTION( "chap_rs" );
795
796 /*
797 * this packet can only reveiced in client mode
798 */
799 if(ppp_data->mode NEQ PPP_CLIENT)
800 {
801 *forward=FORWARD_DISCARD;
802 return;
803 }
804
805 /*
806 * check correct length and identifier
807 */
808 packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
809 packet_len = packet_len << 8;
810 packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
811 if(packet_len > packet->len ||
812 ppp_data->chap.nci != packet->buffer[1])/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
813 {
814 TRACE_EVENT("PPP CHAP: invalid CHAP Success");
815 *forward=FORWARD_DISCARD;
816 return;
817 }
818 /*
819 * check if Response was sent.
820 */
821 if(!ppp_data->chap.sr)
822 {
823 TRACE_EVENT("PPP CHAP: unexpected CHAP Success");
824 *forward=FORWARD_DISCARD;
825 return;
826 }
827
828 /*
829 * free authentication packet
830 */
831 arb_discard_packet(packet);
832 /*
833 * set return value
834 */
835 ppp_data->chap.rs = TRUE;
836 *forward=FORWARD_RS;
837 /*
838 * Announce successful CHAP authentification
839 */
840 TRACE_EVENT("PPP CHAP: authentification successful");
841
842 } /* chap_rs() */
843
844
845
846 /*
847 +------------------------------------------------------------------------------
848 | Function : chap_rf
849 +------------------------------------------------------------------------------
850 | Description : The function chap_rf() checks whether the given Failure
851 | packet is valid and if so it returns FORWARD_RF.
852 |
853 | Parameters : packet - Failure packet
854 | forward - returns result of analysis
855 |
856 +------------------------------------------------------------------------------
857 */
858 GLOBAL void chap_rf (T_desc2* packet, UBYTE* forward)
859 {
860 USHORT packet_len;
861
862 TRACE_FUNCTION( "chap_rf" );
863
864 /*
865 * this packet can only reveiced in client mode
866 */
867 if(ppp_data->mode NEQ PPP_CLIENT)
868 {
869 TRACE_EVENT("PPP CHAP: unexpected Failure packet in server mode");
870 *forward=FORWARD_DISCARD;
871 return;
872 }
873 /*
874 * check correct length
875 */
876 packet_len = packet->buffer[2];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
877 packet_len = packet_len << 8;
878 packet_len+= packet->buffer[3];/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
879 if(packet_len > packet->len)
880 {
881 TRACE_EVENT("PPP CHAP: invalid Failure packet length");
882 *forward=FORWARD_DISCARD;
883 return;
884 }
885 /*
886 * Check identifier
887 */
888 if(ppp_data->chap.nci != packet->buffer[1])/*lint !e415 !e416 (Warning -- access/creation of out-of-bounds pointer) */
889 {
890 TRACE_EVENT("PPP CHAP: invalid identifier in Failure packet");
891 *forward=FORWARD_DISCARD;
892 return;
893 }
894 /*
895 * Check if Success was already received
896 * or if Response was not sent yet
897 */
898 if(ppp_data->chap.rs || !ppp_data->chap.sr)
899 {
900 TRACE_EVENT("PPP CHAP: unexpected Failure");
901 *forward=FORWARD_DISCARD;
902 return;
903 }
904 /*
905 * free Failure packet and reset Response receiving flag
906 */
907 arb_discard_packet(packet);
908 ppp_data->chap.sr = FALSE;
909 /*
910 * set return value
911 */
912 *forward=FORWARD_RF;
913 /*
914 * Announce failed CHAP authentification
915 */
916 TRACE_EVENT("PPP CHAP: authentification failed");
917
918 } /* chap_rf() */
919
920 #ifdef _SIMULATION_
921 /*
922 +------------------------------------------------------------------------------
923 | Function : ppp_trace_desc
924 +------------------------------------------------------------------------------
925 | Description : The function traces desc
926 |
927 | Parameters : packet - tracing packet
928 |
929 +------------------------------------------------------------------------------
930 */
931 GLOBAL void ppp_trace_desc (T_desc2* packet)
932 {
933 UINT i=0;
934 UBYTE *buf=&packet->buffer[0];
935
936
937 while(i < packet->len)
938 {
939 if((i+4) < packet->len){
940 TRACE_EVENT_P4("0x%02x, 0x%02x, 0x%02x, 0x%02x,",
941 buf[i], buf[i+1],buf[i+2],buf[i+3]);
942 i+=4;
943 }
944 else if((i+3) < packet->len){
945 TRACE_EVENT_P3("0x%02x, 0x%02x, 0x%02x,",
946 buf[i], buf[i+1],buf[i+2]);
947 i+=3;
948 }
949 else if((i+2) < packet->len){
950 TRACE_EVENT_P2("0x%02x, 0x%02x,",buf[i],buf[i+1]);
951 i+=2;
952 }
953 else if((i+1) <= packet->len){
954 TRACE_EVENT_P1("0x%02x, ",buf[i]);
955 i+=1;
956 }
957 }
958 }
959 #endif /* _SIMULATION_ */
960
961
962
963
964