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

📄 auth_md5.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ======================================================================== * Copyright 1988-2007 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * *  * ======================================================================== *//* * 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:	30 January 2007 *//* 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,		      char *service,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 *	    SASL service name *	    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,		      char *service,NETMBX *mb,void *stream,		      unsigned long *trial,char *user){  char pwd[MAILTMPLEN];  void *challenge;  unsigned long clen;  long ret = NIL;				/* get challenge */  if (challenge = (*challenger) (stream,&clen)) {    pwd[0] = NIL;		/* prompt user */    mm_login (mb,user,pwd,*trial);    if (!pwd[0]) {		/* user requested abort */      fs_give ((void **) &challenge);      (*responder) (stream,NIL,0);      *trial = 0;		/* cancel subsequent attempts */      ret = LONGT;		/* will get a BAD response back */    }    else {			/* got password, build response */      sprintf (pwd,"%.65s %.33s",user,hmac_md5 (challenge,clen,						pwd,strlen (pwd)));      fs_give ((void **) &challenge);				/* send credentials, allow retry if OK */      if ((*responder) (stream,pwd,strlen (pwd))) {	if (challenge = (*challenger) (stream,&clen))	  fs_give ((void **) &challenge);	else {	  ++*trial;		/* can try again if necessary */	  ret = LONGT;		/* check the authentication */	}      }    }  }  memset (pwd,0,MAILTMPLEN);	/* erase password in case not overwritten */  if (!ret) *trial = 65535;	/* don't retry if bad protocol */  return ret;}/* 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. */static int md5try = MAXLOGINTRIALS;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';				/* get password */      if (p = auth_md5_pwd ((authuser && *authuser) ? authuser : user)) {	pl = strlen (p);	u = (md5try && !strcmp (hash,hmac_md5 (chal,cl,p,pl))) ? user : NIL;	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 ();	else if (md5try) --md5try;      }    }    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.  That's why we don't use stdio here. */char *auth_md5_pwd (char *user){  struct stat sbuf;  int fd = open (MD5ENABLE,O_RDONLY,NIL);  unsigned char *s,*t,*buf,*lusr,*lret;  char *r;  char *ret = NIL;  if (fd >= 0) {		/* found the file? */    fstat (fd,&sbuf);		/* yes, slurp it into memory */    read (fd,buf = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);				/* see if any uppercase characters in user */    for (s = user; *s && ((*s < 'A') || (*s > 'Z')); s++);				/* yes, make lowercase copy */    lusr = *s ? lcase (cpystr (user)) : NIL;    for (s = strtok_r ((char *) buf,"\015\012",&r),lret = NIL; s;	 s = ret ? NIL : strtok_r (NIL,"\015\012",&r))				/* must be valid entry line */      if (*s && (*s != '#') && (t = strchr (s,'\t')) && t[1]) {	*t++ = '\0';		/* found tab, tie off user, point to pwd */	if (!strcmp (s,user)) ret = cpystr (t);	else if (lusr && !lret) if (!strcmp (s,lusr)) lret = t;      }				/* accept case-independent name */    if (!ret && lret) ret = cpystr (lret);				/* don't need lowercase copy any more */    if (lusr) fs_give ((void **) &lusr);				/* 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';				/* get password */  if (s = auth_md5_pwd ((authuser && *authuser) ? authuser : user)) {    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 + -