Bug Summary

File:src/libexec/login_radius/raddauth.c
Warning:line 548, column 4
Potential leak of memory pointed to by 'host'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name raddauth.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/libexec/login_radius/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/libexec/login_radius/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/libexec/login_radius/raddauth.c
1/* $OpenBSD: raddauth.c,v 1.31 2023/03/02 16:13:57 millert Exp $ */
2
3/*-
4 * Copyright (c) 1996, 1997 Berkeley Software Design, Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Berkeley Software Design,
17 * Inc.
18 * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
19 * or promote products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * BSDI $From: raddauth.c,v 1.6 1998/04/14 00:39:04 prb Exp $
35 */
36/*
37 * Copyright(c) 1996 by tfm associates.
38 * All rights reserved.
39 *
40 * tfm associates
41 * P.O. Box 2086
42 * Eugene OR 97402-0031
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. The name of tfm associates may not be used to endorse or promote
53 * products derived from this software without specific prior written
54 * permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY TFM ASSOC``AS IS'' AND ANY EXPRESS OR
57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
58 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
59 * IN NO EVENT SHALL TFM ASSOCIATES BE LIABLE FOR ANY DIRECT, INDIRECT,
60 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
61 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
62 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
63 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
64 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
65 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66 */
67
68#include <sys/types.h>
69#include <sys/socket.h>
70#include <netinet/in.h>
71#include <arpa/inet.h>
72
73#include <ctype.h>
74#include <err.h>
75#include <errno(*__errno()).h>
76#include <stdint.h>
77#include <limits.h>
78#include <login_cap.h>
79#include <netdb.h>
80#include <signal.h>
81#include <stdio.h>
82#include <stdlib.h>
83#include <string.h>
84#include <syslog.h>
85#include <time.h>
86#include <unistd.h>
87#include <md5.h>
88#include <readpassphrase.h>
89#include "login_radius.h"
90
91
92#define MAXPWNETNAM64 64 /* longest username */
93#define MAXSECRETLEN128 128 /* maximum length of secret */
94
95#define AUTH_VECTOR_LEN16 16
96#define AUTH_HDR_LEN20 20
97#define AUTH_PASS_LEN(256 - 16) (256 - 16)
98#define PW_AUTHENTICATION_REQUEST1 1
99#define PW_AUTHENTICATION_ACK2 2
100#define PW_AUTHENTICATION_REJECT3 3
101#define PW_ACCESS_CHALLENGE11 11
102#define PW_USER_NAME1 1
103#define PW_PASSWORD2 2
104#define PW_CLIENT_ID4 4
105#define PW_CLIENT_PORT_ID5 5
106#define PW_PORT_MESSAGE18 18
107#define PW_STATE24 24
108
109#ifndef RADIUS_DIR"/etc/raddb"
110#define RADIUS_DIR"/etc/raddb" "/etc/raddb"
111#endif
112#define RADIUS_SERVERS"servers" "servers"
113
114char *radius_dir = RADIUS_DIR"/etc/raddb";
115char auth_secret[MAXSECRETLEN128+1];
116volatile sig_atomic_t timedout;
117int alt_retries;
118int retries;
119int sockfd;
120int timeout;
121in_addr_t alt_server;
122in_addr_t auth_server;
123in_port_t radius_port;
124
125typedef struct {
126 u_char code;
127 u_char id;
128 u_short length;
129 u_char vector[AUTH_VECTOR_LEN16];
130 u_char data[4096 - AUTH_HDR_LEN20];
131} auth_hdr_t;
132
133void servtimeout(int);
134in_addr_t get_ipaddr(char *);
135in_addr_t gethost(void);
136int rad_recv(char *, char *, u_char *);
137void parse_challenge(auth_hdr_t *, char *, char *);
138void rad_request(u_char, char *, char *, int, char *, char *);
139void getsecret(void);
140
141/*
142 * challenge -- NULL for interactive service
143 * password -- NULL for interactive service and when requesting a challenge
144 */
145int
146raddauth(char *username, char *class, char *style, char *challenge,
147 char *password, char **emsg)
148{
149 static char _pwstate[1024];
150 u_char req_id;
151 char *userstyle, *passwd, *pwstate, *rad_service;
152 char pbuf[AUTH_PASS_LEN(256 - 16)+1];
153 int auth_port;
154 char vector[AUTH_VECTOR_LEN16+1], *p, *v;
155 int i;
156 login_cap_t *lc;
157 u_int32_t r;
158 struct servent *svp;
159 struct sockaddr_in sin;
160 struct sigaction sa;
161 const char *errstr;
162
163 memset(_pwstate, 0, sizeof(_pwstate));
164 pwstate = password ? challenge : _pwstate;
1
Assuming 'password' is null
2
'?' condition is false
165
166 if ((lc = login_getclass(class)) == NULL((void *)0)) {
3
Assuming the condition is false
4
Taking false branch
167 snprintf(_pwstate, sizeof(_pwstate),
168 "%s: no such class", class);
169 *emsg = _pwstate;
170 return (1);
171 }
172
173 rad_service = login_getcapstr(lc, "radius-port", "radius", "radius");
174 timeout = login_getcapnum(lc, "radius-timeout", 2, 2);
175 retries = login_getcapnum(lc, "radius-retries", 6, 6);
176
177 if (timeout < 1)
5
Assuming 'timeout' is >= 1
6
Taking false branch
178 timeout = 1;
179 if (retries < 2)
7
Assuming 'retries' is >= 2
8
Taking false branch
180 retries = 2;
181
182 if (challenge == NULL((void *)0)) {
9
Assuming 'challenge' is not equal to NULL
10
Taking false branch
183 passwd = NULL((void *)0);
184 v = login_getcapstr(lc, "radius-challenge-styles",
185 NULL((void *)0), NULL((void *)0));
186 i = strlen(style);
187 while (v && (p = strstr(v, style)) != NULL((void *)0)) {
188 if ((p == v || p[-1] == ',') &&
189 (p[i] == ',' || p[i] == '\0')) {
190 passwd = "";
191 break;
192 }
193 v = p+1;
194 }
195 if (passwd == NULL((void *)0))
196 passwd = readpassphrase("Password:", pbuf, sizeof(pbuf),
197 RPP_ECHO_OFF0x00);
198 } else
199 passwd = password;
200 if (passwd
10.1
'passwd' is equal to NULL
== NULL((void *)0))
11
Taking true branch
201 passwd = "";
202
203 if ((v = login_getcapstr(lc, "radius-server", NULL((void *)0), NULL((void *)0))) == NULL((void *)0)){
12
Assuming the condition is false
13
Taking false branch
204 *emsg = "radius-server not configured";
205 return (1);
206 }
207
208 auth_server = get_ipaddr(v);
209
210 if ((v = login_getcapstr(lc, "radius-server-alt", NULL((void *)0), NULL((void *)0))) == NULL((void *)0))
14
Assuming the condition is true
15
Taking true branch
211 alt_server = 0;
212 else {
213 alt_server = get_ipaddr(v);
214 alt_retries = retries/2;
215 retries >>= 1;
216 }
217
218 /* get port number */
219 radius_port = strtonum(rad_service, 1, UINT16_MAX0xffff, &errstr);
220 if (errstr) {
16
Assuming 'errstr' is non-null
17
Taking true branch
221 svp = getservbyname(rad_service, "udp");
222 if (svp == NULL((void *)0)) {
18
Assuming 'svp' is not equal to NULL
19
Taking false branch
223 snprintf(_pwstate, sizeof(_pwstate),
224 "No such service: %s/udp", rad_service);
225 *emsg = _pwstate;
226 return (1);
227 }
228 radius_port = svp->s_port;
229 } else
230 radius_port = htons(radius_port)(__uint16_t)(__builtin_constant_p(radius_port) ? (__uint16_t)
(((__uint16_t)(radius_port) & 0xffU) << 8 | ((__uint16_t
)(radius_port) & 0xff00U) >> 8) : __swap16md(radius_port
))
;
231
232 /* get the secret from the servers file */
233 getsecret();
20
Calling 'getsecret'
234
235 /* set up socket */
236 if ((sockfd = socket(AF_INET2, SOCK_DGRAM2, 0)) == -1) {
237 snprintf(_pwstate, sizeof(_pwstate), "%s", strerror(errno(*__errno())));
238 *emsg = _pwstate;
239 return (1);
240 }
241
242 /* set up client structure */
243 memset(&sin, 0, sizeof(sin));
244 sin.sin_family = AF_INET2;
245 sin.sin_addr.s_addr = INADDR_ANY((u_int32_t)(0x00000000));
246 sin.sin_port = radius_port;
247
248 req_id = (u_char) arc4random();
249 auth_port = ttyslot();
250 if (auth_port == 0)
251 auth_port = (int)getppid();
252 if (strcmp(style, "radius") != 0) {
253 if (asprintf(&userstyle, "%s:%s", username, style) == -1)
254 err(1, NULL((void *)0));
255 } else
256 userstyle = username;
257
258 /* generate random vector */
259 for (i = 0; i < AUTH_VECTOR_LEN16;) {
260 r = arc4random();
261 memcpy(&vector[i], &r, sizeof(r));
262 i += sizeof(r);
263 }
264 vector[AUTH_VECTOR_LEN16] = '\0';
265
266 sigemptyset(&sa.sa_mask);
267 sa.sa_handler__sigaction_u.__sa_handler = servtimeout;
268 sa.sa_flags = 0; /* don't restart system calls */
269 (void)sigaction(SIGALRM14, &sa, NULL((void *)0));
270retry:
271 if (timedout) {
272 timedout = 0;
273 if (--retries <= 0) {
274 /*
275 * If we ran out of tries but there is an alternate
276 * server, switch to it and try again.
277 */
278 if (alt_retries) {
279 auth_server = alt_server;
280 retries = alt_retries;
281 alt_retries = 0;
282 getsecret();
283 } else
284 warnx("no response from authentication server");
285 }
286 }
287
288 if (retries > 0) {
289 rad_request(req_id, userstyle, passwd, auth_port, vector,
290 pwstate);
291
292 switch (i = rad_recv(_pwstate, challenge, vector)) {
293 case PW_AUTHENTICATION_ACK2:
294 /*
295 * Make sure we don't think a challenge was issued.
296 */
297 if (challenge)
298 *challenge = '\0';
299 return (0);
300
301 case PW_AUTHENTICATION_REJECT3:
302 return (1);
303
304 case PW_ACCESS_CHALLENGE11:
305 /*
306 * If this is a response then reject them if
307 * we got a challenge.
308 */
309 if (password)
310 return (1);
311 /*
312 * If we wanted a challenge, just return
313 */
314 if (challenge) {
315 if (strcmp(challenge, _pwstate) != 0)
316 syslog(LOG_WARNING4,
317 "challenge for %s does not match state",
318 userstyle);
319 return (0);
320 }
321 req_id++;
322 if ((passwd = readpassphrase("", pbuf, sizeof(pbuf),
323 RPP_ECHO_OFF0x00)) == NULL((void *)0))
324 passwd = "";
325 break;
326
327 default:
328 if (timedout)
329 goto retry;
330 snprintf(_pwstate, sizeof(_pwstate),
331 "invalid response type %d\n", i);
332 *emsg = _pwstate;
333 return (1);
334 }
335 }
336 return (1);
337}
338
339/*
340 * Build a radius authentication digest and submit it to the radius server
341 */
342void
343rad_request(u_char id, char *name, char *password, int port, char *vector,
344 char *state)
345{
346 auth_hdr_t auth;
347 int i, len, secretlen, total_length, p;
348 struct sockaddr_in sin;
349 u_char md5buf[MAXSECRETLEN128+AUTH_VECTOR_LEN16], digest[AUTH_VECTOR_LEN16],
350 pass_buf[AUTH_PASS_LEN(256 - 16)], *pw, *ptr;
351 u_int length;
352 in_addr_t ipaddr;
353 MD5_CTX context;
354
355 memset(&auth, 0, sizeof(auth));
356 auth.code = PW_AUTHENTICATION_REQUEST1;
357 auth.id = id;
358 memcpy(auth.vector, vector, AUTH_VECTOR_LEN16);
359 total_length = AUTH_HDR_LEN20;
360 ptr = auth.data;
361
362 /* User name */
363 *ptr++ = PW_USER_NAME1;
364 length = strlen(name);
365 if (length > MAXPWNETNAM64)
366 length = MAXPWNETNAM64;
367 *ptr++ = length + 2;
368 memcpy(ptr, name, length);
369 ptr += length;
370 total_length += length + 2;
371
372 /* Password */
373 length = strlen(password);
374 if (length > AUTH_PASS_LEN(256 - 16))
375 length = AUTH_PASS_LEN(256 - 16);
376
377 p = (length + AUTH_VECTOR_LEN16 - 1) / AUTH_VECTOR_LEN16;
378 *ptr++ = PW_PASSWORD2;
379 *ptr++ = p * AUTH_VECTOR_LEN16 + 2;
380
381 memset(pass_buf, 0, sizeof(pass_buf)); /* must zero fill */
382 strlcpy((char *)pass_buf, password, sizeof(pass_buf));
383
384 /* Calculate the md5 digest */
385 secretlen = strlen(auth_secret);
386 memcpy(md5buf, auth_secret, secretlen);
387 memcpy(md5buf + secretlen, auth.vector, AUTH_VECTOR_LEN16);
388
389 total_length += 2;
390
391 /* XOR the password into the md5 digest */
392 pw = pass_buf;
393 while (p-- > 0) {
394 MD5Init(&context);
395 MD5Update(&context, md5buf, secretlen + AUTH_VECTOR_LEN16);
396 MD5Final(digest, &context);
397 for (i = 0; i < AUTH_VECTOR_LEN16; ++i) {
398 *ptr = digest[i] ^ *pw;
399 md5buf[secretlen+i] = *ptr++;
400 *pw++ = '\0';
401 }
402 total_length += AUTH_VECTOR_LEN16;
403 }
404 explicit_bzero(pass_buf, strlen(pass_buf));
405
406 /* Client id */
407 *ptr++ = PW_CLIENT_ID4;
408 *ptr++ = sizeof(in_addr_t) + 2;
409 ipaddr = gethost();
410 memcpy(ptr, &ipaddr, sizeof(in_addr_t));
411 ptr += sizeof(in_addr_t);
412 total_length += sizeof(in_addr_t) + 2;
413
414 /* client port */
415 *ptr++ = PW_CLIENT_PORT_ID5;
416 *ptr++ = sizeof(in_addr_t) + 2;
417 port = htonl(port)(__uint32_t)(__builtin_constant_p(port) ? (__uint32_t)(((__uint32_t
)(port) & 0xff) << 24 | ((__uint32_t)(port) & 0xff00
) << 8 | ((__uint32_t)(port) & 0xff0000) >> 8
| ((__uint32_t)(port) & 0xff000000) >> 24) : __swap32md
(port))
;
418 memcpy(ptr, &port, sizeof(int));
419 ptr += sizeof(int);
420 total_length += sizeof(int) + 2;
421
422 /* Append the state info */
423 if ((state != NULL((void *)0)) && (strlen(state) > 0)) {
424 len = strlen(state);
425 *ptr++ = PW_STATE24;
426 *ptr++ = len + 2;
427 memcpy(ptr, state, len);
428 ptr += len;
429 total_length += len + 2;
430 }
431
432 auth.length = htons(total_length)(__uint16_t)(__builtin_constant_p(total_length) ? (__uint16_t
)(((__uint16_t)(total_length) & 0xffU) << 8 | ((__uint16_t
)(total_length) & 0xff00U) >> 8) : __swap16md(total_length
))
;
433
434 memset(&sin, 0, sizeof (sin));
435 sin.sin_family = AF_INET2;
436 sin.sin_addr.s_addr = auth_server;
437 sin.sin_port = radius_port;
438 if (sendto(sockfd, &auth, total_length, 0, (struct sockaddr *)&sin,
439 sizeof(sin)) == -1)
440 err(1, NULL((void *)0));
441}
442
443/*
444 * Receive UDP responses from the radius server
445 */
446int
447rad_recv(char *state, char *challenge, u_char *req_vector)
448{
449 auth_hdr_t auth;
450 socklen_t salen;
451 struct sockaddr_in sin;
452 u_char recv_vector[AUTH_VECTOR_LEN16], test_vector[AUTH_VECTOR_LEN16];
453 MD5_CTX context;
454 ssize_t total_length;
455
456 salen = sizeof(sin);
457
458 alarm(timeout);
459 total_length = recvfrom(sockfd, &auth, sizeof(auth), 0,
460 (struct sockaddr *)&sin, &salen);
461 alarm(0);
462 if (total_length < AUTH_HDR_LEN20) {
463 if (timedout)
464 return(-1);
465 errx(1, "bogus auth packet from server");
466 }
467 if (ntohs(auth.length)(__uint16_t)(__builtin_constant_p(auth.length) ? (__uint16_t)
(((__uint16_t)(auth.length) & 0xffU) << 8 | ((__uint16_t
)(auth.length) & 0xff00U) >> 8) : __swap16md(auth.length
))
> total_length)
468 errx(1, "bogus auth packet from server");
469
470 if (sin.sin_addr.s_addr != auth_server)
471 errx(1, "bogus authentication server");
472
473 /* verify server's shared secret */
474 memcpy(recv_vector, auth.vector, AUTH_VECTOR_LEN16);
475 memcpy(auth.vector, req_vector, AUTH_VECTOR_LEN16);
476 MD5Init(&context);
477 MD5Update(&context, (u_char *)&auth, ntohs(auth.length)(__uint16_t)(__builtin_constant_p(auth.length) ? (__uint16_t)
(((__uint16_t)(auth.length) & 0xffU) << 8 | ((__uint16_t
)(auth.length) & 0xff00U) >> 8) : __swap16md(auth.length
))
);
478 MD5Update(&context, auth_secret, strlen(auth_secret));
479 MD5Final(test_vector, &context);
480 if (memcmp(recv_vector, test_vector, AUTH_VECTOR_LEN16) != 0)
481 errx(1, "shared secret incorrect");
482
483 if (auth.code == PW_ACCESS_CHALLENGE11)
484 parse_challenge(&auth, state, challenge);
485
486 return (auth.code);
487}
488
489/*
490 * Get IP address of local hostname
491 */
492in_addr_t
493gethost(void)
494{
495 char hostname[HOST_NAME_MAX255+1];
496
497 if (gethostname(hostname, sizeof(hostname)))
498 err(1, "gethost");
499 return (get_ipaddr(hostname));
500}
501
502/*
503 * Get an IP address in host in_addr_t notation from a hostname or dotted quad.
504 */
505in_addr_t
506get_ipaddr(char *host)
507{
508 struct hostent *hp;
509
510 if ((hp = gethostbyname(host)) == NULL((void *)0))
511 return (0);
512
513 return (((struct in_addr *)hp->h_addrh_addr_list[0])->s_addr);
514}
515
516/*
517 * Get the secret from the servers file
518 */
519void
520getsecret(void)
521{
522 FILE *servfd;
523 char *host, *secret, buffer[PATH_MAX1024];
524 size_t len;
525
526 snprintf(buffer, sizeof(buffer), "%s/%s",
527 radius_dir, RADIUS_SERVERS"servers");
528
529 if ((servfd = fopen(buffer, "r")) == NULL((void *)0)) {
21
Assuming the condition is false
22
Taking false branch
530 syslog(LOG_ERR3, "%s: %m", buffer);
531 return;
532 }
533
534 secret = NULL((void *)0); /* Keeps gcc happy */
535 while ((host = fgetln(servfd, &len)) != NULL((void *)0)) {
23
Assuming the condition is true
24
Loop condition is true. Entering loop body
38
Execution continues on line 535
39
Assuming the condition is true
40
Loop condition is true. Entering loop body
536 if (*host == '#') {
25
Assuming the condition is false
26
Taking false branch
41
Assuming the condition is false
42
Taking false branch
537 memset(host, 0, len);
538 continue;
539 }
540 if (host[len-1] == '\n')
27
Assuming the condition is false
28
Taking false branch
43
Assuming the condition is false
44
Taking false branch
541 --len;
542 else {
543 /* No trailing newline, must allocate len+1 for NUL */
544 if ((secret = malloc(len + 1)) == NULL((void *)0)) {
29
Memory is allocated
30
Assuming the condition is false
31
Taking false branch
45
Assuming the condition is false
46
Taking false branch
545 memset(host, 0, len);
546 continue;
547 }
548 memcpy(secret, host, len);
47
Potential leak of memory pointed to by 'host'
549 memset(host, 0, len);
550 host = secret;
551 }
552 while (len
31.1
'len' is > 0
> 0 && isspace((unsigned char)host[--len]))
32
Assuming the character is not a whitespace character
33
Loop condition is false. Execution continues on line 554
553 ;
554 host[++len] = '\0';
555 while (isspace((unsigned char)*host)) {
34
Assuming the character is not a whitespace character
35
Loop condition is false. Execution continues on line 559
556 ++host;
557 --len;
558 }
559 if (*host == '\0')
36
Assuming the condition is true
37
Taking true branch
560 continue;
561 secret = host;
562 while (*secret && !isspace((unsigned char)*secret))
563 ++secret;
564 if (*secret)
565 *secret++ = '\0';
566 if (get_ipaddr(host) != auth_server) {
567 memset(host, 0, len);
568 continue;
569 }
570 while (isspace((unsigned char)*secret))
571 ++secret;
572 if (*secret)
573 break;
574 }
575 if (host) {
576 strlcpy(auth_secret, secret, sizeof(auth_secret));
577 memset(host, 0, len);
578 }
579 fclose(servfd);
580}
581
582void
583servtimeout(int signo)
584{
585
586 timedout = 1;
587}
588
589/*
590 * Parse a challenge received from the server
591 */
592void
593parse_challenge(auth_hdr_t *authhdr, char *state, char *challenge)
594{
595 int length;
596 int attribute, attribute_len;
597 u_char *ptr;
598
599 ptr = authhdr->data;
600 length = ntohs(authhdr->length)(__uint16_t)(__builtin_constant_p(authhdr->length) ? (__uint16_t
)(((__uint16_t)(authhdr->length) & 0xffU) << 8 |
((__uint16_t)(authhdr->length) & 0xff00U) >> 8)
: __swap16md(authhdr->length))
- AUTH_HDR_LEN20;
601
602 *state = 0;
603
604 while (length > 0) {
605 attribute = *ptr++;
606 attribute_len = *ptr++;
607 length -= attribute_len;
608 attribute_len -= 2;
609
610 switch (attribute) {
611 case PW_PORT_MESSAGE18:
612 if (challenge) {
613 memcpy(challenge, ptr, attribute_len);
614 challenge[attribute_len] = '\0';
615 } else
616 printf("%.*s", attribute_len, ptr);
617 break;
618 case PW_STATE24:
619 memcpy(state, ptr, attribute_len);
620 state[attribute_len] = '\0';
621 break;
622 }
623 ptr += attribute_len;
624 }
625}