⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlm_pap.c

📁 新的radius程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * rlm_pap.c * * Version:  $Id: rlm_pap.c,v 1.15.2.2.2.5 2007/04/08 06:31:38 aland Exp $ * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2001  The FreeRADIUS server project * Copyright 2001  Kostas Kalevras <kkalev@noc.ntua.gr> */#include "autoconf.h"#include "libradius.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "radiusd.h"#include "modules.h"#include "conffile.h"#include "../../include/md5.h"#include "../../include/sha1.h"#define PAP_ENC_INVALID	-1#define PAP_ENC_CLEAR		0#define PAP_ENC_CRYPT		1#define PAP_ENC_MD5		2#define PAP_ENC_SHA1		3#define PAP_ENC_NT		4#define PAP_ENC_LM		5#define PAP_ENC_SMD5		6#define PAP_ENC_SSHA		7#define PAP_ENC_NS_MTA_MD5	8#define PAP_ENC_AUTO		9#define PAP_MAX_ENC		9static const char rcsid[] = "$Id: rlm_pap.c,v 1.15.2.2.2.5 2007/04/08 06:31:38 aland Exp $";/* *      Define a structure for our module configuration. * *      These variables do not need to be in a structure, but it's *      a lot cleaner to do so, and a pointer to the structure can *      be used as the instance handle. */typedef struct rlm_pap_t {	const char *name;	/* CONF_SECTION->name, not strdup'd */        char *scheme;  /* password encryption scheme */	int sch;	char norm_passwd;	int auto_header;} rlm_pap_t;/* *      A mapping of configuration file names to internal variables. * *      Note that the string is dynamically allocated, so it MUST *      be freed.  When the configuration file parse re-reads the string, *      it free's the old one, and strdup's the new one, placing the pointer *      to the strdup'd string into 'config.string'.  This gets around *      buffer over-flows. */static CONF_PARSER module_config[] = {  { "encryption_scheme", PW_TYPE_STRING_PTR, offsetof(rlm_pap_t,scheme), NULL, "crypt" },	{ "auto_header", PW_TYPE_BOOLEAN, offsetof(rlm_pap_t,auto_header), NULL, "no" },  { NULL, -1, 0, NULL, NULL }};static const LRAD_NAME_NUMBER schemes[] = {	{ "clear", PAP_ENC_CLEAR },	{ "crypt", PAP_ENC_CRYPT },	{ "md5", PAP_ENC_MD5 },	{ "sha1", PAP_ENC_SHA1 },	{ "nt", PAP_ENC_NT },	{ "lm", PAP_ENC_LM },	{ "smd5", PAP_ENC_SMD5 },	{ "ssha", PAP_ENC_SSHA },	{ "auto", PAP_ENC_AUTO },	{ NULL, PAP_ENC_INVALID }};/* *	For auto-header discovery. */static const LRAD_NAME_NUMBER header_names[] = {	{ "{clear}",	PW_CLEARTEXT_PASSWORD },	{ "{cleartext}", PW_CLEARTEXT_PASSWORD },	{ "{md5}",	PW_MD5_PASSWORD },	{ "{smd5}",	PW_SMD5_PASSWORD },	{ "{crypt}",	PW_CRYPT_PASSWORD },	{ "{sha}",	PW_SHA_PASSWORD },	{ "{ssha}",	PW_SSHA_PASSWORD },	{ "{nt}",	PW_NT_PASSWORD },	{ "{x-nthash}",	PW_NT_PASSWORD },	{ "{ns-mta-md5}", PW_NS_MTA_MD5_PASSWORD },	{ NULL, 0 }};static int pap_detach(void *instance){	rlm_pap_t *inst = (rlm_pap_t *) instance;	free((char *)inst->scheme);	free(inst);	return 0;}static int pap_instantiate(CONF_SECTION *conf, void **instance){        rlm_pap_t *inst;        /*         *      Set up a storage area for instance data         */        inst = rad_malloc(sizeof(*inst));	if (!inst) {		return -1;	}	memset(inst, 0, sizeof(*inst));        /*         *      If the configuration parameters can't be parsed, then         *      fail.         */        if (cf_section_parse(conf, inst, module_config) < 0) {                pap_detach(inst);                return -1;        }	if (inst->scheme == NULL || strlen(inst->scheme) == 0){		radlog(L_ERR, "rlm_pap: No scheme defined");		pap_detach(inst);		return -1;	}	inst->sch = lrad_str2int(schemes, inst->scheme, PAP_ENC_INVALID);	if (inst->sch == PAP_ENC_INVALID) {		radlog(L_ERR, "rlm_pap: Unknown scheme \"%s\"", inst->scheme);		pap_detach(inst);		return -1;	}        *instance = inst;	inst->name = cf_section_name2(conf);	if (!inst->name) {		inst->name = cf_section_name1(conf);	}        return 0;}/* *	Decode one base64 chunk */static int decode_it(const char *src, uint8_t *dst){	int i;	unsigned int x = 0;	for(i = 0; i < 4; i++) {		if (src[i] >= 'A' && src[i] <= 'Z')			x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);		else if (src[i] >= 'a' && src[i] <= 'z')			 x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);		else if(src[i] >= '0' && src[i] <= '9') 			 x = (x << 6) + (unsigned int)(src[i] - '0' + 52);		else if(src[i] == '+')			x = (x << 6) + 62;		else if (src[i] == '/')			x = (x << 6) + 63;		else if (src[i] == '=')			x = (x << 6);		else return 0;	}		dst[2] = (unsigned char)(x & 255); x >>= 8;	dst[1] = (unsigned char)(x & 255); x >>= 8;	dst[0] = (unsigned char)(x & 255); x >>= 8;		return 1;}/* *	Base64 decoding. */static int base64_decode (const char *src, uint8_t *dst){	int length, equals;	int i, num;	uint8_t last[3];	length = equals = 0;	while (src[length] && src[length] != '=') length++;	while (src[length + equals] == '=') equals++;	num = (length + equals) / 4;		for (i = 0; i < num - 1; i++) {		if (!decode_it(src, dst)) return 0;		src += 4;		dst += 3;	}	decode_it(src, last);	for (i = 0; i < (3 - equals); i++) {		dst[i] = last[i];	}	return (num * 3) - equals;}/* *	Hex or base64 or bin auto-discovery. */static void normify(VALUE_PAIR *vp, int min_length){	int decoded;	char buffer[64];		if ((size_t) min_length >= sizeof(buffer)) return; /* paranoia */	/*	 *	Hex encoding.	 */	if (vp->length >= (2 * min_length)) {		decoded = lrad_hex2bin(vp->strvalue, buffer, vp->length >> 1);		if (decoded == (vp->length >> 1)) {			DEBUG2("rlm_pap: Normalizing %s from hex encoding", vp->name);			memcpy(vp->strvalue, buffer, decoded);			vp->length = decoded;			return;		}	}	/*	 *	Base 64 encoding.  It's at least 4/3 the original size,	 *	and we want to avoid division...	 */	if ((vp->length * 3) >= ((min_length * 4))) {		decoded = base64_decode(vp->strvalue, buffer);		if (decoded >= min_length) {			DEBUG2("rlm_pap: Normalizing %s from base64 encoding", vp->name);			memcpy(vp->strvalue, buffer, decoded);			vp->length = decoded;			return;		}	}	/*	 *	Else unknown encoding, or already binary.  Leave it.	 */}/* *	Authorize the user for PAP authentication. * *	This isn't strictly necessary, but it does make the *	server simpler to configure. */static int pap_authorize(void *instance, REQUEST *request){	rlm_pap_t *inst = instance;	int auth_type = FALSE;	int found_pw = FALSE;	int user_pw = FALSE;	VALUE_PAIR *vp, *next;	VALUE_PAIR *cleartext_pw = NULL;	for (vp = request->config_items; vp != NULL; vp = next) {		next = vp->next;		switch (vp->attribute) {		case PW_USER_PASSWORD: /* deprecated */			user_pw = TRUE;			found_pw = TRUE;			/*			 *	Look for '{foo}', and use them			 */			if (!inst->auto_header ||			    (vp->strvalue[0] != '{')) {				break;			}			/* FALL-THROUGH */		case PW_PASSWORD_WITH_HEADER: /* preferred */		{			int attr;			uint8_t *p, *q;			char buffer[64];			VALUE_PAIR *new_vp;						found_pw = TRUE;			q = vp->strvalue;			p = strchr(q + 1, '}');			if (!p) {				/*				 *	FIXME: Turn it into a				 *	cleartext-password, unless it,				 *	or user-password already				 *	exists.				 */				break;			}						if ((size_t) (p - q) > sizeof(buffer)) break;						memcpy(buffer, q, p - q + 1);			buffer[p - q + 1] = '\0';						attr = lrad_str2int(header_names, buffer, 0);			if (!attr) {				DEBUG2("rlm_pap: Found unknown header {%s}: Not doing anything", buffer);				break;			}						new_vp = paircreate(attr, PW_TYPE_STRING);			if (!new_vp) break; /* OOM */						strcpy(new_vp->strvalue, p + 1);/* bounds OK */			new_vp->length = strlen(new_vp->strvalue);			pairadd(&request->config_items, new_vp);			/*			 *	May be old-style User-Password with header.			 *	We've found the header & created the proper			 *	attribute, so we should delete the old			 *	User-Password here.			 */			pairdelete(&request->config_items, PW_USER_PASSWORD);		}			break;		case PW_CLEARTEXT_PASSWORD:			cleartext_pw = vp;		case PW_CRYPT_PASSWORD:		case PW_NS_MTA_MD5_PASSWORD:			found_pw = TRUE;			break;	/* don't touch these */		case PW_MD5_PASSWORD:		case PW_SMD5_PASSWORD:		case PW_NT_PASSWORD:		case PW_LM_PASSWORD:			normify(vp, 16); /* ensure it's in the right format */			found_pw = TRUE;			break;		case PW_SHA_PASSWORD:		case PW_SSHA_PASSWORD:			normify(vp, 20); /* ensure it's in the right format */			found_pw = TRUE;			break;			/*			 *	If it's proxied somewhere, don't complain			 *	about not having passwords or Auth-Type.			 */		case PW_PROXY_TO_REALM:		{			REALM *realm = realm_find(vp->strvalue, 0);			if (realm &&			    (realm->ipaddr != htonl(INADDR_NONE))) {				return RLM_MODULE_NOOP;			}			break;		}		case PW_AUTH_TYPE:			auth_type = TRUE;			/*			 *	Auth-Type := Accept			 *	Auth-Type := Reject			 */			if ((vp->lvalue == 254) ||			    (vp->lvalue == 4)) {			    found_pw = 1;			}			break;		default:			break;	/* ignore it */					}	}	/*	 *	Print helpful warnings if there was no password.	 */	if (!found_pw) {		DEBUG("rlm_pap: WARNING! No \"known good\" password found for the user.  Authentication may fail because of this.");		return RLM_MODULE_NOOP;	}	/*	 *	For backwards compatibility with all of the other

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -