radlib.c (c5384974d99d960de4e92f8a2cc1e3ad10aa6248) | radlib.c (3fc0b61c51969c20551372e9c4adb4943e96dbd3) |
---|---|
1/*- 2 * Copyright 1998 Juniper Networks, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 89 unchanged lines hidden (view full) --- 98 unsigned char md5[MD5_DIGEST_LENGTH]; 99 const struct rad_server *srvp; 100 int padded_len; 101 int pos; 102 103 srvp = &h->servers[srv]; 104 padded_len = h->pass_len == 0 ? 16 : (h->pass_len+15) & ~0xf; 105 | 1/*- 2 * Copyright 1998 Juniper Networks, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 89 unchanged lines hidden (view full) --- 98 unsigned char md5[MD5_DIGEST_LENGTH]; 99 const struct rad_server *srvp; 100 int padded_len; 101 int pos; 102 103 srvp = &h->servers[srv]; 104 padded_len = h->pass_len == 0 ? 16 : (h->pass_len+15) & ~0xf; 105 |
106 memcpy(md5, &h->request[POS_AUTH], LEN_AUTH); | 106 memcpy(md5, &h->out[POS_AUTH], LEN_AUTH); |
107 for (pos = 0; pos < padded_len; pos += 16) { 108 int i; 109 110 /* Calculate the new scrambler */ 111 MD5Init(&ctx); 112 MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); 113 MD5Update(&ctx, md5, 16); 114 MD5Final(md5, &ctx); 115 116 /* 117 * Mix in the current chunk of the password, and copy 118 * the result into the right place in the request. Also 119 * modify the scrambler in place, since we will use this 120 * in calculating the scrambler for next time. 121 */ 122 for (i = 0; i < 16; i++) | 107 for (pos = 0; pos < padded_len; pos += 16) { 108 int i; 109 110 /* Calculate the new scrambler */ 111 MD5Init(&ctx); 112 MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); 113 MD5Update(&ctx, md5, 16); 114 MD5Final(md5, &ctx); 115 116 /* 117 * Mix in the current chunk of the password, and copy 118 * the result into the right place in the request. Also 119 * modify the scrambler in place, since we will use this 120 * in calculating the scrambler for next time. 121 */ 122 for (i = 0; i < 16; i++) |
123 h->request[h->pass_pos + pos + i] = | 123 h->out[h->pass_pos + pos + i] = |
124 md5[i] ^= h->pass[pos + i]; 125 } 126} 127 128static void | 124 md5[i] ^= h->pass[pos + i]; 125 } 126} 127 128static void |
129insert_request_authenticator(struct rad_handle *h, int srv) | 129insert_request_authenticator(struct rad_handle *h, int resp) |
130{ 131 MD5_CTX ctx; 132 const struct rad_server *srvp; 133 | 130{ 131 MD5_CTX ctx; 132 const struct rad_server *srvp; 133 |
134 srvp = &h->servers[srv]; | 134 srvp = &h->servers[h->srv]; |
135 136 /* Create the request authenticator */ 137 MD5Init(&ctx); | 135 136 /* Create the request authenticator */ 137 MD5Init(&ctx); |
138 MD5Update(&ctx, &h->request[POS_CODE], POS_AUTH - POS_CODE); 139 MD5Update(&ctx, memset(&h->request[POS_AUTH], 0, LEN_AUTH), LEN_AUTH); 140 MD5Update(&ctx, &h->request[POS_ATTRS], h->req_len - POS_ATTRS); | 138 MD5Update(&ctx, &h->out[POS_CODE], POS_AUTH - POS_CODE); 139 if (resp) 140 MD5Update(&ctx, &h->in[POS_AUTH], LEN_AUTH); 141 else 142 MD5Update(&ctx, &h->out[POS_AUTH], LEN_AUTH); 143 MD5Update(&ctx, &h->out[POS_ATTRS], h->out_len - POS_ATTRS); |
141 MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); | 144 MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); |
142 MD5Final(&h->request[POS_AUTH], &ctx); | 145 MD5Final(&h->out[POS_AUTH], &ctx); |
143} 144 145static void | 146} 147 148static void |
146insert_message_authenticator(struct rad_handle *h, int srv) | 149insert_message_authenticator(struct rad_handle *h, int resp) |
147{ 148#ifdef WITH_SSL 149 u_char md[EVP_MAX_MD_SIZE]; 150 u_int md_len; 151 const struct rad_server *srvp; 152 HMAC_CTX ctx; | 150{ 151#ifdef WITH_SSL 152 u_char md[EVP_MAX_MD_SIZE]; 153 u_int md_len; 154 const struct rad_server *srvp; 155 HMAC_CTX ctx; |
153 srvp = &h->servers[srv]; | 156 srvp = &h->servers[h->srv]; |
154 155 if (h->authentic_pos != 0) { 156 HMAC_CTX_init(&ctx); 157 HMAC_Init(&ctx, srvp->secret, strlen(srvp->secret), EVP_md5()); | 157 158 if (h->authentic_pos != 0) { 159 HMAC_CTX_init(&ctx); 160 HMAC_Init(&ctx, srvp->secret, strlen(srvp->secret), EVP_md5()); |
158 HMAC_Update(&ctx, &h->request[POS_CODE], POS_AUTH - POS_CODE); 159 HMAC_Update(&ctx, &h->request[POS_AUTH], LEN_AUTH); 160 HMAC_Update(&ctx, &h->request[POS_ATTRS], 161 h->req_len - POS_ATTRS); | 161 HMAC_Update(&ctx, &h->out[POS_CODE], POS_AUTH - POS_CODE); 162 if (resp) 163 HMAC_Update(&ctx, &h->in[POS_AUTH], LEN_AUTH); 164 else 165 HMAC_Update(&ctx, &h->out[POS_AUTH], LEN_AUTH); 166 HMAC_Update(&ctx, &h->out[POS_ATTRS], 167 h->out_len - POS_ATTRS); |
162 HMAC_Final(&ctx, md, &md_len); 163 HMAC_CTX_cleanup(&ctx); 164 HMAC_cleanup(&ctx); | 168 HMAC_Final(&ctx, md, &md_len); 169 HMAC_CTX_cleanup(&ctx); 170 HMAC_cleanup(&ctx); |
165 memcpy(&h->request[h->authentic_pos + 2], md, md_len); | 171 memcpy(&h->out[h->authentic_pos + 2], md, md_len); |
166 } 167#endif 168} 169 170/* 171 * Return true if the current response is valid for a request to the 172 * specified server. 173 */ --- 16 unchanged lines hidden (view full) --- 190 191 /* Check the source address */ 192 if (from->sin_family != srvp->addr.sin_family || 193 from->sin_addr.s_addr != srvp->addr.sin_addr.s_addr || 194 from->sin_port != srvp->addr.sin_port) 195 return 0; 196 197 /* Check the message length */ | 172 } 173#endif 174} 175 176/* 177 * Return true if the current response is valid for a request to the 178 * specified server. 179 */ --- 16 unchanged lines hidden (view full) --- 196 197 /* Check the source address */ 198 if (from->sin_family != srvp->addr.sin_family || 199 from->sin_addr.s_addr != srvp->addr.sin_addr.s_addr || 200 from->sin_port != srvp->addr.sin_port) 201 return 0; 202 203 /* Check the message length */ |
198 if (h->resp_len < POS_ATTRS) | 204 if (h->in_len < POS_ATTRS) |
199 return 0; | 205 return 0; |
200 len = h->response[POS_LENGTH] << 8 | h->response[POS_LENGTH+1]; 201 if (len > h->resp_len) | 206 len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1]; 207 if (len > h->in_len) |
202 return 0; 203 204 /* Check the response authenticator */ 205 MD5Init(&ctx); | 208 return 0; 209 210 /* Check the response authenticator */ 211 MD5Init(&ctx); |
206 MD5Update(&ctx, &h->response[POS_CODE], POS_AUTH - POS_CODE); 207 MD5Update(&ctx, &h->request[POS_AUTH], LEN_AUTH); 208 MD5Update(&ctx, &h->response[POS_ATTRS], len - POS_ATTRS); | 212 MD5Update(&ctx, &h->in[POS_CODE], POS_AUTH - POS_CODE); 213 MD5Update(&ctx, &h->out[POS_AUTH], LEN_AUTH); 214 MD5Update(&ctx, &h->in[POS_ATTRS], len - POS_ATTRS); |
209 MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); 210 MD5Final(md5, &ctx); | 215 MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); 216 MD5Final(md5, &ctx); |
211 if (memcmp(&h->response[POS_AUTH], md5, sizeof md5) != 0) | 217 if (memcmp(&h->in[POS_AUTH], md5, sizeof md5) != 0) |
212 return 0; 213 214#ifdef WITH_SSL 215 /* 216 * For non accounting responses check the message authenticator, 217 * if any. 218 */ | 218 return 0; 219 220#ifdef WITH_SSL 221 /* 222 * For non accounting responses check the message authenticator, 223 * if any. 224 */ |
219 if (h->response[POS_CODE] != RAD_ACCOUNTING_RESPONSE) { | 225 if (h->in[POS_CODE] != RAD_ACCOUNTING_RESPONSE) { |
220 | 226 |
221 memcpy(resp, h->response, MSGSIZE); | 227 memcpy(resp, h->in, MSGSIZE); |
222 pos = POS_ATTRS; 223 224 /* Search and verify the Message-Authenticator */ 225 while (pos < len - 2) { 226 | 228 pos = POS_ATTRS; 229 230 /* Search and verify the Message-Authenticator */ 231 while (pos < len - 2) { 232 |
227 if (h->response[pos] == RAD_MESSAGE_AUTHENTIC) { | 233 if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) { |
228 /* zero fill the Message-Authenticator */ 229 memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH); 230 231 HMAC_CTX_init(&hctx); 232 HMAC_Init(&hctx, srvp->secret, 233 strlen(srvp->secret), EVP_md5()); | 234 /* zero fill the Message-Authenticator */ 235 memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH); 236 237 HMAC_CTX_init(&hctx); 238 HMAC_Init(&hctx, srvp->secret, 239 strlen(srvp->secret), EVP_md5()); |
234 HMAC_Update(&hctx, &h->response[POS_CODE], | 240 HMAC_Update(&hctx, &h->in[POS_CODE], |
235 POS_AUTH - POS_CODE); | 241 POS_AUTH - POS_CODE); |
236 HMAC_Update(&hctx, &h->request[POS_AUTH], | 242 HMAC_Update(&hctx, &h->out[POS_AUTH], |
237 LEN_AUTH); 238 HMAC_Update(&hctx, &resp[POS_ATTRS], | 243 LEN_AUTH); 244 HMAC_Update(&hctx, &resp[POS_ATTRS], |
239 h->resp_len - POS_ATTRS); | 245 h->in_len - POS_ATTRS); |
240 HMAC_Final(&hctx, md, &md_len); 241 HMAC_CTX_cleanup(&hctx); 242 HMAC_cleanup(&hctx); | 246 HMAC_Final(&hctx, md, &md_len); 247 HMAC_CTX_cleanup(&hctx); 248 HMAC_cleanup(&hctx); |
243 if (memcmp(md, &h->response[pos + 2], | 249 if (memcmp(md, &h->in[pos + 2], |
244 MD5_DIGEST_LENGTH) != 0) 245 return 0; 246 break; 247 } | 250 MD5_DIGEST_LENGTH) != 0) 251 return 0; 252 break; 253 } |
248 pos += h->response[pos + 1]; | 254 pos += h->in[pos + 1]; |
249 } 250 } 251#endif 252 return 1; 253} 254 | 255 } 256 } 257#endif 258 return 1; 259} 260 |
261/* 262 * Return true if the current request is valid for the specified server. 263 */ |
|
255static int | 264static int |
265is_valid_request(struct rad_handle *h) 266{ 267 MD5_CTX ctx; 268 unsigned char md5[MD5_DIGEST_LENGTH]; 269 const struct rad_server *srvp; 270 int len; 271#ifdef WITH_SSL 272 HMAC_CTX hctx; 273 u_char resp[MSGSIZE], md[EVP_MAX_MD_SIZE]; 274 u_int md_len; 275 int pos; 276#endif 277 278 srvp = &h->servers[h->srv]; 279 280 /* Check the message length */ 281 if (h->in_len < POS_ATTRS) 282 return (0); 283 len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1]; 284 if (len > h->in_len) 285 return (0); 286 287 if (h->in[POS_CODE] != RAD_ACCESS_REQUEST) { 288 uint32_t zeroes[4] = { 0, 0, 0, 0 }; 289 /* Check the request authenticator */ 290 MD5Init(&ctx); 291 MD5Update(&ctx, &h->in[POS_CODE], POS_AUTH - POS_CODE); 292 MD5Update(&ctx, zeroes, LEN_AUTH); 293 MD5Update(&ctx, &h->in[POS_ATTRS], len - POS_ATTRS); 294 MD5Update(&ctx, srvp->secret, strlen(srvp->secret)); 295 MD5Final(md5, &ctx); 296 if (memcmp(&h->in[POS_AUTH], md5, sizeof md5) != 0) 297 return (0); 298 } 299 300#ifdef WITH_SSL 301 /* Search and verify the Message-Authenticator */ 302 pos = POS_ATTRS; 303 while (pos < len - 2) { 304 if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) { 305 memcpy(resp, h->in, MSGSIZE); 306 /* zero fill the Request-Authenticator */ 307 if (h->in[POS_CODE] != RAD_ACCESS_REQUEST) 308 memset(&resp[POS_AUTH], 0, LEN_AUTH); 309 /* zero fill the Message-Authenticator */ 310 memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH); 311 312 HMAC_CTX_init(&hctx); 313 HMAC_Init(&hctx, srvp->secret, 314 strlen(srvp->secret), EVP_md5()); 315 HMAC_Update(&hctx, resp, h->in_len); 316 HMAC_Final(&hctx, md, &md_len); 317 HMAC_CTX_cleanup(&hctx); 318 HMAC_cleanup(&hctx); 319 if (memcmp(md, &h->in[pos + 2], 320 MD5_DIGEST_LENGTH) != 0) 321 return (0); 322 break; 323 } 324 pos += h->in[pos + 1]; 325 } 326#endif 327 return (1); 328} 329 330static int |
|
256put_password_attr(struct rad_handle *h, int type, const void *value, size_t len) 257{ 258 int padded_len; 259 int pad_len; 260 261 if (h->pass_pos != 0) { 262 generr(h, "Multiple User-Password attributes specified"); 263 return -1; --- 4 unchanged lines hidden (view full) --- 268 pad_len = padded_len - len; 269 270 /* 271 * Put in a place-holder attribute containing all zeros, and 272 * remember where it is so we can fill it in later. 273 */ 274 clear_password(h); 275 put_raw_attr(h, type, h->pass, padded_len); | 331put_password_attr(struct rad_handle *h, int type, const void *value, size_t len) 332{ 333 int padded_len; 334 int pad_len; 335 336 if (h->pass_pos != 0) { 337 generr(h, "Multiple User-Password attributes specified"); 338 return -1; --- 4 unchanged lines hidden (view full) --- 343 pad_len = padded_len - len; 344 345 /* 346 * Put in a place-holder attribute containing all zeros, and 347 * remember where it is so we can fill it in later. 348 */ 349 clear_password(h); 350 put_raw_attr(h, type, h->pass, padded_len); |
276 h->pass_pos = h->req_len - padded_len; | 351 h->pass_pos = h->out_len - padded_len; |
277 278 /* Save the cleartext password, padded as necessary */ 279 memcpy(h->pass, value, len); 280 h->pass_len = len; 281 memset(h->pass + len, 0, pad_len); 282 return 0; 283} 284 285static int 286put_raw_attr(struct rad_handle *h, int type, const void *value, size_t len) 287{ 288 if (len > 253) { 289 generr(h, "Attribute too long"); 290 return -1; 291 } | 352 353 /* Save the cleartext password, padded as necessary */ 354 memcpy(h->pass, value, len); 355 h->pass_len = len; 356 memset(h->pass + len, 0, pad_len); 357 return 0; 358} 359 360static int 361put_raw_attr(struct rad_handle *h, int type, const void *value, size_t len) 362{ 363 if (len > 253) { 364 generr(h, "Attribute too long"); 365 return -1; 366 } |
292 if (h->req_len + 2 + len > MSGSIZE) { | 367 if (h->out_len + 2 + len > MSGSIZE) { |
293 generr(h, "Maximum message length exceeded"); 294 return -1; 295 } | 368 generr(h, "Maximum message length exceeded"); 369 return -1; 370 } |
296 h->request[h->req_len++] = type; 297 h->request[h->req_len++] = len + 2; 298 memcpy(&h->request[h->req_len], value, len); 299 h->req_len += len; | 371 h->out[h->out_len++] = type; 372 h->out[h->out_len++] = len + 2; 373 memcpy(&h->out[h->out_len], value, len); 374 h->out_len += len; |
300 return 0; 301} 302 303int 304rad_add_server(struct rad_handle *h, const char *host, int port, 305 const char *secret, int timeout, int tries) 306{ 307 struct rad_server *srvp; --- 210 unchanged lines hidden (view full) --- 518 * > 0 Success 519 */ 520int 521rad_continue_send_request(struct rad_handle *h, int selected, int *fd, 522 struct timeval *tv) 523{ 524 int n; 525 | 375 return 0; 376} 377 378int 379rad_add_server(struct rad_handle *h, const char *host, int port, 380 const char *secret, int timeout, int tries) 381{ 382 struct rad_server *srvp; --- 210 unchanged lines hidden (view full) --- 593 * > 0 Success 594 */ 595int 596rad_continue_send_request(struct rad_handle *h, int selected, int *fd, 597 struct timeval *tv) 598{ 599 int n; 600 |
601 if (h->type == RADIUS_SERVER) { 602 generr(h, "denied function call"); 603 return (-1); 604 } |
|
526 if (selected) { 527 struct sockaddr_in from; 528 socklen_t fromlen; 529 530 fromlen = sizeof from; | 605 if (selected) { 606 struct sockaddr_in from; 607 socklen_t fromlen; 608 609 fromlen = sizeof from; |
531 h->resp_len = recvfrom(h->fd, h->response, | 610 h->in_len = recvfrom(h->fd, h->in, |
532 MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen); | 611 MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen); |
533 if (h->resp_len == -1) { | 612 if (h->in_len == -1) { |
534 generr(h, "recvfrom: %s", strerror(errno)); 535 return -1; 536 } 537 if (is_valid_response(h, h->srv, &from)) { | 613 generr(h, "recvfrom: %s", strerror(errno)); 614 return -1; 615 } 616 if (is_valid_response(h, h->srv, &from)) { |
538 h->resp_len = h->response[POS_LENGTH] << 8 | 539 h->response[POS_LENGTH+1]; 540 h->resp_pos = POS_ATTRS; 541 return h->response[POS_CODE]; | 617 h->in_len = h->in[POS_LENGTH] << 8 | 618 h->in[POS_LENGTH+1]; 619 h->in_pos = POS_ATTRS; 620 return h->in[POS_CODE]; |
542 } 543 } 544 545 if (h->try == h->total_tries) { 546 generr(h, "No valid RADIUS responses received"); 547 return -1; 548 } 549 550 /* 551 * Scan round-robin to the next server that has some 552 * tries left. There is guaranteed to be one, or we 553 * would have exited this loop by now. 554 */ 555 while (h->servers[h->srv].num_tries >= h->servers[h->srv].max_tries) 556 if (++h->srv >= h->num_servers) 557 h->srv = 0; 558 | 621 } 622 } 623 624 if (h->try == h->total_tries) { 625 generr(h, "No valid RADIUS responses received"); 626 return -1; 627 } 628 629 /* 630 * Scan round-robin to the next server that has some 631 * tries left. There is guaranteed to be one, or we 632 * would have exited this loop by now. 633 */ 634 while (h->servers[h->srv].num_tries >= h->servers[h->srv].max_tries) 635 if (++h->srv >= h->num_servers) 636 h->srv = 0; 637 |
559 if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) 560 /* Insert the request authenticator into the request */ 561 insert_request_authenticator(h, h->srv); 562 else | 638 if (h->out[POS_CODE] == RAD_ACCESS_REQUEST) { |
563 /* Insert the scrambled password into the request */ 564 if (h->pass_pos != 0) 565 insert_scrambled_password(h, h->srv); | 639 /* Insert the scrambled password into the request */ 640 if (h->pass_pos != 0) 641 insert_scrambled_password(h, h->srv); |
642 } 643 insert_message_authenticator(h, 0); 644 if (h->out[POS_CODE] != RAD_ACCESS_REQUEST) { 645 /* Insert the request authenticator into the request */ 646 insert_request_authenticator(h, h->srv); 647 } |
|
566 | 648 |
567 insert_message_authenticator(h, h->srv); 568 | |
569 /* Send the request */ | 649 /* Send the request */ |
570 n = sendto(h->fd, h->request, h->req_len, 0, | 650 n = sendto(h->fd, h->out, h->out_len, 0, |
571 (const struct sockaddr *)&h->servers[h->srv].addr, 572 sizeof h->servers[h->srv].addr); | 651 (const struct sockaddr *)&h->servers[h->srv].addr, 652 sizeof h->servers[h->srv].addr); |
573 if (n != h->req_len) { | 653 if (n != h->out_len) { |
574 if (n == -1) 575 generr(h, "sendto: %s", strerror(errno)); 576 else 577 generr(h, "sendto: short write"); 578 return -1; 579 } 580 581 h->try++; 582 h->servers[h->srv].num_tries++; 583 tv->tv_sec = h->servers[h->srv].timeout; 584 tv->tv_usec = 0; 585 *fd = h->fd; 586 587 return 0; 588} 589 590int | 654 if (n == -1) 655 generr(h, "sendto: %s", strerror(errno)); 656 else 657 generr(h, "sendto: short write"); 658 return -1; 659 } 660 661 h->try++; 662 h->servers[h->srv].num_tries++; 663 tv->tv_sec = h->servers[h->srv].timeout; 664 tv->tv_usec = 0; 665 *fd = h->fd; 666 667 return 0; 668} 669 670int |
671rad_receive_request(struct rad_handle *h) 672{ 673 struct sockaddr_in from; 674 socklen_t fromlen; 675 int n; 676 677 if (h->type != RADIUS_SERVER) { 678 generr(h, "denied function call"); 679 return (-1); 680 } 681 h->srv = -1; 682 fromlen = sizeof(from); 683 h->in_len = recvfrom(h->fd, h->in, 684 MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen); 685 if (h->in_len == -1) { 686 generr(h, "recvfrom: %s", strerror(errno)); 687 return (-1); 688 } 689 for (n = 0; n < h->num_servers; n++) { 690 if (h->servers[n].addr.sin_addr.s_addr == from.sin_addr.s_addr) { 691 h->servers[n].addr.sin_port = from.sin_port; 692 h->srv = n; 693 break; 694 } 695 } 696 if (h->srv == -1) 697 return (-2); 698 if (is_valid_request(h)) { 699 h->in_len = h->in[POS_LENGTH] << 8 | 700 h->in[POS_LENGTH+1]; 701 h->in_pos = POS_ATTRS; 702 return (h->in[POS_CODE]); 703 } 704 return (-3); 705} 706 707int 708rad_send_response(struct rad_handle *h) 709{ 710 int n; 711 712 if (h->type != RADIUS_SERVER) { 713 generr(h, "denied function call"); 714 return (-1); 715 } 716 /* Fill in the length field in the message */ 717 h->out[POS_LENGTH] = h->out_len >> 8; 718 h->out[POS_LENGTH+1] = h->out_len; 719 720 insert_message_authenticator(h, 721 (h->in[POS_CODE] == RAD_ACCESS_REQUEST) ? 1 : 0); 722 insert_request_authenticator(h, 1); 723 724 /* Send the request */ 725 n = sendto(h->fd, h->out, h->out_len, 0, 726 (const struct sockaddr *)&h->servers[h->srv].addr, 727 sizeof h->servers[h->srv].addr); 728 if (n != h->out_len) { 729 if (n == -1) 730 generr(h, "sendto: %s", strerror(errno)); 731 else 732 generr(h, "sendto: short write"); 733 return -1; 734 } 735 736 return 0; 737} 738 739int |
|
591rad_create_request(struct rad_handle *h, int code) 592{ 593 int i; 594 | 740rad_create_request(struct rad_handle *h, int code) 741{ 742 int i; 743 |
595 h->request[POS_CODE] = code; 596 h->request[POS_IDENT] = ++h->ident; 597 /* Create a random authenticator */ 598 for (i = 0; i < LEN_AUTH; i += 2) { 599 long r; 600 r = random(); 601 h->request[POS_AUTH+i] = (u_char)r; 602 h->request[POS_AUTH+i+1] = (u_char)(r >> 8); | 744 if (h->type == RADIUS_SERVER) { 745 generr(h, "denied function call"); 746 return (-1); |
603 } | 747 } |
604 h->req_len = POS_ATTRS; | 748 h->out[POS_CODE] = code; 749 h->out[POS_IDENT] = ++h->ident; 750 if (code == RAD_ACCESS_REQUEST) { 751 /* Create a random authenticator */ 752 for (i = 0; i < LEN_AUTH; i += 2) { 753 long r; 754 r = random(); 755 h->out[POS_AUTH+i] = (u_char)r; 756 h->out[POS_AUTH+i+1] = (u_char)(r >> 8); 757 } 758 } else 759 memset(&h->out[POS_AUTH], 0, LEN_AUTH); 760 h->out_len = POS_ATTRS; |
605 clear_password(h); | 761 clear_password(h); |
606 h->request_created = 1; | 762 h->authentic_pos = 0; 763 h->out_created = 1; |
607 return 0; 608} 609 | 764 return 0; 765} 766 |
767int 768rad_create_response(struct rad_handle *h, int code) 769{ 770 771 if (h->type != RADIUS_SERVER) { 772 generr(h, "denied function call"); 773 return (-1); 774 } 775 h->out[POS_CODE] = code; 776 h->out[POS_IDENT] = h->in[POS_IDENT]; 777 memset(&h->out[POS_AUTH], 0, LEN_AUTH); 778 h->out_len = POS_ATTRS; 779 clear_password(h); 780 h->authentic_pos = 0; 781 h->out_created = 1; 782 return 0; 783} 784 |
|
610struct in_addr 611rad_cvt_addr(const void *data) 612{ 613 struct in_addr value; 614 615 memcpy(&value.s_addr, data, sizeof value.s_addr); 616 return value; 617} --- 24 unchanged lines hidden (view full) --- 642 * Returns the attribute type. If none are left, returns 0. On failure, 643 * returns -1. 644 */ 645int 646rad_get_attr(struct rad_handle *h, const void **value, size_t *len) 647{ 648 int type; 649 | 785struct in_addr 786rad_cvt_addr(const void *data) 787{ 788 struct in_addr value; 789 790 memcpy(&value.s_addr, data, sizeof value.s_addr); 791 return value; 792} --- 24 unchanged lines hidden (view full) --- 817 * Returns the attribute type. If none are left, returns 0. On failure, 818 * returns -1. 819 */ 820int 821rad_get_attr(struct rad_handle *h, const void **value, size_t *len) 822{ 823 int type; 824 |
650 if (h->resp_pos >= h->resp_len) | 825 if (h->in_pos >= h->in_len) |
651 return 0; | 826 return 0; |
652 if (h->resp_pos + 2 > h->resp_len) { | 827 if (h->in_pos + 2 > h->in_len) { |
653 generr(h, "Malformed attribute in response"); 654 return -1; 655 } | 828 generr(h, "Malformed attribute in response"); 829 return -1; 830 } |
656 type = h->response[h->resp_pos++]; 657 *len = h->response[h->resp_pos++] - 2; 658 if (h->resp_pos + (int)*len > h->resp_len) { | 831 type = h->in[h->in_pos++]; 832 *len = h->in[h->in_pos++] - 2; 833 if (h->in_pos + (int)*len > h->in_len) { |
659 generr(h, "Malformed attribute in response"); 660 return -1; 661 } | 834 generr(h, "Malformed attribute in response"); 835 return -1; 836 } |
662 *value = &h->response[h->resp_pos]; 663 h->resp_pos += *len; | 837 *value = &h->in[h->in_pos]; 838 h->in_pos += *len; |
664 return type; 665} 666 667/* 668 * Returns -1 on error, 0 to indicate no event and >0 for success 669 */ 670int 671rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv) 672{ 673 int srv; 674 | 839 return type; 840} 841 842/* 843 * Returns -1 on error, 0 to indicate no event and >0 for success 844 */ 845int 846rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv) 847{ 848 int srv; 849 |
850 if (h->type == RADIUS_SERVER) { 851 generr(h, "denied function call"); 852 return (-1); 853 } |
|
675 /* Make sure we have a socket to use */ 676 if (h->fd == -1) { 677 struct sockaddr_in sin; 678 679 if ((h->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { 680 generr(h, "Cannot create socket: %s", strerror(errno)); 681 return -1; 682 } --- 6 unchanged lines hidden (view full) --- 689 sizeof sin) == -1) { 690 generr(h, "bind: %s", strerror(errno)); 691 close(h->fd); 692 h->fd = -1; 693 return -1; 694 } 695 } 696 | 854 /* Make sure we have a socket to use */ 855 if (h->fd == -1) { 856 struct sockaddr_in sin; 857 858 if ((h->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { 859 generr(h, "Cannot create socket: %s", strerror(errno)); 860 return -1; 861 } --- 6 unchanged lines hidden (view full) --- 868 sizeof sin) == -1) { 869 generr(h, "bind: %s", strerror(errno)); 870 close(h->fd); 871 h->fd = -1; 872 return -1; 873 } 874 } 875 |
697 if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) { | 876 if (h->out[POS_CODE] != RAD_ACCESS_REQUEST) { |
698 /* Make sure no password given */ 699 if (h->pass_pos || h->chap_pass) { 700 generr(h, "User or Chap Password" 701 " in accounting request"); 702 return -1; 703 } 704 } else { 705 if (h->eap_msg == 0) { --- 7 unchanged lines hidden (view full) --- 713 generr(h, "Both User and Chap Password" 714 " attributes given"); 715 return -1; 716 } 717 } 718 } 719 720 /* Fill in the length field in the message */ | 877 /* Make sure no password given */ 878 if (h->pass_pos || h->chap_pass) { 879 generr(h, "User or Chap Password" 880 " in accounting request"); 881 return -1; 882 } 883 } else { 884 if (h->eap_msg == 0) { --- 7 unchanged lines hidden (view full) --- 892 generr(h, "Both User and Chap Password" 893 " attributes given"); 894 return -1; 895 } 896 } 897 } 898 899 /* Fill in the length field in the message */ |
721 h->request[POS_LENGTH] = h->req_len >> 8; 722 h->request[POS_LENGTH+1] = h->req_len; | 900 h->out[POS_LENGTH] = h->out_len >> 8; 901 h->out[POS_LENGTH+1] = h->out_len; |
723 724 /* 725 * Count the total number of tries we will make, and zero the 726 * counter for each server. 727 */ 728 h->total_tries = 0; 729 for (srv = 0; srv < h->num_servers; srv++) { 730 h->total_tries += h->servers[srv].max_tries; --- 27 unchanged lines hidden (view full) --- 758 h->ident = random(); 759 h->errmsg[0] = '\0'; 760 memset(h->pass, 0, sizeof h->pass); 761 h->pass_len = 0; 762 h->pass_pos = 0; 763 h->chap_pass = 0; 764 h->authentic_pos = 0; 765 h->type = RADIUS_AUTH; | 902 903 /* 904 * Count the total number of tries we will make, and zero the 905 * counter for each server. 906 */ 907 h->total_tries = 0; 908 for (srv = 0; srv < h->num_servers; srv++) { 909 h->total_tries += h->servers[srv].max_tries; --- 27 unchanged lines hidden (view full) --- 937 h->ident = random(); 938 h->errmsg[0] = '\0'; 939 memset(h->pass, 0, sizeof h->pass); 940 h->pass_len = 0; 941 h->pass_pos = 0; 942 h->chap_pass = 0; 943 h->authentic_pos = 0; 944 h->type = RADIUS_AUTH; |
766 h->request_created = 0; | 945 h->out_created = 0; |
767 h->eap_msg = 0; 768 } 769 return h; 770} 771 772struct rad_handle * 773rad_acct_open(void) 774{ 775 struct rad_handle *h; 776 777 h = rad_open(); 778 if (h != NULL) 779 h->type = RADIUS_ACCT; 780 return h; 781} 782 783struct rad_handle * | 946 h->eap_msg = 0; 947 } 948 return h; 949} 950 951struct rad_handle * 952rad_acct_open(void) 953{ 954 struct rad_handle *h; 955 956 h = rad_open(); 957 if (h != NULL) 958 h->type = RADIUS_ACCT; 959 return h; 960} 961 962struct rad_handle * |
963rad_server_open(int fd) 964{ 965 struct rad_handle *h; 966 967 h = rad_open(); 968 if (h != NULL) { 969 h->type = RADIUS_SERVER; 970 h->fd = fd; 971 } 972 return h; 973} 974 975struct rad_handle * |
|
784rad_open(void) 785{ 786 return rad_auth_open(); 787} 788 789int 790rad_put_addr(struct rad_handle *h, int type, struct in_addr addr) 791{ 792 return rad_put_attr(h, type, &addr.s_addr, sizeof addr.s_addr); 793} 794 795int 796rad_put_attr(struct rad_handle *h, int type, const void *value, size_t len) 797{ 798 int result; 799 | 976rad_open(void) 977{ 978 return rad_auth_open(); 979} 980 981int 982rad_put_addr(struct rad_handle *h, int type, struct in_addr addr) 983{ 984 return rad_put_attr(h, type, &addr.s_addr, sizeof addr.s_addr); 985} 986 987int 988rad_put_attr(struct rad_handle *h, int type, const void *value, size_t len) 989{ 990 int result; 991 |
800 if (!h->request_created) { | 992 if (!h->out_created) { |
801 generr(h, "Please call rad_create_request()" 802 " before putting attributes"); 803 return -1; 804 } 805 | 993 generr(h, "Please call rad_create_request()" 994 " before putting attributes"); 995 return -1; 996 } 997 |
806 if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) { | 998 if (h->out[POS_CODE] == RAD_ACCOUNTING_REQUEST) { |
807 if (type == RAD_EAP_MESSAGE) { 808 generr(h, "EAP-Message attribute is not valid" 809 " in accounting requests"); 810 return -1; 811 } 812 } 813 814 /* --- 38 unchanged lines hidden (view full) --- 853} 854 855int 856rad_put_message_authentic(struct rad_handle *h) 857{ 858#ifdef WITH_SSL 859 u_char md_zero[MD5_DIGEST_LENGTH]; 860 | 999 if (type == RAD_EAP_MESSAGE) { 1000 generr(h, "EAP-Message attribute is not valid" 1001 " in accounting requests"); 1002 return -1; 1003 } 1004 } 1005 1006 /* --- 38 unchanged lines hidden (view full) --- 1045} 1046 1047int 1048rad_put_message_authentic(struct rad_handle *h) 1049{ 1050#ifdef WITH_SSL 1051 u_char md_zero[MD5_DIGEST_LENGTH]; 1052 |
861 if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) { | 1053 if (h->out[POS_CODE] == RAD_ACCOUNTING_REQUEST) { |
862 generr(h, "Message-Authenticator is not valid" 863 " in accounting requests"); 864 return -1; 865 } 866 867 if (h->authentic_pos == 0) { | 1054 generr(h, "Message-Authenticator is not valid" 1055 " in accounting requests"); 1056 return -1; 1057 } 1058 1059 if (h->authentic_pos == 0) { |
868 h->authentic_pos = h->req_len; | 1060 h->authentic_pos = h->out_len; |
869 memset(md_zero, 0, sizeof(md_zero)); 870 return (put_raw_attr(h, RAD_MESSAGE_AUTHENTIC, md_zero, 871 sizeof(md_zero))); 872 } 873 return 0; 874#else 875 generr(h, "Message Authenticator not supported," 876 " please recompile libradius with SSL support"); --- 159 unchanged lines hidden (view full) --- 1036 1037int 1038rad_put_vendor_attr(struct rad_handle *h, int vendor, int type, 1039 const void *value, size_t len) 1040{ 1041 struct vendor_attribute *attr; 1042 int res; 1043 | 1061 memset(md_zero, 0, sizeof(md_zero)); 1062 return (put_raw_attr(h, RAD_MESSAGE_AUTHENTIC, md_zero, 1063 sizeof(md_zero))); 1064 } 1065 return 0; 1066#else 1067 generr(h, "Message Authenticator not supported," 1068 " please recompile libradius with SSL support"); --- 159 unchanged lines hidden (view full) --- 1228 1229int 1230rad_put_vendor_attr(struct rad_handle *h, int vendor, int type, 1231 const void *value, size_t len) 1232{ 1233 struct vendor_attribute *attr; 1234 int res; 1235 |
1044 if (!h->request_created) { | 1236 if (!h->out_created) { |
1045 generr(h, "Please call rad_create_request()" 1046 " before putting attributes"); 1047 return -1; 1048 } 1049 1050 if ((attr = malloc(len + 6)) == NULL) { 1051 generr(h, "malloc failure (%zu bytes)", len + 6); 1052 return -1; --- 30 unchanged lines hidden (view full) --- 1083 return (rad_put_vendor_attr(h, vendor, type, str, strlen(str))); 1084} 1085 1086ssize_t 1087rad_request_authenticator(struct rad_handle *h, char *buf, size_t len) 1088{ 1089 if (len < LEN_AUTH) 1090 return (-1); | 1237 generr(h, "Please call rad_create_request()" 1238 " before putting attributes"); 1239 return -1; 1240 } 1241 1242 if ((attr = malloc(len + 6)) == NULL) { 1243 generr(h, "malloc failure (%zu bytes)", len + 6); 1244 return -1; --- 30 unchanged lines hidden (view full) --- 1275 return (rad_put_vendor_attr(h, vendor, type, str, strlen(str))); 1276} 1277 1278ssize_t 1279rad_request_authenticator(struct rad_handle *h, char *buf, size_t len) 1280{ 1281 if (len < LEN_AUTH) 1282 return (-1); |
1091 memcpy(buf, h->request + POS_AUTH, LEN_AUTH); | 1283 memcpy(buf, h->out + POS_AUTH, LEN_AUTH); |
1092 if (len > LEN_AUTH) 1093 buf[LEN_AUTH] = '\0'; 1094 return (LEN_AUTH); 1095} 1096 1097u_char * 1098rad_demangle(struct rad_handle *h, const void *mangled, size_t mlen) 1099{ --- 134 unchanged lines hidden --- | 1284 if (len > LEN_AUTH) 1285 buf[LEN_AUTH] = '\0'; 1286 return (LEN_AUTH); 1287} 1288 1289u_char * 1290rad_demangle(struct rad_handle *h, const void *mangled, size_t mlen) 1291{ --- 134 unchanged lines hidden --- |