GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/npppd/npppd/npppd_auth.c Lines: 0 215 0.0 %
Date: 2017-11-13 Branches: 0 139 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: npppd_auth.c,v 1.20 2017/08/11 16:41:47 goda 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
/**@file authentication realm */
29
/* $Id: npppd_auth.c,v 1.20 2017/08/11 16:41:47 goda Exp $ */
30
#include <sys/types.h>
31
#include <sys/stat.h>
32
#include <sys/socket.h>
33
#include <netinet/in.h>
34
#include <net/if_dl.h>
35
#include <arpa/inet.h>
36
#include <stdio.h>
37
#include <syslog.h>
38
#include <string.h>
39
#include <time.h>
40
#include <event.h>
41
#include <stdarg.h>
42
#include <stdlib.h>
43
#include <netdb.h>
44
#include <errno.h>
45
46
#include "debugutil.h"
47
#include "slist.h"
48
#include "npppd_local.h"
49
#include "npppd_auth.h"
50
#include "net_utils.h"
51
52
#include "npppd_auth_local.h"
53
54
/**
55
 * Create a npppd_auth_base object.
56
 * @param auth_type	the authentication type.
57
 *	specify {@link ::NPPPD_AUTH_TYPE_LOCAL} to authenticate by the local
58
 *	file, or specify {@link ::NPPPD_AUTH_TYPE_RADIUS} for RADIUS
59
 *	authentication.
60
 * @param name		the configuration name
61
 * @param _npppd	the parent {@link ::npppd} object
62
 * @see	::NPPPD_AUTH_TYPE_LOCAL
63
 * @see	::NPPPD_AUTH_TYPE_RADIUS
64
 * @return The pointer to the {@link ::npppd_auth_base} object will be returned
65
 * in case success otherwise NULL will be returned.
66
 */
67
npppd_auth_base *
68
npppd_auth_create(int auth_type, const char *name, void *_npppd)
69
{
70
	npppd_auth_base *base;
71
72
	NPPPD_AUTH_ASSERT(name != NULL);
73
74
	switch (auth_type) {
75
	case NPPPD_AUTH_TYPE_LOCAL:
76
		if ((base = calloc(1, sizeof(npppd_auth_local))) != NULL) {
77
			base->type = NPPPD_AUTH_TYPE_LOCAL;
78
			strlcpy(base->name, name, sizeof(base->name));
79
			base->npppd = _npppd;
80
81
			return base;
82
		}
83
		break;
84
85
#ifdef USE_NPPPD_RADIUS
86
	case NPPPD_AUTH_TYPE_RADIUS:
87
		if ((base = calloc(1, sizeof(npppd_auth_radius))) != NULL) {
88
			npppd_auth_radius *_this = (npppd_auth_radius *)base;
89
			base->type = NPPPD_AUTH_TYPE_RADIUS;
90
			strlcpy(base->name, name, sizeof(base->name));
91
			base->npppd = _npppd;
92
			if ((_this->rad_auth_setting =
93
			    radius_req_setting_create()) == NULL)
94
				goto radius_fail;
95
			if ((_this->rad_acct_setting =
96
			    radius_req_setting_create()) == NULL)
97
				goto radius_fail;
98
99
			return base;
100
radius_fail:
101
			if (_this->rad_auth_setting != NULL)
102
				radius_req_setting_destroy(
103
				    _this->rad_auth_setting);
104
			if (_this->rad_acct_setting != NULL)
105
				radius_req_setting_destroy(
106
				    _this->rad_acct_setting);
107
			free(base);
108
			return NULL;
109
		}
110
111
		break;
112
#endif
113
114
	default:
115
		NPPPD_AUTH_ASSERT(0);
116
		break;
117
	}
118
119
	return NULL;
120
}
121
122
/**
123
 * Call this function to make the object unusable.
124
 * <p>
125
 * {@link ::npppd_auth_base} objects is refered by the {@link ::npppd_ppp}
126
 * object.   After this funcation is called, npppd will disconnect the PPP
127
 * links that refers the object, it will call {@link ::npppd_auth_destroy()}
128
 * when all the references to the object are released.</p>
129
 */
130
void
131
npppd_auth_dispose(npppd_auth_base *base)
132
{
133
134
	base->disposing = 1;
135
136
	return;
137
}
138
139
/** Destroy the {@link ::npppd_auth_base} object.  */
140
void
141
npppd_auth_destroy(npppd_auth_base *base)
142
{
143
144
	if (base->disposing == 0)
145
		npppd_auth_dispose(base);
146
147
	npppd_auth_base_log(base, LOG_INFO, "Finalized");
148
149
	switch(base->type) {
150
	case NPPPD_AUTH_TYPE_LOCAL:
151
		memset(base, 0, sizeof(npppd_auth_local));
152
		break;
153
154
#ifdef USE_NPPPD_RADIUS
155
	case NPPPD_AUTH_TYPE_RADIUS:
156
	    {
157
		npppd_auth_radius *_this = (npppd_auth_radius *)base;
158
		if (_this->rad_auth_setting != NULL)
159
			radius_req_setting_destroy(_this->rad_auth_setting);
160
		_this->rad_auth_setting = NULL;
161
		if (_this->rad_acct_setting != NULL)
162
			radius_req_setting_destroy(_this->rad_acct_setting);
163
		_this->rad_acct_setting = NULL;
164
		memset(base, 0, sizeof(npppd_auth_local));
165
		break;
166
	    }
167
#endif
168
	}
169
	free(base);
170
171
	return;
172
}
173
174
/** Reload the configuration */
175
int
176
npppd_auth_reload(npppd_auth_base *base)
177
{
178
	struct authconf *auth;
179
180
	TAILQ_FOREACH(auth, &base->npppd->conf.authconfs, entry) {
181
		if (strcmp(auth->name, base->name) == 0)
182
			break;
183
	}
184
	if (auth == NULL)
185
		return 1;
186
187
	base->pppsuffix[0] = '\0';
188
	if (auth->username_suffix != NULL)
189
		strlcpy(base->pppsuffix, auth->username_suffix,
190
		    sizeof(base->pppsuffix));
191
	base->eap_capable = auth->eap_capable;
192
	base->strip_nt_domain = auth->strip_nt_domain;
193
	base->strip_atmark_realm = auth->strip_atmark_realm;
194
	base->has_users_file = 0;
195
	base->radius_ready = 0;
196
	base->user_max_session = auth->user_max_session;
197
198
	if (strlen(auth->users_file_path) > 0) {
199
		strlcpy(base->users_file_path, auth->users_file_path,
200
		    sizeof(base->users_file_path));
201
		base->has_users_file = 1;
202
	} else {
203
		if (base->type == NPPPD_AUTH_TYPE_LOCAL) {
204
			npppd_auth_base_log(base,
205
			    LOG_WARNING, "missing users_file property.");
206
			goto fail;
207
		}
208
	}
209
210
	switch (base->type) {
211
#ifdef USE_NPPPD_RADIUS
212
	case NPPPD_AUTH_TYPE_RADIUS:
213
		if (npppd_auth_radius_reload(base, auth) != 0)
214
			goto fail;
215
		break;
216
#endif
217
	}
218
	base->initialized = 1;
219
220
	return 0;
221
222
fail:
223
	base->initialized = 0;
224
	base->has_users_file = 0;
225
	base->radius_ready = 0;
226
227
	return 1;
228
}
229
230
/**
231
 * This function gets specified user's password. The value 0 is returned
232
 * if the call succeeds.
233
 *
234
 * @param	username	username which gets the password
235
 * @param	password	buffers which stores the password
236
 *				Specify NULL if you want to known the length of
237
 *				the password only.
238
 * @param	lppassword	pointer which indicates the length of
239
 *				the buffer which stores the password.
240
 * @return A value 1 is returned if user is unknown. A value 2 is returned
241
 *				if password buffer is sufficient. A negative value is
242
 *				returned if other error occurred.
243
 */
244
int
245
npppd_auth_get_user_password(npppd_auth_base *base,
246
    const char *username, char *password, int *plpassword)
247
{
248
	int              retval, sz, lpassword;
249
	npppd_auth_user *user;
250
251
	NPPPD_AUTH_ASSERT(base != NULL);
252
	NPPPD_AUTH_DBG((base, LOG_DEBUG, "%s(%s)", __func__, username));
253
254
	user = NULL;
255
	retval = 0;
256
	if (base->has_users_file == 0) {
257
		retval = -1;
258
		goto out;
259
	}
260
	if ((user = npppd_auth_get_user(base, username)) == NULL) {
261
		retval = 1;
262
		goto out;
263
	}
264
	if (password == NULL && plpassword == NULL) {
265
		retval = 0;
266
		goto out;
267
	}
268
	if (plpassword == NULL) {
269
		retval = -1;
270
		goto out;
271
	}
272
	lpassword = strlen(user->password) + 1;
273
	sz = *plpassword;
274
	*plpassword = lpassword;
275
	if (password == NULL) {
276
		retval = 0;
277
		goto out;
278
	}
279
	if (sz < lpassword) {
280
		retval = 2;
281
		goto out;
282
	}
283
	strlcpy(password, user->password, sz);
284
out:
285
	free(user);
286
287
	return retval;
288
}
289
290
/**
291
 * This function gets specified users' Framed-IP-{Address,Netmask}.
292
 * The value 0 is returned if the call succeeds.
293
 * <p>
294
 * Because authentication database is updated at any time, the password is
295
 * possible to be inconsistent if this function is not called immediately
296
 * after authentication. So this function is called immediately after
297
 * authentication. </p>
298
 * @param	username	username which gets the password
299
 * @param	ip4address	pointer which indicates struct in_addr which
300
 *						stores the Framed-IP-Address
301
 * @param	ip4netmask	pointer which indicates struct in_addr which
302
 *						stores Framed-IP-Netmask
303
 */
304
int
305
npppd_auth_get_framed_ip(npppd_auth_base *base, const char *username,
306
    struct in_addr *ip4address, struct in_addr *ip4netmask)
307
{
308
	npppd_auth_user *user;
309
310
	NPPPD_AUTH_ASSERT(base != NULL);
311
	NPPPD_AUTH_DBG((base, LOG_DEBUG, "%s(%s)", __func__, username));
312
	if (base->has_users_file == 0)
313
		return -1;
314
315
	if ((user = npppd_auth_get_user(base, username)) == NULL)
316
		return 1;
317
318
	if (user->framed_ip_address.s_addr != 0) {
319
		*ip4address = user->framed_ip_address;
320
		if (ip4netmask != NULL)
321
			*ip4netmask = user->framed_ip_netmask;
322
323
		free(user);
324
		return 0;
325
	}
326
	free(user);
327
328
	return 1;
329
}
330
331
/**
332
 * Retribute "Calling-Number" attribute of the user from the realm.
333
 *
334
 * @param username	Username.
335
 * @param number	Pointer to the space for the Calling-Number.  This
336
 *	can be NULL in case retributing the Calling-Number only.
337
 * @param plnumber	Pointer to the length of the space for the
338
 *	Calling-Number.
339
 * @return 0 if the Calling-Number attribute is successfully retributed.
340
 *	1 if the user has no Calling-Number attribute.  return -1 if the realm
341
 *	doesn't have user attributes or other errors.   return 2 if the space
342
 *	is not enough.
343
 */
344
int
345
npppd_auth_get_calling_number(npppd_auth_base *base, const char *username,
346
    char *number, int *plnumber)
347
{
348
	int              retval, lcallnum, sz;
349
	npppd_auth_user *user;
350
351
	user = NULL;
352
	retval = 0;
353
	if (base->has_users_file == 0)
354
		return -1;
355
356
	if ((user = npppd_auth_get_user(base, username)) == NULL)
357
		return 1;
358
359
	if (number == NULL && plnumber == NULL) {
360
		retval = 0;
361
		goto out;
362
	}
363
	if (plnumber == NULL) {
364
		retval = -1;
365
		goto out;
366
	}
367
	lcallnum = strlen(user->calling_number) + 1;
368
	sz = *plnumber;
369
	*plnumber = lcallnum;
370
	if (sz < lcallnum) {
371
		retval = 2;
372
		goto out;
373
	}
374
	strlcpy(number, user->calling_number, sz);
375
376
out:
377
	free(user);
378
379
	return retval;
380
}
381
382
int
383
npppd_auth_get_type(npppd_auth_base *base)
384
{
385
	return base->type;
386
}
387
388
int
389
npppd_auth_is_usable(npppd_auth_base *base)
390
{
391
    	return (base->initialized != 0 && base->disposing == 0)? 1 : 0;
392
}
393
394
int
395
npppd_auth_is_ready(npppd_auth_base *base)
396
{
397
	if (!npppd_auth_is_usable(base))
398
		return 0;
399
400
	switch(base->type) {
401
	case NPPPD_AUTH_TYPE_LOCAL:
402
		return (base->has_users_file)? 1 : 0;
403
		/* NOTREACHED */
404
405
	case NPPPD_AUTH_TYPE_RADIUS:
406
		return (base->has_users_file != 0 ||
407
		    base->radius_ready != 0)? 1 : 0;
408
		/* NOTREACHED */
409
	}
410
	NPPPD_AUTH_ASSERT(0);
411
412
    	return 0;
413
}
414
415
int
416
npppd_auth_is_disposing(npppd_auth_base *base)
417
{
418
	return (base->disposing != 0)? 1 : 0;
419
}
420
421
int
422
npppd_auth_is_eap_capable(npppd_auth_base *base)
423
{
424
	return (base->eap_capable != 0)? 1 : 0;
425
}
426
427
const char *
428
npppd_auth_get_name(npppd_auth_base *base)
429
{
430
	return base->name;
431
}
432
433
const char *
434
npppd_auth_get_suffix(npppd_auth_base *base)
435
{
436
	return base->pppsuffix;
437
}
438
439
const char *
440
npppd_auth_username_for_auth(npppd_auth_base *base, const char *username,
441
    char *username_buffer)
442
{
443
	const char *u0;
444
	char *atmark, *u1;
445
446
	u0 = NULL;
447
	if (base->strip_nt_domain != 0) {
448
		if ((u0 = strchr(username, '\\')) != NULL)
449
			u0++;
450
	}
451
	if (u0 == NULL)
452
		u0 = username;
453
	u1 = username_buffer;
454
	if (username_buffer != u0)
455
		memmove(username_buffer, u0, MINIMUM(strlen(u0) + 1,
456
		    MAX_USERNAME_LENGTH));
457
	if (base->strip_atmark_realm != 0) {
458
		if ((atmark = strrchr(u1, '@')) != NULL)
459
			*atmark = '\0';
460
	}
461
462
	return username_buffer;
463
}
464
465
int
466
npppd_auth_user_session_unlimited(npppd_auth_base *_this)
467
{
468
	return (_this->user_max_session == 0) ? 1 : 0;
469
}
470
471
int
472
npppd_check_auth_user_max_session(npppd_auth_base *_this, int count)
473
{
474
	if (!npppd_auth_user_session_unlimited(_this) &&
475
	    _this->user_max_session <= count)
476
		return 1;
477
	else
478
		return 0;
479
}
480
481
/***********************************************************************
482
 * Account list related functions
483
 ***********************************************************************/
484
static npppd_auth_user *
485
npppd_auth_get_user(npppd_auth_base *base, const char *username)
486
{
487
	int              lsuffix, lusername;
488
	const char      *un;
489
	char             buf[MAX_USERNAME_LENGTH];
490
	npppd_auth_user *u;
491
492
	un = username;
493
	lsuffix = strlen(base->pppsuffix);
494
	lusername = strlen(username);
495
	if (lsuffix > 0 && lusername > lsuffix &&
496
	    strcmp(username + lusername - lsuffix, base->pppsuffix) == 0 &&
497
	    lusername - lsuffix < sizeof(buf)) {
498
		memcpy(buf, username, lusername - lsuffix);
499
		buf[lusername - lsuffix] = '\0';
500
		un = buf;
501
	}
502
503
	if (priv_get_user_info(base->users_file_path, un, &u) == 0)
504
		return u;
505
506
	return NULL;
507
}
508
509
#ifdef USE_NPPPD_RADIUS
510
/***********************************************************************
511
 * RADIUS
512
 ***********************************************************************/
513
/** reload the configuration of RADIUS authentication realm */
514
static int
515
npppd_auth_radius_reload(npppd_auth_base *base, struct authconf *auth)
516
{
517
	npppd_auth_radius  *_this = (npppd_auth_radius *)base;
518
	radius_req_setting *rad;
519
	struct radserver   *server;
520
	int                 i, nauth, nacct;
521
522
	_this->rad_auth_setting->timeout =
523
	    (auth->data.radius.auth.timeout == 0)
524
		    ? DEFAULT_RADIUS_TIMEOUT : auth->data.radius.auth.timeout;
525
	_this->rad_acct_setting->timeout =
526
	    (auth->data.radius.acct.timeout == 0)
527
		    ? DEFAULT_RADIUS_TIMEOUT : auth->data.radius.acct.timeout;
528
529
530
	_this->rad_auth_setting->max_tries =
531
	    (auth->data.radius.auth.max_tries == 0)
532
		    ? DEFAULT_RADIUS_MAX_TRIES : auth->data.radius.auth.max_tries;
533
	_this->rad_acct_setting->max_tries =
534
	    (auth->data.radius.acct.max_tries == 0)
535
		    ? DEFAULT_RADIUS_MAX_TRIES : auth->data.radius.acct.max_tries;
536
537
	_this->rad_auth_setting->max_failovers =
538
	    (auth->data.radius.auth.max_failovers == 0)
539
		    ? DEFAULT_RADIUS_MAX_FAILOVERS
540
		    : auth->data.radius.auth.max_failovers;
541
	_this->rad_acct_setting->max_failovers =
542
	    (auth->data.radius.acct.max_failovers == 0)
543
		    ? DEFAULT_RADIUS_MAX_FAILOVERS
544
		    : auth->data.radius.acct.max_failovers;
545
546
	_this->rad_acct_setting->curr_server =
547
	_this->rad_auth_setting->curr_server = 0;
548
549
	/* load configs for authentication server */
550
	rad = _this->rad_auth_setting;
551
	for (i = 0; i < countof(rad->server); i++)
552
		memset(&rad->server[i], 0, sizeof(rad->server[0]));
553
	i = 0;
554
	TAILQ_FOREACH(server, &auth->data.radius.auth.servers, entry) {
555
		if (i >= countof(rad->server))
556
			break;
557
		memcpy(&rad->server[i].peer, &server->address,
558
		    server->address.ss_len);
559
		if (((struct sockaddr_in *)&rad->server[i].peer)->sin_port
560
		    == 0)
561
			((struct sockaddr_in *)&rad->server[i].peer)->sin_port
562
			    = htons(DEFAULT_RADIUS_AUTH_PORT);
563
		strlcpy(rad->server[i].secret, server->secret,
564
		    sizeof(rad->server[i].secret));
565
		rad->server[i].enabled = 1;
566
		i++;
567
	}
568
	nauth = i;
569
570
	/* load configs for accounting server */
571
	rad = _this->rad_acct_setting;
572
	for (i = 0; i < countof(rad->server); i++)
573
		memset(&rad->server[i], 0, sizeof(rad->server[0]));
574
	i = 0;
575
	TAILQ_FOREACH(server, &auth->data.radius.acct.servers, entry) {
576
		if (i >= countof(rad->server))
577
			break;
578
		memcpy(&rad->server[i].peer, &server->address,
579
		    server->address.ss_len);
580
		if (((struct sockaddr_in *)&rad->server[i].peer)->sin_port
581
		    == 0)
582
			((struct sockaddr_in *)&rad->server[i].peer)->sin_port
583
			    = htons(DEFAULT_RADIUS_ACCT_PORT);
584
		strlcpy(rad->server[i].secret, server->secret,
585
		    sizeof(rad->server[i].secret));
586
		rad->server[i].enabled = 1;
587
		i++;
588
	}
589
	nacct = i;
590
591
	for (i = 0; i < countof(_this->rad_auth_setting->server); i++) {
592
		if (_this->rad_auth_setting->server[i].enabled)
593
			base->radius_ready = 1;
594
	}
595
596
	npppd_auth_base_log(&_this->nar_base, LOG_INFO,
597
	    "Loaded configuration.  %d authentication server%s, %d accounting "
598
	    "server%s.",
599
	    nauth, (nauth > 1)? "s" : "", nacct, (nacct > 1)? "s" : "");
600
601
	return 0;
602
}
603
604
/**
605
 * Get {@link ::radius_req_setting} for RADIUS authentication of specified
606
 * {@link ::npppd_auth_base} object.
607
 */
608
void *
609
npppd_auth_radius_get_radius_auth_setting(npppd_auth_radius *_this)
610
{
611
	return _this->rad_auth_setting;
612
}
613
614
/**
615
 * Get {@link ::radius_req_setting} for RADIUS accounting of specified
616
 * {@link ::npppd_auth_base} object.
617
 */
618
void *
619
npppd_auth_radius_get_radius_acct_setting(npppd_auth_radius *_this)
620
{
621
	return _this->rad_acct_setting;
622
}
623
624
#endif
625
626
/***********************************************************************
627
 * Helper functions
628
 ***********************************************************************/
629
/** Log it which starts the label based on this instance. */
630
static int
631
npppd_auth_base_log(npppd_auth_base *_this, int prio, const char *fmt, ...)
632
{
633
	int status;
634
	char logbuf[BUFSIZ];
635
	va_list ap;
636
637
	NPPPD_AUTH_ASSERT(_this != NULL);
638
	va_start(ap, fmt);
639
	snprintf(logbuf, sizeof(logbuf), "realm name=%s %s",
640
	    _this->name, fmt);
641
	status = vlog_printf(prio, logbuf, ap);
642
	va_end(ap);
643
644
	return status;
645
}