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

📄 auth_md5.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Program:	CRAM-MD5 authenticator * * Author:	Mark Crispin *		Networks and Distributed Computing *		Computing & Communications *		University of Washington *		Administration Building, AG-44 *		Seattle, WA  98195 *		Internet: MRC@CAC.Washington.EDU * * Date:	21 October 1998 * Last Edited:	13 April 2000 * * Copyright 2000 by the University of Washington * *  Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * above copyright notice and this permission notice appear in supporting * documentation, and that the name of the University of Washington not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission.  This software is made available * "as is", and * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *//* MD5 context */#define MD5BLKLEN 64		/* MD5 block length */#define MD5DIGLEN 16		/* MD5 digest length */typedef struct {  unsigned long chigh;		/* high 32bits of byte count */  unsigned long clow;		/* low 32bits of byte count */  unsigned long state[4];	/* state (ABCD) */  unsigned char buf[MD5BLKLEN];	/* input buffer */  unsigned char *ptr;		/* buffer position */} MD5CONTEXT;/* Prototypes */long auth_md5_valid (void);long auth_md5_client (authchallenge_t challenger,authrespond_t responder,		      NETMBX *mb,void *stream,unsigned long *trial,char *user);char *auth_md5_server (authresponse_t responder,int argc,char *argv[]);char *auth_md5_pwd (char *user);char *apop_login (char *chal,char *user,char *md5,int argc,char *argv[]);char *hmac_md5 (char *text,unsigned long tl,char *key,unsigned long kl);void md5_init (MD5CONTEXT *ctx);void md5_update (MD5CONTEXT *ctx,unsigned char *data,unsigned long len);void md5_final (unsigned char *digest,MD5CONTEXT *ctx);static void md5_transform (unsigned long *state,unsigned char *block);static void md5_encode (unsigned char *dst,unsigned long *src,int len);static void md5_decode (unsigned long *dst,unsigned char *src,int len);/* Authenticator linkage */AUTHENTICATOR auth_md5 = {  AU_SECURE,			/* secure authenticator */  "CRAM-MD5",			/* authenticator name */  auth_md5_valid,		/* check if valid */  auth_md5_client,		/* client method */  auth_md5_server,		/* server method */  NIL				/* next authenticator */};/* Check if CRAM-MD5 valid on this system * Returns: T, always */long auth_md5_valid (void){  struct stat sbuf;				/* server forbids MD5 if no MD5 enable file */  if (stat (MD5ENABLE,&sbuf)) auth_md5.server = NIL;  return T;			/* MD5 is otherwise valid */}/* Client authenticator * Accepts: challenger function *	    responder function *	    parsed network mailbox structure *	    stream argument for functions *	    pointer to current trial count *	    returned user name * Returns: T if success, NIL otherwise, number of trials incremented if retry */long auth_md5_client (authchallenge_t challenger,authrespond_t responder,		      NETMBX *mb,void *stream,unsigned long *trial,char *user){  char pwd[MAILTMPLEN],resp[MAILTMPLEN];  void *chal;  unsigned long cl;				/* get challenge */  if (chal = (*challenger) (stream,&cl)) {				/* prompt user */    mm_login (mb,user,pwd,*trial);    if (pwd[0]) {		/* got password, build response */      sprintf (resp,"%s %s",user,hmac_md5 (chal,cl,pwd,strlen (pwd)));      fs_give ((void **) &chal);/* don't need challenge any moe */				/* send credentials, allow retry if OK */      if ((*responder) (stream,resp,strlen (resp)) &&	  !(chal = (*challenger) (stream,&cl))) return (long) ++*trial;    }				/* user requested abort */    else (*responder) (stream,NIL,0);  }				/* flush any challenge left behind */  if (chal) fs_give ((void **) &chal);  *trial = 0;			/* retries not permitted */  return NIL;			/* return failure */}/* Server authenticator * Accepts: responder function *	    argument count *	    argument vector * Returns: authenticated user name or NIL * * This is much hairier than it needs to be due to the necessary of zapping * the password data. */char *auth_md5_server (authresponse_t responder,int argc,char *argv[]){  char *ret = NIL;  char *p,*u,*user,*authuser,*hash,chal[MAILTMPLEN];  unsigned long cl,pl;				/* generate challenge */  sprintf (chal,"<%lu.%lu@%s>",(unsigned long) getpid (),	   (unsigned long) time (0),mylocalhost ());				/* send challenge, get user and hash */  if (user = (*responder) (chal,cl = strlen (chal),NIL)) {				/* got user, locate hash */    if (hash = strrchr (user,' ')) {      *hash++ = '\0';		/* tie off user */				/* see if authentication user */      if (authuser = strchr (user,'*')) *authuser++ = '\0';      if (authuser && *authuser) {	if (!(p = auth_md5_pwd (authuser)))	  p = auth_md5_pwd (lcase (authuser));	}      else if (!(p = auth_md5_pwd (user))) p = auth_md5_pwd (lcase (user));      if (p) {			/* quickly verify password */	u = strcmp (hash,hmac_md5 (chal,cl,p,pl = strlen (p))) ? NIL : user;	memset (p,0,pl);	/* erase sensitive information */	fs_give ((void **) &p);	/* flush erased password */				/* now log in for real */	if (u && authserver_login (u,authuser,argc,argv)) ret = myusername ();      }    }    fs_give ((void **) &user);  }  if (!ret) sleep (3);		/* slow down possible cracker */  return ret;}/* Return MD5 password for user * Accepts: user name * Returns: plaintext password if success, else NIL * * This is much hairier than it needs to be due to the necessary of zapping * the password data. */char *auth_md5_pwd (char *user){  struct stat sbuf;  int fd = open (MD5ENABLE,O_RDONLY,NIL);  char *s,*t,*buf;  char *ret = NIL;  if (fd >= 0) {		/* found the file? */    if (!fstat (fd,&sbuf)) {	/* yes, slurp it into memory */      read (fd,buf = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);      for (s = strtok (buf,"\015\012"); s;	   s = ret ? NIL : strtok (NIL,"\015\012"))				/* must be valid entry line */	if ((*s != '#') && (t = strchr (s,'\t'))) {	  *t++ = '\0';		/* found tab, tie off user, point to pwd */	  if (*s && *t && !strcmp (s,user)) ret = cpystr (t);	}				/* erase sensitive information from buffer */      memset (buf,0,sbuf.st_size + 1);      fs_give ((void **) &buf);	/* flush the buffer */    }    close (fd);			/* don't need file any longer */  }  return ret;			/* return password */}/* APOP server login * Accepts: challenge *	    desired user name *	    purported MD5 *	    argument count *	    argument vector * Returns: authenticated user name or NIL */char *apop_login (char *chal,char *user,char *md5,int argc,char *argv[]){  int i,j;  char *ret = NIL;  char *s,*authuser,tmp[MAILTMPLEN];  unsigned char digest[MD5DIGLEN];  MD5CONTEXT ctx;  char *hex = "0123456789abcdef";				/* see if authentication user */  if (authuser = strchr (user,'*')) *authuser++ = '\0';  if (authuser && *authuser) {    if (!(s = auth_md5_pwd (authuser))) s = auth_md5_pwd (lcase (authuser));  }  else if (!(s = auth_md5_pwd (user))) s = auth_md5_pwd (lcase (user));  if (s) {			/* only if found password */    md5_init (&ctx);		/* initialize MD5 context */				/* build string to get MD5 digest */    sprintf (tmp,"%.128s%.128s",chal,s);    memset (s,0,strlen (s));	/* erase sensitive information */    fs_give ((void **) &s);	/* flush erased password */    md5_update (&ctx,(unsigned char *) tmp,strlen (tmp));    memset (tmp,0,MAILTMPLEN);	/* erase sensitive information */    md5_final (digest,&ctx);

⌨️ 快捷键说明

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