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

📄 mutt_sasl.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2000-5 Brendan Cully <brendan@kublai.com> *  *     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 Street, Fifth Floor, Boston, MA  02110-1301, USA. */ /* common SASL helper routines */#if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "account.h"#include "mutt_sasl.h"#include "mutt_socket.h"#include <errno.h>#include <netdb.h>#include <sasl/sasl.h>#include <sys/socket.h>#include <netinet/in.h>static int getnameinfo_err(int ret){  int err;  dprint (1, (debugfile, "getnameinfo: "));  switch(ret)  {     case EAI_AGAIN:       dprint (1, (debugfile, "The name could not be resolved at this time.  Future attempts may succeed.\n"));       err=SASL_TRYAGAIN;       break;     case EAI_BADFLAGS:       dprint (1, (debugfile, "The flags had an invalid value.\n"));       err=SASL_BADPARAM;       break;     case EAI_FAIL:       dprint (1, (debugfile, "A non-recoverable error occurred.\n"));       err=SASL_FAIL;       break;     case EAI_FAMILY:       dprint (1, (debugfile, "The address family was not recognized or the address length was invalid for the specified family.\n"));       err=SASL_BADPROT;       break;     case EAI_MEMORY:       dprint (1, (debugfile, "There was a memory allocation failure.\n"));       err=SASL_NOMEM;       break;     case EAI_NONAME:       dprint (1, (debugfile, "The name does not resolve for the supplied parameters.  NI_NAMEREQD is set and the host's name cannot be located, or both nodename and servname were null.\n"));       err=SASL_FAIL; /* no real equivalent */       break;     case EAI_SYSTEM:       dprint (1, (debugfile, "A system error occurred.  The error code can be found in errno(%d,%s)).\n",errno,strerror(errno)));       err=SASL_FAIL; /* no real equivalent */       break;     default:       dprint (1, (debugfile, "Unknown error %d\n",ret));       err=SASL_FAIL; /* no real equivalent */       break;  }  return err;}/* arbitrary. SASL will probably use a smaller buffer anyway. OTOH it's * been a while since I've had access to an SASL server which negotiated * a protection buffer. */ #define M_SASL_MAXBUF 65536#define IP_PORT_BUFLEN 1024static sasl_callback_t mutt_sasl_callbacks[5];static int mutt_sasl_start (void);/* callbacks */static int mutt_sasl_cb_log (void* context, int priority, const char* message);static int mutt_sasl_cb_authname (void* context, int id, const char** result,  unsigned int* len);static int mutt_sasl_cb_pass (sasl_conn_t* conn, void* context, int id,  sasl_secret_t** psecret);/* socket wrappers for a SASL security layer */static int mutt_sasl_conn_open (CONNECTION* conn);static int mutt_sasl_conn_close (CONNECTION* conn);static int mutt_sasl_conn_read (CONNECTION* conn, char* buf, size_t len);static int mutt_sasl_conn_write (CONNECTION* conn, const char* buf,  size_t count);/* utility function, stolen from sasl2 sample code */static int iptostring(const struct sockaddr *addr, socklen_t addrlen,                     char *out, unsigned outlen) {    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];    int ret;        if(!addr || !out) return SASL_BADPARAM;    ret=getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),                   NI_NUMERICHOST |#ifdef NI_WITHSCOPEID		   NI_WITHSCOPEID |#endif		   NI_NUMERICSERV);    if(ret)      return getnameinfo_err(ret);    if(outlen < strlen(hbuf) + strlen(pbuf) + 2)        return SASL_BUFOVER;    snprintf(out, outlen, "%s;%s", hbuf, pbuf);    return SASL_OK;}/* mutt_sasl_start: called before doing a SASL exchange - initialises library *   (if necessary). */int mutt_sasl_start (void){  static unsigned char sasl_init = 0;  static sasl_callback_t callbacks[2];  int rc;  if (sasl_init)    return SASL_OK;  /* set up default logging callback */  callbacks[0].id = SASL_CB_LOG;  callbacks[0].proc = mutt_sasl_cb_log;  callbacks[0].context = NULL;  callbacks[1].id = SASL_CB_LIST_END;  callbacks[1].proc = NULL;  callbacks[1].context = NULL;  rc = sasl_client_init (callbacks);  if (rc != SASL_OK)  {    dprint (1, (debugfile, "mutt_sasl_start: libsasl initialisation failed.\n"));    return SASL_FAIL;  }  sasl_init = 1;  return SASL_OK;}/* mutt_sasl_client_new: wrapper for sasl_client_new which also sets various * security properties. If this turns out to be fine for POP too we can * probably stop exporting mutt_sasl_get_callbacks(). */int mutt_sasl_client_new (CONNECTION* conn, sasl_conn_t** saslconn){  sasl_security_properties_t secprops;  struct sockaddr_storage local, remote;  socklen_t size;  char iplocalport[IP_PORT_BUFLEN], ipremoteport[IP_PORT_BUFLEN];  const char* service;  int rc;  if (mutt_sasl_start () != SASL_OK)    return -1;  switch (conn->account.type)  {    case M_ACCT_TYPE_IMAP:      service = "imap";      break;    case M_ACCT_TYPE_POP:      service = "pop";      break;    default:      dprint (1, (debugfile, "mutt_sasl_client_new: account type unset\n"));      return -1;  }  size = sizeof (local);  if (getsockname (conn->fd, (struct sockaddr *)&local, &size)){    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for local failed\n"));    return -1;  }  else   if (iptostring((struct sockaddr *)&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK){    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for local failed\n"));    return -1;  }    size = sizeof (remote);  if (getpeername (conn->fd, (struct sockaddr *)&remote, &size)){    dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for remote failed\n"));    return -1;  }  else   if (iptostring((struct sockaddr *)&remote, size, ipremoteport, IP_PORT_BUFLEN) != SASL_OK){    dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for remote failed\n"));    return -1;  }  dprint(1,(debugfile, "local ip: %s, remote ip:%s\n", iplocalport, ipremoteport));    rc = sasl_client_new (service, conn->account.host, iplocalport, ipremoteport,    mutt_sasl_get_callbacks (&conn->account), 0, saslconn);  if (rc != SASL_OK)  {    dprint (1, (debugfile,      "mutt_sasl_client_new: Error allocating SASL connection\n"));    return -1;  }  /* set security properties. We use NOPLAINTEXT globally, since we can   * just fall back to LOGIN in the IMAP case anyway. If that doesn't   * work for POP, we can make it a flag or move this code into   * imap/auth_sasl.c */  memset (&secprops, 0, sizeof (secprops));  /* Work around a casting bug in the SASL krb4 module */  secprops.max_ssf = 0x7fff;  secprops.maxbufsize = M_SASL_MAXBUF;  secprops.security_flags |= SASL_SEC_NOPLAINTEXT;  if (sasl_setprop (*saslconn, SASL_SEC_PROPS, &secprops) != SASL_OK)  {    dprint (1, (debugfile,      "mutt_sasl_client_new: Error setting security properties\n"));    return -1;  }  if (conn->ssf)  {    /* I'm not sure this actually has an effect, at least with SASLv2 */    dprint (2, (debugfile, "External SSF: %d\n", conn->ssf));    if (sasl_setprop (*saslconn, SASL_SSF_EXTERNAL, &(conn->ssf)) != SASL_OK)    {      dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));      return -1;    }    dprint (2, (debugfile, "External authentication name: %s\n", conn->account.user));    if (sasl_setprop (*saslconn, SASL_AUTH_EXTERNAL, conn->account.user) != SASL_OK)     {      dprint (1, (debugfile, "mutt_sasl_client_new: Error setting external properties\n"));      return -1;    }  }  return 0;}sasl_callback_t* mutt_sasl_get_callbacks (ACCOUNT* account){  sasl_callback_t* callback;  callback = mutt_sasl_callbacks;  callback->id = SASL_CB_USER;  callback->proc = mutt_sasl_cb_authname;  callback->context = account;  callback++;  callback->id = SASL_CB_AUTHNAME;  callback->proc = mutt_sasl_cb_authname;  callback->context = account;  callback++;  callback->id = SASL_CB_PASS;  callback->proc = mutt_sasl_cb_pass;  callback->context = account;  callback++;  callback->id = SASL_CB_GETREALM;  callback->proc = NULL;  callback->context = NULL;  callback++;  callback->id = SASL_CB_LIST_END;  callback->proc = NULL;  callback->context = NULL;  return mutt_sasl_callbacks;}int mutt_sasl_interact (sasl_interact_t* interaction){  char prompt[SHORT_STRING];  char resp[SHORT_STRING];  while (interaction->id != SASL_CB_LIST_END)

⌨️ 快捷键说明

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