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

📄 mutt_sasl.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
  {    dprint (2, (debugfile, "mutt_sasl_interact: filling in SASL interaction %ld.\n", interaction->id));    snprintf (prompt, sizeof (prompt), "%s: ", interaction->prompt);    resp[0] = '\0';    if (mutt_get_field (prompt, resp, sizeof (resp), 0))      return SASL_FAIL;    interaction->len = mutt_strlen (resp)+1;    interaction->result = safe_malloc (interaction->len);    memcpy ((char *)interaction->result, resp, interaction->len);    interaction++;  }  return SASL_OK;}/* SASL can stack a protection layer on top of an existing connection. * To handle this, we store a saslconn_t in conn->sockdata, and write * wrappers which en/decode the read/write stream, then replace sockdata * with an embedded copy of the old sockdata and call the underlying * functions (which we've also preserved). I thought about trying to make * a general stackable connection system, but it seemed like overkill - * something is wrong if we have 15 filters on top of a socket. Anyway, * anything else which wishes to stack can use the same method. The only * disadvantage is we have to write wrappers for all the socket methods, * even if we only stack over read and write. Thinking about it, the * abstraction problem is that there is more in CONNECTION than there * needs to be. Ideally it would have only (void*)data and methods. *//* mutt_sasl_setup_conn: replace connection methods, sockdata with  *   SASL wrappers, for protection layers. Also get ssf, as a fastpath *   for the read/write methods. */void mutt_sasl_setup_conn (CONNECTION* conn, sasl_conn_t* saslconn){  SASL_DATA* sasldata = (SASL_DATA*) safe_malloc (sizeof (SASL_DATA));  sasldata->saslconn = saslconn;  /* get ssf so we know whether we have to (en|de)code read/write */  sasl_getprop (saslconn, SASL_SSF, (const void**) &sasldata->ssf);  dprint (3, (debugfile, "SASL protection strength: %u\n", *sasldata->ssf));  /* Add SASL SSF to transport SSF */  conn->ssf += *sasldata->ssf;  sasl_getprop (saslconn, SASL_MAXOUTBUF, (const void**) &sasldata->pbufsize);  dprint (3, (debugfile, "SASL protection buffer size: %u\n", *sasldata->pbufsize));  /* clear input buffer */  sasldata->buf = NULL;  sasldata->bpos = 0;  sasldata->blen = 0;  /* preserve old functions */  sasldata->sockdata = conn->sockdata;  sasldata->msasl_open = conn->conn_open;  sasldata->msasl_close = conn->conn_close;  sasldata->msasl_read = conn->conn_read;  sasldata->msasl_write = conn->conn_write;  /* and set up new functions */  conn->sockdata = sasldata;  conn->conn_open = mutt_sasl_conn_open;  conn->conn_close = mutt_sasl_conn_close;  conn->conn_read = mutt_sasl_conn_read;  conn->conn_write = mutt_sasl_conn_write;}/* mutt_sasl_cb_log: callback to log SASL messages */static int mutt_sasl_cb_log (void* context, int priority, const char* message){  dprint (priority, (debugfile, "SASL: %s\n", message));  return SASL_OK;}void mutt_sasl_done (void){  sasl_done ();}/* mutt_sasl_cb_authname: callback to retrieve authname or user from ACCOUNT */static int mutt_sasl_cb_authname (void* context, int id, const char** result,  unsigned* len){  ACCOUNT* account = (ACCOUNT*) context;  *result = NULL;  if (len)    *len = 0;  if (!account)    return SASL_BADPARAM;  dprint (2, (debugfile, "mutt_sasl_cb_authname: getting %s for %s:%u\n",	      id == SASL_CB_AUTHNAME ? "authname" : "user",	      account->host, account->port));  if (id == SASL_CB_AUTHNAME)  {    if (mutt_account_getlogin (account))      return SASL_FAIL;    *result = account->login;  }  else  {    if (mutt_account_getuser (account))      return SASL_FAIL;    *result = account->user;  }    if (len)    *len = strlen (*result);  return SASL_OK;}static int mutt_sasl_cb_pass (sasl_conn_t* conn, void* context, int id,  sasl_secret_t** psecret){  ACCOUNT* account = (ACCOUNT*) context;  int len;  if (!account || !psecret)    return SASL_BADPARAM;  dprint (2, (debugfile,    "mutt_sasl_cb_pass: getting password for %s@%s:%u\n", account->login,    account->host, account->port));  if (mutt_account_getpass (account))    return SASL_FAIL;  len = strlen (account->pass);  *psecret = (sasl_secret_t*) safe_malloc (sizeof (sasl_secret_t) + len);  (*psecret)->len = len;  strcpy ((char*)(*psecret)->data, account->pass);	/* __STRCPY_CHECKED__ */  return SASL_OK;}/* mutt_sasl_conn_open: empty wrapper for underlying open function. We *   don't know in advance that a connection will use SASL, so we *   replace conn's methods with sasl methods when authentication *   is successful, using mutt_sasl_setup_conn */static int mutt_sasl_conn_open (CONNECTION* conn){  SASL_DATA* sasldata;  int rc;  sasldata = (SASL_DATA*) conn->sockdata;  conn->sockdata = sasldata->sockdata;  rc = (sasldata->msasl_open) (conn);  conn->sockdata = sasldata;  return rc;}/* mutt_sasl_conn_close: calls underlying close function and disposes of *   the sasl_conn_t object, then restores connection to pre-sasl state */static int mutt_sasl_conn_close (CONNECTION* conn){  SASL_DATA* sasldata;  int rc;  sasldata = (SASL_DATA*) conn->sockdata;  /* restore connection's underlying methods */  conn->sockdata = sasldata->sockdata;  conn->conn_open = sasldata->msasl_open;  conn->conn_close = sasldata->msasl_close;  conn->conn_read = sasldata->msasl_read;  conn->conn_write = sasldata->msasl_write;  /* release sasl resources */  sasl_dispose (&sasldata->saslconn);  FREE (&sasldata);  /* call underlying close */  rc = (conn->conn_close) (conn);  return rc;}static int mutt_sasl_conn_read (CONNECTION* conn, char* buf, size_t len){  SASL_DATA* sasldata;  int rc;  unsigned int olen;  sasldata = (SASL_DATA*) conn->sockdata;  /* if we still have data in our read buffer, copy it into buf */  if (sasldata->blen > sasldata->bpos)  {    olen = (sasldata->blen - sasldata->bpos > len) ? len :      sasldata->blen - sasldata->bpos;    memcpy (buf, sasldata->buf+sasldata->bpos, olen);    sasldata->bpos += olen;    return olen;  }    conn->sockdata = sasldata->sockdata;  sasldata->bpos = 0;  sasldata->blen = 0;  /* and decode the result, if necessary */  if (*sasldata->ssf)  {    do    {      /* call the underlying read function to fill the buffer */      rc = (sasldata->msasl_read) (conn, buf, len);      if (rc <= 0)	goto out;      rc = sasl_decode (sasldata->saslconn, buf, rc, &sasldata->buf,        &sasldata->blen);      if (rc != SASL_OK)      {	dprint (1, (debugfile, "SASL decode failed: %s\n",          sasl_errstring (rc, NULL, NULL)));	goto out;      }    }    while (!sasldata->blen);    olen = (sasldata->blen - sasldata->bpos > len) ? len :      sasldata->blen - sasldata->bpos;    memcpy (buf, sasldata->buf, olen);    sasldata->bpos += olen;    rc = olen;  }  else    rc = (sasldata->msasl_read) (conn, buf, len);  out:    conn->sockdata = sasldata;    return rc;}static int mutt_sasl_conn_write (CONNECTION* conn, const char* buf,  size_t len){  SASL_DATA* sasldata;  int rc;  const char *pbuf;  unsigned int olen, plen;  sasldata = (SASL_DATA*) conn->sockdata;  conn->sockdata = sasldata->sockdata;  /* encode data, if necessary */  if (*sasldata->ssf)  {    /* handle data larger than MAXOUTBUF */    do    {      olen = (len > *sasldata->pbufsize) ? *sasldata->pbufsize : len;      rc = sasl_encode (sasldata->saslconn, buf, olen, &pbuf, &plen);      if (rc != SASL_OK)      {	dprint (1, (debugfile, "SASL encoding failed: %s\n",          sasl_errstring (rc, NULL, NULL)));	goto fail;      }      rc = (sasldata->msasl_write) (conn, pbuf, plen);      if (rc != plen)	goto fail;      len -= olen;      buf += olen;    }    while (len > *sasldata->pbufsize);  }  else  /* just write using the underlying socket function */    rc = (sasldata->msasl_write) (conn, buf, len);    conn->sockdata = sasldata;  return rc; fail:  conn->sockdata = sasldata;  return -1;}

⌨️ 快捷键说明

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