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

📄 imap4r1.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 5 页
字号:
/* IMAP authenticate * Accepts: stream to authenticate *	    parsed network mailbox structure *	    scratch buffer *	    place to return user name * Returns: T on success, NIL on failure */long imap_auth (MAILSTREAM *stream,NETMBX *mb,char *tmp,char *usr){  unsigned long trial,ua;  int ok;  char tag[16];  char *lsterr = NIL;  AUTHENTICATOR *at;  IMAPPARSEDREPLY *reply;  for (ua = LOCAL->cap.auth, LOCAL->saslcancel = NIL; LOCAL->netstream && ua &&       (at = mail_lookup_auth (find_rightmost_bit (&ua) + 1));) {    if (lsterr) {		/* previous authenticator failed? */      sprintf (tmp,"Retrying using %s authentication after %.80s",	       at->name,lsterr);      mm_log (tmp,NIL);      fs_give ((void **) &lsterr);    }    trial = 0;			/* initial trial count */    tmp[0] = '\0';		/* no error */    do {			/* gensym a new tag */      if (lsterr) {		/* previous attempt with this one failed? */	sprintf (tmp,"Retrying %s authentication after %.80s",at->name,lsterr);	mm_log (tmp,WARN);	fs_give ((void **) &lsterr);      }      LOCAL->saslcancel = NIL;      sprintf (tag,"%08lx",0xffffffff & (stream->gensym++));				/* build command */      sprintf (tmp,"%s AUTHENTICATE %s",tag,at->name);      if (imap_soutr (stream,tmp)) {				/* hide client authentication responses */	if (!(at->flags & AU_SECURE)) LOCAL->sensitive = T;	ok = (*at->client) (imap_challenge,imap_response,"imap",mb,stream,			    &trial,usr);	LOCAL->sensitive = NIL;	/* unhide */				/* make sure have a response */	if (!(reply = &LOCAL->reply)->tag)	  reply = imap_fake (stream,tag,			     "[CLOSED] IMAP connection broken (authenticate)");	else if (compare_cstring (reply->tag,tag))	  while (compare_cstring ((reply = imap_reply (stream,tag))->tag,tag))	    imap_soutr (stream,"*");				/* good if SASL ok and success response */	if (ok && imap_OK (stream,reply)) return T;	if (!trial) {		/* if main program requested cancellation */	  mm_log ("IMAP Authentication cancelled",ERROR);	  return NIL;	}				/* no error if protocol-initiated cancel */	lsterr = cpystr (reply->text);      }    }    while (LOCAL->netstream && !LOCAL->byeseen && trial &&	   (trial < imap_maxlogintrials));  }  if (lsterr) {			/* previous authenticator failed? */    if (!LOCAL->saslcancel) {	/* don't do this if a cancel */      sprintf (tmp,"Can not authenticate to IMAP server: %.80s",lsterr);      mm_log (tmp,ERROR);    }    fs_give ((void **) &lsterr);  }  return NIL;			/* ran out of authenticators */}/* IMAP login * Accepts: stream to login *	    parsed network mailbox structure *	    scratch buffer of length MAILTMPLEN *	    place to return user name * Returns: T on success, NIL on failure */long imap_login (MAILSTREAM *stream,NETMBX *mb,char *pwd,char *usr){  unsigned long trial = 0;  IMAPPARSEDREPLY *reply;  IMAPARG *args[3];  IMAPARG ausr,apwd;  long ret = NIL;  if (stream->secure)		/* never do LOGIN if want security */    mm_log ("Can't do secure authentication with this server",ERROR);				/* never do LOGIN if server disabled it */  else if (LOCAL->cap.logindisabled)    mm_log ("Server disables LOGIN, no recognized SASL authenticator",ERROR);  else if (mb->authuser[0])	/* never do LOGIN with /authuser */    mm_log ("Can't do /authuser with this server",ERROR);  else {			/* OK to try login */    ausr.type = apwd.type = ASTRING;    ausr.text = (void *) usr;    apwd.text = (void *) pwd;    args[0] = &ausr; args[1] = &apwd; args[2] = NIL;    do {      pwd[0] = 0;		/* prompt user for password */      mm_login (mb,usr,pwd,trial++);      if (pwd[0]) {		/* send login command if have password */	LOCAL->sensitive = T;	/* hide this command */				/* send "LOGIN usr pwd" */	if (imap_OK (stream,reply = imap_send (stream,"LOGIN",args)))	  ret = LONGT;		/* success */	else {	  mm_log (reply->text,WARN);	  if (!LOCAL->referral && (trial == imap_maxlogintrials))	    mm_log ("Too many login failures",ERROR);	}	LOCAL->sensitive = NIL;	/* unhide */      }				/* user refused to give password */      else mm_log ("Login aborted",ERROR);    } while (!ret && pwd[0] && (trial < imap_maxlogintrials) &&	     LOCAL->netstream && !LOCAL->byeseen && !LOCAL->referral);  }  memset (pwd,0,MAILTMPLEN);	/* erase password */  return ret;}/* Get challenge to authenticator in binary * Accepts: stream *	    pointer to returned size * Returns: challenge or NIL if not challenge */void *imap_challenge (void *s,unsigned long *len){  char tmp[MAILTMPLEN];  void *ret = NIL;  MAILSTREAM *stream = (MAILSTREAM *) s;  IMAPPARSEDREPLY *reply = NIL;				/* get tagged response or challenge */  while (stream && LOCAL->netstream &&	 (reply = imap_parse_reply (stream,net_getline (LOCAL->netstream))) &&	 !strcmp (reply->tag,"*")) imap_parse_unsolicited (stream,reply);				/* parse challenge if have one */  if (stream && LOCAL->netstream && reply && reply->tag &&      (*reply->tag == '+') && !reply->tag[1] && reply->text &&      !(ret = rfc822_base64 ((unsigned char *) reply->text,			     strlen (reply->text),len))) {    sprintf (tmp,"IMAP SERVER BUG (invalid challenge): %.80s",	     (char *) reply->text);    mm_log (tmp,ERROR);  }  return ret;}/* Send authenticator response in BASE64 * Accepts: MAIL stream *	    string to send *	    length of string * Returns: T if successful, else NIL */long imap_response (void *s,char *response,unsigned long size){  MAILSTREAM *stream = (MAILSTREAM *) s;  unsigned long i,j,ret;  char *t,*u;  if (response) {		/* make CRLFless BASE64 string */    if (size) {      for (t = (char *) rfc822_binary ((void *) response,size,&i),u = t,j = 0;	   j < i; j++) if (t[j] > ' ') *u++ = t[j];      *u = '\0';		/* tie off string for mm_dlog() */      if (stream->debug) mail_dlog (t,LOCAL->sensitive);				/* append CRLF */      *u++ = '\015'; *u++ = '\012';      ret = net_sout (LOCAL->netstream,t,u - t);      fs_give ((void **) &t);    }    else ret = imap_soutr (stream,"");  }  else {			/* abort requested */    ret = imap_soutr (stream,"*");    LOCAL->saslcancel = T;	/* mark protocol-requested SASL cancel */  }  return ret;}/* IMAP close * Accepts: MAIL stream *	    option flags */void imap_close (MAILSTREAM *stream,long options){  THREADER *thr,*t;  IMAPPARSEDREPLY *reply;  if (stream && LOCAL) {	/* send "LOGOUT" */    if (!LOCAL->byeseen) {	/* don't even think of doing it if saw a BYE */				/* expunge silently if requested */      if (options & CL_EXPUNGE)	imap_send (stream,LEVELIMAP4 (stream) ? "CLOSE" : "EXPUNGE",NIL);      if (LOCAL->netstream &&	  !imap_OK (stream,reply = imap_send (stream,"LOGOUT",NIL)))	mm_log (reply->text,WARN);    }				/* close NET connection if still open */    if (LOCAL->netstream) net_close (LOCAL->netstream);    LOCAL->netstream = NIL;				/* free up memory */    if (LOCAL->sortdata) fs_give ((void **) &LOCAL->sortdata);    if (LOCAL->namespace) {      mail_free_namespace (&LOCAL->namespace[0]);      mail_free_namespace (&LOCAL->namespace[1]);      mail_free_namespace (&LOCAL->namespace[2]);      fs_give ((void **) &LOCAL->namespace);    }    if (LOCAL->threaddata) mail_free_threadnode (&LOCAL->threaddata);				/* flush threaders */    if (thr = LOCAL->cap.threader) while (t = thr) {      fs_give ((void **) &t->name);      thr = t->next;      fs_give ((void **) &t);    }    if (LOCAL->referral) fs_give ((void **) &LOCAL->referral);    if (LOCAL->user) fs_give ((void **) &LOCAL->user);    if (LOCAL->reply.line) fs_give ((void **) &LOCAL->reply.line);    if (LOCAL->reform) fs_give ((void **) &LOCAL->reform);				/* nuke the local data */    fs_give ((void **) &stream->local);  }}/* IMAP fetch fast information * Accepts: MAIL stream *	    sequence *	    option flags * * Generally, imap_structure is preferred */void imap_fast (MAILSTREAM *stream,char *sequence,long flags){  IMAPPARSEDREPLY *reply = imap_fetch (stream,sequence,flags & FT_UID);  if (!imap_OK (stream,reply)) mm_log (reply->text,ERROR);}/* IMAP fetch flags * Accepts: MAIL stream *	    sequence *	    option flags */void imap_flags (MAILSTREAM *stream,char *sequence,long flags){				/* send "FETCH sequence FLAGS" */  char *cmd = (LEVELIMAP4 (stream) && (flags & FT_UID)) ? "UID FETCH":"FETCH";  IMAPPARSEDREPLY *reply;  IMAPARG *args[3],aseq,aatt;  if (LOCAL->loser) sequence = imap_reform_sequence (stream,sequence,						     flags & FT_UID);  aseq.type = SEQUENCE; aseq.text = (void *) sequence;  aatt.type = ATOM; aatt.text = (void *) "FLAGS";  args[0] = &aseq; args[1] = &aatt; args[2] = NIL;  if (!imap_OK (stream,reply = imap_send (stream,cmd,args)))    mm_log (reply->text,ERROR);}/* IMAP fetch overview * Accepts: MAIL stream, sequence bits set *	    pointer to overview return function * Returns: T if successful, NIL otherwise */long imap_overview (MAILSTREAM *stream,overview_t ofn){  MESSAGECACHE *elt;  ENVELOPE *env;  OVERVIEW ov;  char *s,*t;  unsigned long i,start,last,len,slen;  if (!LOCAL->netstream) return NIL;				/* build overview sequence */  for (i = 1,len = start = last = 0,s = t = NIL; i <= stream->nmsgs; ++i)    if ((elt = mail_elt (stream,i))->sequence) {      if (!elt->private.msg.env) {	if (s) {		/* continuing a sequence */	  if (i == last + 1) last = i;	  else {		/* end of range */	    if (last != start) sprintf (t,":%lu,%lu",last,i);	    else sprintf (t,",%lu",i);	    if ((len - (slen = (t += strlen (t)) - s)) < 20) {	      fs_resize ((void **) &s,len += MAILTMPLEN);	      t = s + slen;	/* relocate current pointer */	    }	    start = last = i;	/* begin a new range */	  }	}	else {			/* first time, start new buffer */	  s = (char *) fs_get (len = MAILTMPLEN);	  sprintf (s,"%lu",start = last = i);	  t = s + strlen (s);	/* end of buffer */	}      }    }				/* last sequence */  if (last != start) sprintf (t,":%lu",last);  if (s) {			/* prefetch as needed */    imap_fetch (stream,s,FT_NEEDENV);    fs_give ((void **) &s);  }  ov.optional.lines = 0;	/* now overview each message */  ov.optional.xref = NIL;  if (ofn) for (i = 1; i <= stream->nmsgs; i++)    if (((elt = mail_elt (stream,i))->sequence) &&	(env = mail_fetch_structure (stream,i,NIL,NIL)) && ofn) {      ov.subject = env->subject;      ov.from = env->from;      ov.date = env->date;      ov.message_id = env->message_id;      ov.references = env->references;      ov.optional.octets = elt->rfc822_size;      (*ofn) (stream,mail_uid (stream,i),&ov,i);    }  return LONGT;}/* IMAP fetch structure * Accepts: MAIL stream *	    message # to fetch *	    pointer to return body *	    option flags * Returns: envelope of this message, body returned in body value * * Fetches the "fast" information as well */ENVELOPE *imap_structure (MAILSTREAM *stream,unsigned long msgno,BODY **body,			  long flags){  unsigned long i,j,k,x;  char *s,seq[MAILTMPLEN],tmp[MAILTMPLEN];  MESSAGECACHE *elt;  ENVELOPE **env;  BODY **b;  IMAPPARSEDREPLY *reply = NIL;  IMAPARG *args[3],aseq,aatt;  SEARCHSET *set = LOCAL->lookahead;  LOCAL->lookahead = NIL;  args[0] = &aseq; args[1] = &aatt; args[2] = NIL;  aseq.type = SEQUENCE; aseq.text = (void *) seq;  aatt.type = ATOM; aatt.text = NIL;  if (flags & FT_UID)		/* see if can find msgno from UID */    for (i = 1; i <= stream->nmsgs; i++)      if ((elt = mail_elt (stream,i))->private.uid == msgno) {	msgno = i;		/* found msgno, use it from now on */	flags &= ~FT_UID;	/* no longer a UID fetch */      }  sprintf (s = seq,"%lu",msgno);/* initial sequence */  if (LEVELIMAP4 (stream) && (flags & FT_UID)) {    /* UID fetching is requested and we can't map the UID to a message sequence     * number.  Assume that the message isn't cached at all.     */    if (!imap_OK (stream,reply = imap_fetch (stream,seq,FT_NEEDENV +					     (body ? FT_NEEDBODY : NIL) +					     (flags & (FT_UID + FT_NOHDRS)))))      mm_log (reply->text,ERROR);				/* now hunt for this UID */    for (i = 1; i <= stream->nmsgs; i++)      if ((elt = mail_elt (stream,i))->private.uid == msgno) {	if (body) *body = elt->private.msg.body;

⌨️ 快捷键说明

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