📄 rlm_cram.c
字号:
/* * rlm_cram.c * * Version: $Id$ * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2002,2006 The FreeRADIUS server project *//* * CRAM mail authentication (APOP, CRAM-MD5) * by 3APA3A * * rlm_cram module is a part of Mail authorization/authentication * support. * * Attributes used (Vendor Code/PEN: 11406, you may change it to your own) * 101 (Sandy-Mail-Authtype), selects CRAM protocol, possible values: * 2: CRAM-MD5 * 3: APOP * 8: CRAM-MD4 * 9: CRAM-SHA1 * 102 (Sandy-Mail-Challenge), contains server's challenge (usually * text banner) * 103 (Sandy-Mail-Response), contains client's response, 16 octets * for APOP/CRAM-MD5/CRAM-MD4, 20 octets for CRAM-SHA1 * * (c) 2002 by SANDY (http://www.sandy.ru/) under GPL */#include <freeradius-devel/ident.h>RCSID("$Id$")#include <freeradius-devel/radiusd.h>#include <freeradius-devel/modules.h>#include <freeradius-devel/md5.h>#include <ctype.h>#define SM_AUTHTYPE ((11406<<16)|101)#define SM_CHALLENGE ((11406<<16)|102)#define SM_RESPONSE ((11406<<16)|103)static void calc_apop_digest(char * buffer, const char * challenge, int challen, const char * password){ FR_MD5_CTX Context; fr_MD5Init(&Context); fr_MD5Update(&Context,challenge,challen); fr_MD5Update(&Context,password,strlen(password)); fr_MD5Final(buffer,&Context);}static void calc_md5_digest(char * buffer, const char * challenge, int challen, const char * password){ char buf[1024]; int i; FR_MD5_CTX Context; memset(buf, 0, 1024); memset(buf, 0x36, 64); for(i=0; i<64 && password[i]; i++) buf[i]^=password[i]; memcpy(buf+64, challenge, challen); fr_MD5Init(&Context); fr_MD5Update(&Context,buf,64+challen); memset(buf, 0x5c, 64); for(i=0; i<64 && password[i]; i++) buf[i]^=password[i]; fr_MD5Final(buf+64,&Context); fr_MD5Init(&Context); fr_MD5Update(&Context,buf,64+16); fr_MD5Final(buffer,&Context);}static void calc_md4_digest(char * buffer, const char * challenge, int challen, const char * password){ char buf[1024]; int i; FR_MD4_CTX Context; memset(buf, 0, 1024); memset(buf, 0x36, 64); for(i=0; i<64 && password[i]; i++) buf[i]^=password[i]; memcpy(buf+64, challenge, challen); fr_MD4Init(&Context); fr_MD4Update(&Context,buf,64+challen); memset(buf, 0x5c, 64); for(i=0; i<64 && password[i]; i++) buf[i]^=password[i]; fr_MD4Final(buf+64,&Context); fr_MD4Init(&Context); fr_MD4Update(&Context,buf,64+16); fr_MD4Final(buffer,&Context);}static void calc_sha1_digest(char * buffer, const char * challenge, int challen, const char * password){ char buf[1024]; int i; fr_SHA1_CTX Context; memset(buf, 0, 1024); memset(buf, 0x36, 64); for(i=0; i<64 && password[i]; i++) buf[i]^=password[i]; memcpy(buf+64, challenge, challen); fr_SHA1Init(&Context); fr_SHA1Update(&Context,buf,64+challen); memset(buf, 0x5c, 64); for(i=0; i<64 && password[i]; i++) buf[i]^=password[i]; fr_SHA1Final(buf+64,&Context); fr_SHA1Init(&Context); fr_SHA1Update(&Context,buf,64+20); fr_SHA1Final(buffer,&Context);}static int cram_authenticate(UNUSED void * instance, REQUEST *request){ VALUE_PAIR *authtype, *challenge, *response, *password; char buffer[64]; password = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD); if(!password) { radlog(L_AUTH, "rlm_cram: Cleartext-Password is required for authentication."); return RLM_MODULE_INVALID; } authtype = pairfind(request->packet->vps, SM_AUTHTYPE); if(!authtype) { radlog(L_AUTH, "rlm_cram: Required attribute Sandy-Mail-Authtype missed"); return RLM_MODULE_INVALID; } challenge = pairfind(request->packet->vps, SM_CHALLENGE); if(!challenge) { radlog(L_AUTH, "rlm_cram: Required attribute Sandy-Mail-Challenge missed"); return RLM_MODULE_INVALID; } response = pairfind(request->packet->vps, SM_RESPONSE); if(!response) { radlog(L_AUTH, "rlm_cram: Required attribute Sandy-Mail-Response missed"); return RLM_MODULE_INVALID; } switch(authtype->vp_integer){ case 2: /* CRAM-MD5 */ if(challenge->length < 5 || response->length != 16) { radlog(L_AUTH, "rlm_cram: invalid MD5 challenge/response length"); return RLM_MODULE_INVALID; } calc_md5_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue); if(!memcmp(buffer, response->vp_strvalue, 16)) return RLM_MODULE_OK; break; case 3: /* APOP */ if(challenge->length < 5 || response->length != 16) { radlog(L_AUTH, "rlm_cram: invalid APOP challenge/response length"); return RLM_MODULE_INVALID; } calc_apop_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue); if(!memcmp(buffer, response->vp_strvalue, 16)) return RLM_MODULE_OK; break; case 8: /* CRAM-MD4 */ if(challenge->length < 5 || response->length != 16) { radlog(L_AUTH, "rlm_cram: invalid MD4 challenge/response length"); return RLM_MODULE_INVALID; } calc_md4_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue); if(!memcmp(buffer, response->vp_strvalue, 16)) return RLM_MODULE_OK; break; case 9: /* CRAM-SHA1 */ if(challenge->length < 5 || response->length != 20) { radlog(L_AUTH, "rlm_cram: invalid MD4 challenge/response length"); return RLM_MODULE_INVALID; } calc_sha1_digest(buffer, challenge->vp_strvalue, challenge->length, password->vp_strvalue); if(!memcmp(buffer, response->vp_strvalue, 20)) return RLM_MODULE_OK; break; default: radlog(L_AUTH, "rlm_cram: unsupported Sandy-Mail-Authtype"); return RLM_MODULE_INVALID; } return RLM_MODULE_NOTFOUND;}module_t rlm_cram = { RLM_MODULE_INIT, "CRAM", RLM_TYPE_THREAD_SAFE, /* type */ NULL, /* instantiation */ NULL, /* detach */ { cram_authenticate, /* authenticate */ NULL, /* authorize */ NULL, /* pre-accounting */ NULL, /* accounting */ NULL, /* checksimul */ NULL, /* pre-proxy */ NULL, /* post-proxy */ NULL /* post-auth */ },};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -