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

📄 ssl_nt.c

📁 广泛使用的邮件服务器!同时
💻 C
📖 第 1 页 / 共 2 页
字号:
  stream = NIL;			/* no stream returned */  switch (*reason) {		/* analyze reason */  case '*':			/* certificate failure */    ++reason;			/* skip over certificate failure indication */				/* pass to error callback */    if (sf) (*sf) (host,reason,flags);    else {			/* no error callback, build error message */      sprintf (tmp,"Certificate failure for %.80s: %.512s",host,reason);      mm_log (tmp,ERROR);    }  case '\0':			/* user answered no to certificate callback */    if (flags & NET_TRYSSL)	/* return dummy stream to stop tryssl */      stream = (SSLSTREAM *) memset (fs_get (sizeof (SSLSTREAM)),0,				     sizeof (SSLSTREAM));    break;  default:			/* non-certificate failure */    if (flags & NET_TRYSSL);	/* no error output if tryssl */				/* pass to error callback */    else if (sf) (*sf) (host,reason,flags);    else {			/* no error callback, build error message */      sprintf (tmp,"TLS/SSL failure for %.80s: %.512s",host,reason);      mm_log (tmp,ERROR);    }    break;  }  fs_give ((void **) &buf);	/* flush temporary buffer */  return stream;}/* Generate error text from SSL error code * Accepts: SSL status *	    scratch buffer * Returns: text if error status, else NIL */static char *ssl_analyze_status (SECURITY_STATUS err,char *buf){  switch (err) {  case SEC_E_OK:		/* no error */  case SEC_I_CONTINUE_NEEDED:  case SEC_I_INCOMPLETE_CREDENTIALS:  case SEC_E_INCOMPLETE_MESSAGE:    return NIL;  case SEC_E_NO_AUTHENTICATING_AUTHORITY:    mm_log ("unexpected SEC_E_NO_AUTHENTICATING_AUTHORITY",NIL);    return "*No authority could be contacted for authentication";  case SEC_E_WRONG_PRINCIPAL:    mm_log ("unexpected SEC_E_WRONG_PRINCIPAL",NIL);  case CERT_E_CN_NO_MATCH:    return "*Server name does not match certificate";  case SEC_E_UNTRUSTED_ROOT:    mm_log ("unexpected SEC_E_UNTRUSTED_ROOT",NIL);  case CERT_E_UNTRUSTEDROOT:    return "*Self-signed certificate or untrusted authority";  case SEC_E_CERT_EXPIRED:    mm_log ("unexpected SEC_E_CERT_EXPIRED",NIL);  case CERT_E_EXPIRED:    return "*Certificate has expired";  case CERT_E_REVOKED:    return "*Certificate revoked";  case SEC_E_INVALID_TOKEN:    return "Invalid token, probably not an SSL server";  case SEC_E_UNSUPPORTED_FUNCTION:    return "SSL not supported on this machine - upgrade your system software";  }  sprintf (buf,"Unexpected SSPI or certificate error %lx - report this",err);  return buf;}/* SSL receive line * Accepts: SSL stream * Returns: text line string or NIL if failure */char *ssl_getline (SSLSTREAM *stream){  unsigned long n,contd;  char *ret = ssl_getline_work (stream,&n,&contd);  if (ret && contd) {		/* got a line needing continuation? */    STRINGLIST *stl = mail_newstringlist ();    STRINGLIST *stc = stl;    do {			/* collect additional lines */      stc->text.data = (unsigned char *) ret;      stc->text.size = n;      stc = stc->next = mail_newstringlist ();      ret = ssl_getline_work (stream,&n,&contd);    } while (ret && contd);    if (ret) {			/* stash final part of line on list */      stc->text.data = (unsigned char *) ret;      stc->text.size = n;				/* determine how large a buffer we need */      for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size;      ret = fs_get (n + 1);	/* copy parts into buffer */      for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next)	memcpy (ret + n,stc->text.data,stc->text.size);      ret[n] = '\0';    }    mail_free_stringlist (&stl);/* either way, done with list */  }  return ret;}/* SSL receive line or partial line * Accepts: SSL stream *	    pointer to return size *	    pointer to return continuation flag * Returns: text line string, size and continuation flag, or NIL if failure */static char *ssl_getline_work (SSLSTREAM *stream,unsigned long *size,			       long *contd){  unsigned long n;  char *s,*ret,c,d;  *contd = NIL;			/* assume no continuation */				/* make sure have data */  if (!ssl_getdata (stream)) return NIL;  for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) {    d = *stream->iptr++;	/* slurp another character */    if ((c == '\015') && (d == '\012')) {      ret = (char *) fs_get (n--);      memcpy (ret,s,*size = n);	/* copy into a free storage string */      ret[n] = '\0';		/* tie off string with null */      return ret;    }  }				/* copy partial string from buffer */  memcpy ((ret = (char *) fs_get (n)),s,*size = n);				/* get more data from the net */  if (!ssl_getdata (stream)) fs_give ((void **) &ret);				/* special case of newline broken by buffer */  else if ((c == '\015') && (*stream->iptr == '\012')) {    stream->iptr++;		/* eat the line feed */    stream->ictr--;    ret[*size = --n] = '\0';	/* tie off string with null */  }  else *contd = LONGT;		/* continuation needed */  return ret;}/* SSL receive buffer * Accepts: SSL stream *	    size in bytes *	    buffer to read into * Returns: T if success, NIL otherwise */long ssl_getbuffer (SSLSTREAM *stream,unsigned long size,char *buffer){  unsigned long n;  while (size > 0) {		/* until request satisfied */    if (!ssl_getdata (stream)) return NIL;    n = min (size,stream->ictr);/* number of bytes to transfer */				/* do the copy */    memcpy (buffer,stream->iptr,n);    buffer += n;		/* update pointer */    stream->iptr += n;    size -= n;			/* update # of bytes to do */    stream->ictr -= n;  }  buffer[0] = '\0';		/* tie off string */  return T;}/* SSL receive data * Accepts: TCP/IP stream * Returns: T if success, NIL otherwise */long ssl_getdata (SSLSTREAM *stream){  while (stream->ictr < 1) {	/* decrypted buffer empty? */    SECURITY_STATUS status;    SecBuffer buf[4];    SecBufferDesc msg;    size_t i;    size_t n = 0;		/* initially no bytes to decrypt */    do {			/* yes, make sure have data from TCP */      if (stream->iextractr) {	/* have previous unread data? */	memcpy (stream->ibuf + n,stream->iextraptr,stream->iextractr);	n += stream->iextractr;	/* update number of bytes read */	stream->iextractr = 0;	/* no more extra data */      }      else {			/* read from TCP */	if (!tcp_getdata (stream->tcpstream)) return ssl_abort (stream);				/* maximum amount of data to copy */	if (!(i = min (stream->bufsize - n,stream->tcpstream->ictr)))	  fatal ("incomplete SecBuffer exceeds maximum buffer size");				/* do the copy */	memcpy (stream->ibuf + n,stream->tcpstream->iptr,i);	stream->tcpstream->iptr += i;	stream->tcpstream->ictr -= i;	n += i;			/* update number of bytes to decrypt */      }      buf[0].cbBuffer = n;	/* first SecBuffer gets data */      buf[0].pvBuffer = stream->ibuf;      buf[0].BufferType = SECBUFFER_DATA;				/* subsequent ones are for spares */      buf[1].BufferType = buf[2].BufferType = buf[3].BufferType =	SECBUFFER_EMPTY;      msg.ulVersion = SECBUFFER_VERSION;      msg.cBuffers = 4;		/* number of SecBuffers */      msg.pBuffers = buf;	/* first SecBuffer */    } while ((status = ((DECRYPT_MESSAGE_FN) sft->Reserved4)	      (&stream->context,&msg,0,NIL)) == SEC_E_INCOMPLETE_MESSAGE);    switch (status) {    case SEC_E_OK:		/* won */    case SEC_I_RENEGOTIATE:	/* won but lost it after this buffer */				/* hunt for a buffer */      for (i = 0; (i < 4) && (buf[i].BufferType != SECBUFFER_DATA) ; i++);      if (i < 4) {		/* found a buffer? */				/* yes, set up pointer and counter */	stream->iptr = buf[i].pvBuffer;	stream->ictr = buf[i].cbBuffer;				/* any unprocessed data? */	while (++i < 4) if (buf[i].BufferType == SECBUFFER_EXTRA) {				/* yes, note for next time around */	  stream->iextraptr = buf[i].pvBuffer;	  stream->iextractr = buf[i].cbBuffer;	}      }      break;    default:			/* anything else means we've lost */      return ssl_abort (stream);    }  }  return LONGT;}/* SSL send string as record * Accepts: SSL stream *	    string pointer * Returns: T if success else NIL */long ssl_soutr (SSLSTREAM *stream,char *string){  return ssl_sout (stream,string,(unsigned long) strlen (string));}/* SSL send string * Accepts: SSL stream *	    string pointer *	    byte count * Returns: T if success else NIL */long ssl_sout (SSLSTREAM *stream,char *string,unsigned long size){  SecBuffer buf[4];  SecBufferDesc msg;  char *s;  size_t n;  if (!stream->tcpstream) return NIL;				/* until request satisfied */  for (s = stream->ibuf,n = 0; size;) {				/* header */    buf[0].BufferType = SECBUFFER_STREAM_HEADER;    memset (buf[0].pvBuffer = stream->obuf,0,	    buf[0].cbBuffer = stream->sizes.cbHeader);				/* message (up to maximum size) */    buf[1].BufferType = SECBUFFER_DATA;    memcpy (buf[1].pvBuffer = stream->obuf + stream->sizes.cbHeader,string,	    buf[1].cbBuffer = min (size,SSLBUFLEN));				/* trailer */    buf[2].BufferType = SECBUFFER_STREAM_TRAILER;    memset (buf[2].pvBuffer = ((char *) buf[1].pvBuffer) + buf[1].cbBuffer,0,	    buf[2].cbBuffer = stream->sizes.cbTrailer);				/* spare */    buf[3].BufferType = SECBUFFER_EMPTY;    msg.ulVersion = SECBUFFER_VERSION;    msg.cBuffers = 4;		/* number of SecBuffers */    msg.pBuffers = buf;		/* first SecBuffer */    string += buf[1].cbBuffer;    size -= buf[1].cbBuffer;	/* this many bytes processed */				/* encrypt and send message */    if ((((ENCRYPT_MESSAGE_FN) sft->Reserved3)	 (&stream->context,0,&msg,NIL) != SEC_E_OK) ||	!tcp_sout (stream->tcpstream,stream->obuf,		   buf[0].cbBuffer + buf[1].cbBuffer + buf[2].cbBuffer))      return ssl_abort (stream);/* encryption or sending failed */  }  return LONGT;}/* SSL close * Accepts: SSL stream */void ssl_close (SSLSTREAM *stream){  ssl_abort (stream);		/* nuke the stream */  fs_give ((void **) &stream);	/* flush the stream */}/* SSL abort stream * Accepts: SSL stream * Returns: NIL always */static long ssl_abort (SSLSTREAM *stream){  if (stream->tcpstream) {	/* close TCP stream */    sft->DeleteSecurityContext (&stream->context);    sft->FreeCredentialHandle (&stream->cred);    tcp_close (stream->tcpstream);    stream->tcpstream = NIL;  }  if (stream->ibuf) fs_give ((void **) &stream->ibuf);  if (stream->obuf) fs_give ((void **) &stream->obuf);  return NIL;}/* SSL get host name * Accepts: SSL stream * Returns: host name for this stream */char *ssl_host (SSLSTREAM *stream){  return tcp_host (stream->tcpstream);}/* SSL get remote host name * Accepts: SSL stream * Returns: host name for this stream */char *ssl_remotehost (SSLSTREAM *stream){  return tcp_remotehost (stream->tcpstream);}/* SSL return port for this stream * Accepts: SSL stream * Returns: port number for this stream */unsigned long ssl_port (SSLSTREAM *stream){  return tcp_port (stream->tcpstream);}/* SSL get local host name * Accepts: SSL stream * Returns: local host name */char *ssl_localhost (SSLSTREAM *stream){  return tcp_localhost (stream->tcpstream);}#include "ssl_none.c"		/* currently no server support */

⌨️ 快捷键说明

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