| File: | src/usr.sbin/npppd/npppd/pap.c |
| Warning: | line 479, column 2 Value stored to 'radctx' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: pap.c,v 1.12 2021/03/29 03:54:39 yasuoka Exp $ */ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 2009 Internet Initiative Japan Inc. |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 | * SUCH DAMAGE. |
| 27 | */ |
| 28 | /* $Id: pap.c,v 1.12 2021/03/29 03:54:39 yasuoka Exp $ */ |
| 29 | /**@file |
| 30 | * This file provides Password Authentication Protocol (PAP) handlers. |
| 31 | * @author Yasuoka Masahiko |
| 32 | */ |
| 33 | #include <sys/types.h> |
| 34 | #include <sys/socket.h> |
| 35 | #include <sys/time.h> |
| 36 | #include <net/if_dl.h> |
| 37 | #include <netinet/in.h> |
| 38 | |
| 39 | #include <event.h> |
| 40 | #include <md5.h> |
| 41 | #include <stdarg.h> |
| 42 | #include <stdio.h> |
| 43 | #include <stdlib.h> |
| 44 | #include <string.h> |
| 45 | #include <syslog.h> |
| 46 | #include <errno(*__errno()).h> |
| 47 | #include <vis.h> |
| 48 | |
| 49 | #include "npppd.h" |
| 50 | #include "ppp.h" |
| 51 | |
| 52 | #ifdef USE_NPPPD_RADIUS1 |
| 53 | #include <radius.h> |
| 54 | #include "radius_chap_const.h" |
| 55 | #include "npppd_radius.h" |
| 56 | #endif |
| 57 | |
| 58 | #include "debugutil.h" |
| 59 | |
| 60 | #define AUTHREQ0x01 0x01 |
| 61 | #define AUTHACK0x02 0x02 |
| 62 | #define AUTHNAK0x03 0x03 |
| 63 | |
| 64 | #define PAP_STATE_INITIAL0 0 |
| 65 | #define PAP_STATE_STARTING1 1 |
| 66 | #define PAP_STATE_AUTHENTICATING2 2 |
| 67 | #define PAP_STATE_SENT_RESPONSE3 3 |
| 68 | #define PAP_STATE_STOPPED4 4 |
| 69 | #define PAP_STATE_PROXY_AUTHENTICATION5 5 |
| 70 | |
| 71 | #define DEFAULT_SUCCESS_MESSAGE"OK" "OK" |
| 72 | #define DEFAULT_FAILURE_MESSAGE"Unknown username or password" "Unknown username or password" |
| 73 | #define DEFAULT_ERROR_MESSAGE"Unknown failure" "Unknown failure" |
| 74 | |
| 75 | #ifdef PAP_DEBUG |
| 76 | #define PAP_DBG(x) pap_log x |
| 77 | #define PAP_ASSERT(cond) \ |
| 78 | if (!(cond)) { \ |
| 79 | fprintf(stderr(&__sF[2]), \ |
| 80 | "\nASSERT(" #cond ") failed on %s() at %s:%d.\n"\ |
| 81 | , __func__, __FILE__"/usr/src/usr.sbin/npppd/npppd/pap.c", __LINE__81); \ |
| 82 | abort(); \ |
| 83 | } |
| 84 | #else |
| 85 | #define PAP_ASSERT(cond) |
| 86 | #define PAP_DBG(x) |
| 87 | #endif |
| 88 | |
| 89 | static void pap_log (pap *, uint32_t, const char *, ...) __printflike(3,4)__attribute__((__format__ (__printf__, 3, 4))); |
| 90 | static void pap_response (pap *, int, const char *); |
| 91 | static void pap_authenticate(pap *, const char *); |
| 92 | static void pap_local_authenticate (pap *, const char *, const char *); |
| 93 | #ifdef USE_NPPPD_RADIUS1 |
| 94 | static void pap_radius_authenticate (pap *, const char *, const char *); |
| 95 | static void pap_radius_response (void *, RADIUS_PACKET *, int, RADIUS_REQUEST_CTX); |
| 96 | #endif |
| 97 | |
| 98 | #ifdef __cplusplus |
| 99 | extern "C" { |
| 100 | #endif |
| 101 | |
| 102 | void pap_init (pap *, npppd_ppp *); |
| 103 | int pap_start (pap *); |
| 104 | int pap_stop (pap *); |
| 105 | int pap_input (pap *, u_char *, int); |
| 106 | |
| 107 | #ifdef __cplusplus |
| 108 | } |
| 109 | #endif |
| 110 | |
| 111 | void |
| 112 | pap_init(pap *_this, npppd_ppp *ppp) |
| 113 | { |
| 114 | _this->ppp = ppp; |
| 115 | _this->state = PAP_STATE_INITIAL0; |
| 116 | _this->auth_id = -1; |
| 117 | } |
| 118 | |
| 119 | int |
| 120 | pap_start(pap *_this) |
| 121 | { |
| 122 | pap_log(_this, LOG_DEBUG7, "%s", __func__); |
| 123 | |
| 124 | if (_this->state == PAP_STATE_PROXY_AUTHENTICATION5) { |
| 125 | _this->state = PAP_STATE_AUTHENTICATING2; |
| 126 | pap_authenticate(_this, _this->ppp->proxy_authen_resp); |
| 127 | return 0; |
| 128 | } |
| 129 | |
| 130 | _this->state = PAP_STATE_STARTING1; |
| 131 | return 0; |
| 132 | } |
| 133 | |
| 134 | int |
| 135 | pap_stop(pap *_this) |
| 136 | { |
| 137 | _this->state = PAP_STATE_STOPPED4; |
| 138 | _this->auth_id = -1; |
| 139 | |
| 140 | #ifdef USE_NPPPD_RADIUS1 |
| 141 | if (_this->radctx != NULL((void *)0)) { |
| 142 | radius_cancel_request(_this->radctx); |
| 143 | _this->radctx = NULL((void *)0); |
| 144 | } |
| 145 | #endif |
| 146 | return 0; |
| 147 | } |
| 148 | |
| 149 | /** Receiving PAP packet */ |
| 150 | int |
| 151 | pap_input(pap *_this, u_char *pktp, int lpktp) |
| 152 | { |
| 153 | int code, id, length, len; |
| 154 | u_char *pktp1; |
| 155 | char name[MAX_USERNAME_LENGTH256], password[MAX_PASSWORD_LENGTH256]; |
| 156 | |
| 157 | if (_this->state == PAP_STATE_STOPPED4 || |
| 158 | _this->state == PAP_STATE_INITIAL0) { |
| 159 | pap_log(_this, LOG_ERR3, "Received pap packet. But pap is " |
| 160 | "not started."); |
| 161 | return -1; |
| 162 | } |
| 163 | pktp1 = pktp; |
| 164 | |
| 165 | GETCHAR(code, pktp1){ (code) = *(pktp1)++; }; |
| 166 | GETCHAR(id, pktp1){ (id) = *(pktp1)++; }; |
| 167 | GETSHORT(length, pktp1){ (length) = *(pktp1)++ << 8; (length) |= *(pktp1)++; }; |
| 168 | |
| 169 | if (code != AUTHREQ0x01) { |
| 170 | pap_log(_this, LOG_ERR3, "%s: Received unknown code=%d", |
| 171 | __func__, code); |
| 172 | return -1; |
| 173 | } |
| 174 | if (lpktp < length) { |
| 175 | pap_log(_this, LOG_ERR3, "%s: Received broken packet.", |
| 176 | __func__); |
| 177 | return -1; |
| 178 | } |
| 179 | |
| 180 | /* retribute the username */ |
| 181 | #define remlen(lpktp - (pktp1 - pktp)) (lpktp - (pktp1 - pktp)) |
| 182 | if (remlen(lpktp - (pktp1 - pktp)) < 1) |
| 183 | goto fail; |
| 184 | GETCHAR(len, pktp1){ (len) = *(pktp1)++; }; |
| 185 | if (len <= 0) |
| 186 | goto fail; |
| 187 | if (remlen(lpktp - (pktp1 - pktp)) < len) |
| 188 | goto fail; |
| 189 | if (len > 0) |
| 190 | memcpy(name, pktp1, len); |
| 191 | name[len] = '\0'; |
| 192 | pktp1 += len; |
| 193 | |
| 194 | if (_this->state != PAP_STATE_STARTING1) { |
| 195 | /* |
| 196 | * Receiving identical message again, it must be the message |
| 197 | * retransmit by the peer. Continue if the username is same. |
| 198 | */ |
| 199 | if ((_this->state == PAP_STATE_AUTHENTICATING2 || |
| 200 | _this->state == PAP_STATE_SENT_RESPONSE3) && |
| 201 | strcmp(_this->name, name) == 0) { |
| 202 | /* continue */ |
| 203 | } else { |
| 204 | pap_log(_this, LOG_ERR3, |
| 205 | "Received AuthReq is not same as before. " |
| 206 | "(%d,%s) != (%d,%s)", id, name, _this->auth_id, |
| 207 | _this->name); |
| 208 | _this->auth_id = id; |
| 209 | goto fail; |
| 210 | } |
| 211 | } |
| 212 | if (_this->state == PAP_STATE_AUTHENTICATING2) |
| 213 | return 0; |
| 214 | _this->auth_id = id; |
| 215 | strlcpy(_this->name, name, sizeof(_this->name)); |
| 216 | |
| 217 | _this->state = PAP_STATE_AUTHENTICATING2; |
| 218 | |
| 219 | /* retribute the password */ |
| 220 | if (remlen(lpktp - (pktp1 - pktp)) < 1) |
| 221 | goto fail; |
| 222 | GETCHAR(len, pktp1){ (len) = *(pktp1)++; }; |
| 223 | if (remlen(lpktp - (pktp1 - pktp)) < len) |
| 224 | goto fail; |
| 225 | if (len > 0) |
| 226 | memcpy(password, pktp1, len); |
| 227 | |
| 228 | password[len] = '\0'; |
| 229 | pap_authenticate(_this, password); |
| 230 | |
| 231 | return 0; |
| 232 | fail: |
| 233 | pap_response(_this, 0, DEFAULT_FAILURE_MESSAGE"Unknown username or password"); |
| 234 | return -1; |
| 235 | } |
| 236 | |
| 237 | static void |
| 238 | pap_authenticate(pap *_this, const char *password) |
| 239 | { |
| 240 | if (npppd_ppp_bind_realm(_this->ppp->pppd, _this->ppp, _this->name, 0) |
| 241 | == 0) { |
| 242 | if (!npppd_ppp_is_realm_ready(_this->ppp->pppd, _this->ppp)) { |
| 243 | pap_log(_this, LOG_INFO6, |
| 244 | "username=\"%s\" realm is not ready.", _this->name); |
| 245 | goto fail; |
| 246 | /* NOTREACHED */ |
| 247 | } |
| 248 | #if USE_NPPPD_RADIUS1 |
| 249 | if (npppd_ppp_is_realm_radius(_this->ppp->pppd, _this->ppp)) { |
| 250 | pap_radius_authenticate(_this, _this->name, password); |
| 251 | return; |
| 252 | /* NOTREACHED */ |
| 253 | } else |
| 254 | #endif |
| 255 | if (npppd_ppp_is_realm_local(_this->ppp->pppd, _this->ppp)) { |
| 256 | pap_local_authenticate(_this, _this->name, password); |
| 257 | return; |
| 258 | /* NOTREACHED */ |
| 259 | } |
| 260 | } |
| 261 | fail: |
| 262 | pap_response(_this, 0, DEFAULT_FAILURE_MESSAGE"Unknown username or password"); |
| 263 | } |
| 264 | |
| 265 | static void |
| 266 | pap_log(pap *_this, uint32_t prio, const char *fmt, ...) |
| 267 | { |
| 268 | char logbuf[BUFSIZ1024]; |
| 269 | va_list ap; |
| 270 | |
| 271 | va_start(ap, fmt)__builtin_va_start(ap, fmt); |
| 272 | snprintf(logbuf, sizeof(logbuf), "ppp id=%u layer=pap %s", |
| 273 | _this->ppp->id, fmt); |
| 274 | vlog_printf(prio, logbuf, ap); |
| 275 | va_end(ap)__builtin_va_end(ap); |
| 276 | } |
| 277 | |
| 278 | static void |
| 279 | pap_response(pap *_this, int authok, const char *mes) |
| 280 | { |
| 281 | int lpktp, lmes; |
| 282 | u_char *pktp, *pktp1; |
| 283 | const char *realm; |
| 284 | |
| 285 | pktp = ppp_packetbuf(_this->ppp, PPP_PROTO_PAP0xC023) + HEADERLEN4; |
| 286 | lpktp = _this->ppp->mru - HEADERLEN4; |
| 287 | realm = npppd_ppp_get_realm_name(_this->ppp->pppd, _this->ppp); |
| 288 | |
| 289 | pktp1 = pktp; |
| 290 | if (mes == NULL((void *)0)) |
| 291 | lmes = 0; |
| 292 | else |
| 293 | lmes = strlen(mes); |
| 294 | lmes = MINIMUM(lmes, lpktp - 1)(((lmes) < (lpktp - 1)) ? (lmes) : (lpktp - 1)); |
| 295 | |
| 296 | PUTCHAR(lmes, pktp1){ *(pktp1)++ = (u_char) (lmes); }; |
| 297 | if (lmes > 0) |
| 298 | memcpy(pktp1, mes, lmes); |
| 299 | lpktp = lmes + 1; |
| 300 | |
| 301 | if (authok) |
| 302 | ppp_output(_this->ppp, PPP_PROTO_PAP0xC023, AUTHACK0x02, _this->auth_id, |
| 303 | pktp, lpktp); |
| 304 | else |
| 305 | ppp_output(_this->ppp, PPP_PROTO_PAP0xC023, AUTHNAK0x03, _this->auth_id, |
| 306 | pktp, lpktp); |
| 307 | |
| 308 | if (!authok) { |
| 309 | pap_log(_this, LOG_ALERT1, |
| 310 | "logtype=Failure username=\"%s\" realm=%s", _this->name, |
| 311 | realm); |
| 312 | pap_stop(_this); |
| 313 | ppp_set_disconnect_cause(_this->ppp, |
| 314 | PPP_DISCON_AUTH_FAILED, PPP_PROTO_PAP0xC023, 1 /* peer */, NULL((void *)0)); |
| 315 | ppp_stop(_this->ppp, "Authentication Required"); |
| 316 | } else { |
| 317 | strlcpy(_this->ppp->username, _this->name, |
| 318 | sizeof(_this->ppp->username)); |
| 319 | pap_log(_this, LOG_INFO6, |
| 320 | "logtype=Success username=\"%s\" realm=%s", _this->name, |
| 321 | realm); |
| 322 | pap_stop(_this); |
| 323 | ppp_auth_ok(_this->ppp); |
| 324 | /* reset the state to response request of retransmision. */ |
| 325 | _this->state = PAP_STATE_SENT_RESPONSE3; |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | static void |
| 330 | pap_local_authenticate(pap *_this, const char *username, const char *password) |
| 331 | { |
| 332 | int lpassword0; |
| 333 | char password0[MAX_PASSWORD_LENGTH256]; |
| 334 | |
| 335 | lpassword0 = sizeof(password0); |
| 336 | |
| 337 | if (npppd_get_user_password(_this->ppp->pppd, _this->ppp, username, |
| 338 | password0, &lpassword0) == 0) { |
| 339 | if (!strcmp(password0, password)) { |
| 340 | pap_response(_this, 1, DEFAULT_SUCCESS_MESSAGE"OK"); |
| 341 | return; |
| 342 | } |
| 343 | } |
| 344 | pap_response(_this, 0, DEFAULT_FAILURE_MESSAGE"Unknown username or password"); |
| 345 | } |
| 346 | |
| 347 | /*********************************************************************** |
| 348 | * Proxy Authentication |
| 349 | ***********************************************************************/ |
| 350 | int |
| 351 | pap_proxy_authen_prepare(pap *_this, dialin_proxy_info *dpi) |
| 352 | { |
| 353 | |
| 354 | PAP_ASSERT(dpi->auth_type == PPP_AUTH_PAP); |
| 355 | PAP_ASSERT(_this->state == PAP_STATE_INITIAL); |
| 356 | |
| 357 | _this->auth_id = dpi->auth_id; |
| 358 | if (strlen(dpi->username) >= sizeof(_this->name)) { |
| 359 | pap_log(_this, LOG_NOTICE5, |
| 360 | "\"Proxy Authen Name\" is too long."); |
| 361 | return -1; |
| 362 | } |
| 363 | |
| 364 | /* copy the authentication properties */ |
| 365 | PAP_ASSERT(_this->ppp->proxy_authen_resp == NULL); |
| 366 | if ((_this->ppp->proxy_authen_resp = malloc(dpi->lauth_resp + 1)) == |
| 367 | NULL((void *)0)) { |
| 368 | pap_log(_this, LOG_ERR3, "malloc() failed in %s(): %m", |
| 369 | __func__); |
| 370 | return -1; |
| 371 | } |
| 372 | memcpy(_this->ppp->proxy_authen_resp, dpi->auth_resp, |
| 373 | dpi->lauth_resp); |
| 374 | _this->ppp->proxy_authen_resp[dpi->lauth_resp] = '\0'; |
| 375 | strlcpy(_this->name, dpi->username, sizeof(_this->name)); |
| 376 | |
| 377 | _this->state = PAP_STATE_PROXY_AUTHENTICATION5; |
| 378 | |
| 379 | return 0; |
| 380 | } |
| 381 | |
| 382 | #ifdef USE_NPPPD_RADIUS1 |
| 383 | static void |
| 384 | pap_radius_authenticate(pap *_this, const char *username, const char *password) |
| 385 | { |
| 386 | void *radctx; |
| 387 | RADIUS_PACKET *radpkt; |
| 388 | MD5_CTX md5ctx; |
| 389 | int i, j, s_len, passlen; |
| 390 | u_char ra[16], digest[16], pass[128]; |
| 391 | const char *s; |
| 392 | radius_req_setting *rad_setting = NULL((void *)0); |
| 393 | char buf0[MAX_USERNAME_LENGTH256]; |
| 394 | |
| 395 | if ((rad_setting = npppd_get_radius_auth_setting(_this->ppp->pppd, |
| 396 | _this->ppp)) == NULL((void *)0)) |
| 397 | goto fail; |
| 398 | |
| 399 | if ((radpkt = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST1)) |
| 400 | == NULL((void *)0)) |
| 401 | goto fail; |
| 402 | |
| 403 | if (radius_prepare(rad_setting, _this, &radctx, pap_radius_response) |
| 404 | != 0) { |
| 405 | radius_delete_packet(radpkt); |
| 406 | goto fail; |
| 407 | } |
| 408 | |
| 409 | if (ppp_set_radius_attrs_for_authreq(_this->ppp, rad_setting, radpkt) |
| 410 | != 0) |
| 411 | goto fail; |
| 412 | |
| 413 | if (radius_put_string_attr(radpkt, RADIUS_TYPE_USER_NAME1, |
| 414 | npppd_ppp_get_username_for_auth(_this->ppp->pppd, _this->ppp, |
| 415 | username, buf0)) != 0) |
| 416 | goto fail; |
| 417 | |
| 418 | if (_this->radctx != NULL((void *)0)) |
| 419 | radius_cancel_request(_this->radctx); |
| 420 | |
| 421 | _this->radctx = radctx; |
| 422 | |
| 423 | /* Create RADIUS User-Password Attribute (RFC 2865, 5.2.) */ |
| 424 | s = radius_get_server_secret(_this->radctx); |
| 425 | s_len = strlen(s); |
| 426 | |
| 427 | memset(pass, 0, sizeof(pass)); /* null padding */ |
| 428 | passlen = MINIMUM(strlen(password), sizeof(pass))(((strlen(password)) < (sizeof(pass))) ? (strlen(password) ) : (sizeof(pass))); |
| 429 | memcpy(pass, password, passlen); |
| 430 | if ((passlen % 16) != 0) |
| 431 | passlen += 16 - (passlen % 16); |
| 432 | |
| 433 | radius_get_authenticator(radpkt, ra); |
| 434 | |
| 435 | MD5Init(&md5ctx); |
| 436 | MD5Update(&md5ctx, s, s_len); |
| 437 | MD5Update(&md5ctx, ra, 16); |
| 438 | MD5Final(digest, &md5ctx); |
| 439 | |
| 440 | for (i = 0; i < 16; i++) |
| 441 | pass[i] ^= digest[i]; |
| 442 | |
| 443 | while (i < passlen) { |
| 444 | MD5Init(&md5ctx); |
| 445 | MD5Update(&md5ctx, s, s_len); |
| 446 | MD5Update(&md5ctx, &pass[i - 16], 16); |
| 447 | MD5Final(digest, &md5ctx); |
| 448 | |
| 449 | for (j = 0; j < 16; j++, i++) |
| 450 | pass[i] ^= digest[j]; |
| 451 | } |
| 452 | |
| 453 | if (radius_put_raw_attr(radpkt, RADIUS_TYPE_USER_PASSWORD2, pass, |
| 454 | passlen) != 0) |
| 455 | goto fail; |
| 456 | |
| 457 | radius_request(_this->radctx, radpkt); |
| 458 | |
| 459 | return; |
| 460 | fail: |
| 461 | if (_this->radctx != NULL((void *)0)) |
| 462 | radius_cancel_request(_this->radctx); |
| 463 | pap_log(_this, LOG_ERR3, "%s() failed: %m", __func__); |
| 464 | pap_response(_this, 0, DEFAULT_ERROR_MESSAGE"Unknown failure"); |
| 465 | |
| 466 | return; |
| 467 | } |
| 468 | |
| 469 | static void |
| 470 | pap_radius_response(void *context, RADIUS_PACKET *pkt, int flags, |
| 471 | RADIUS_REQUEST_CTX reqctx) |
| 472 | { |
| 473 | int code = -1; |
| 474 | const char *reason = NULL((void *)0); |
| 475 | RADIUS_REQUEST_CTX radctx; |
| 476 | pap *_this; |
| 477 | |
| 478 | _this = context; |
| 479 | radctx = _this->radctx; |
Value stored to 'radctx' is never read | |
| 480 | _this->radctx = NULL((void *)0); /* important */ |
| 481 | |
| 482 | if (pkt == NULL((void *)0)) { |
| 483 | if (flags & RADIUS_REQUEST_TIMEOUT0x0002) |
| 484 | reason = "timeout"; |
| 485 | else if (flags & RADIUS_REQUEST_ERROR0x0001) |
| 486 | reason = strerror(errno(*__errno())); |
| 487 | else |
| 488 | reason = "error"; |
| 489 | goto auth_failed; |
| 490 | } |
| 491 | code = radius_get_code(pkt); |
| 492 | if (code == RADIUS_CODE_ACCESS_REJECT3) { |
| 493 | reason="reject"; |
| 494 | goto auth_failed; |
| 495 | } else if (code != RADIUS_CODE_ACCESS_ACCEPT2) { |
| 496 | reason="error"; |
| 497 | goto auth_failed; |
| 498 | } |
| 499 | if ((flags & RADIUS_REQUEST_CHECK_AUTHENTICATOR_OK0x0010) == 0 && |
| 500 | (flags & RADIUS_REQUEST_CHECK_AUTHENTICATOR_NO_CHECK0x0020) == 0) { |
| 501 | reason="bad_authenticator"; |
| 502 | goto auth_failed; |
| 503 | } |
| 504 | /* Authentication succeeded */ |
| 505 | pap_response(_this, 1, DEFAULT_SUCCESS_MESSAGE"OK"); |
| 506 | ppp_process_radius_framed_ip(_this->ppp, pkt); |
| 507 | |
| 508 | return; |
| 509 | auth_failed: |
| 510 | /* Authentication failure */ |
| 511 | pap_log(_this, LOG_WARNING4, "Radius authentication request failed: %s", |
| 512 | reason); |
| 513 | /* log reply messages from radius server */ |
| 514 | if (pkt != NULL((void *)0)) { |
| 515 | char radmsg[255], vissed[1024]; |
| 516 | size_t rmlen = 0; |
| 517 | if ((radius_get_raw_attr(pkt, RADIUS_TYPE_REPLY_MESSAGE18, |
| 518 | radmsg, &rmlen)) == 0) { |
| 519 | if (rmlen != 0) { |
| 520 | strvisx(vissed, radmsg, rmlen, VIS_WHITE(0x04 | 0x08 | 0x10)); |
| 521 | pap_log(_this, LOG_WARNING4, |
| 522 | "Radius reply message: %s", vissed); |
| 523 | } |
| 524 | } |
| 525 | } |
| 526 | |
| 527 | pap_response(_this, 0, DEFAULT_FAILURE_MESSAGE"Unknown username or password"); |
| 528 | } |
| 529 | #endif |