Bug Summary

File:src/usr.sbin/npppd/npppd/pap.c
Warning:line 479, column 2
Value stored to 'radctx' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pap.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/npppd/npppd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/npppd/npppd/../common -I /usr/src/usr.sbin/npppd/npppd -I /usr/src/usr.sbin/npppd/npppd/../pptp -I /usr/src/usr.sbin/npppd/npppd/../l2tp -I /usr/src/usr.sbin/npppd/npppd/../pppoe -D USE_NPPPD_PPTP -D USE_NPPPD_L2TP -D USE_NPPPD_PPPOE -D __COPYRIGHT(x)= -D __RCSID(x)= -D NPPPD_MAX_IFACE=8 -D NPPPD_MAX_POOL=8 -D USE_NPPPD_MPPE -D USE_NPPPD_PIPEX -D USE_NPPPD_RADIUS -D USE_SA_COOKIE -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/npppd/npppd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/npppd/npppd/pap.c
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
89static void pap_log (pap *, uint32_t, const char *, ...) __printflike(3,4)__attribute__((__format__ (__printf__, 3, 4)));
90static void pap_response (pap *, int, const char *);
91static void pap_authenticate(pap *, const char *);
92static void pap_local_authenticate (pap *, const char *, const char *);
93#ifdef USE_NPPPD_RADIUS1
94static void pap_radius_authenticate (pap *, const char *, const char *);
95static void pap_radius_response (void *, RADIUS_PACKET *, int, RADIUS_REQUEST_CTX);
96#endif
97
98#ifdef __cplusplus
99extern "C" {
100#endif
101
102void pap_init (pap *, npppd_ppp *);
103int pap_start (pap *);
104int pap_stop (pap *);
105int pap_input (pap *, u_char *, int);
106
107#ifdef __cplusplus
108}
109#endif
110
111void
112pap_init(pap *_this, npppd_ppp *ppp)
113{
114 _this->ppp = ppp;
115 _this->state = PAP_STATE_INITIAL0;
116 _this->auth_id = -1;
117}
118
119int
120pap_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
134int
135pap_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 */
150int
151pap_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;
232fail:
233 pap_response(_this, 0, DEFAULT_FAILURE_MESSAGE"Unknown username or password");
234 return -1;
235}
236
237static void
238pap_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 }
261fail:
262 pap_response(_this, 0, DEFAULT_FAILURE_MESSAGE"Unknown username or password");
263}
264
265static void
266pap_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
278static void
279pap_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
329static void
330pap_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 ***********************************************************************/
350int
351pap_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
383static void
384pap_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;
460fail:
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
469static void
470pap_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;
509auth_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