Пример #1
0
/* imap_auth_login: Plain LOGIN support */
imap_auth_res_t imap_auth_login (IMAP_DATA* idata, const char* method)
{
	char q_user[SHORT_STRING], q_pass[SHORT_STRING];
	char buf[STRING];
	int rc;

	if (bit_val(idata->capabilities, LOGINDISABLED))
	{
		mutt_message("LOGIN disabled on this server.");
		return IMAP_AUTH_UNAVAIL;
	}

	if (mutt_account_getuser (&idata->conn->account))
		return IMAP_AUTH_FAILURE;
	if (mutt_account_getpass (&idata->conn->account))
		return IMAP_AUTH_FAILURE;

	mutt_message("Logging in...");

	imap_quote_string (q_user, sizeof (q_user), idata->conn->account.user);
	imap_quote_string (q_pass, sizeof (q_pass), idata->conn->account.pass);

	snprintf (buf, sizeof (buf), "LOGIN %s %s", q_user, q_pass);
	rc = imap_exec (idata, buf, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS);

	if (!rc)
	{
		mutt_clear_error(); /* clear "Logging in...".  fixes #3524 */
		return IMAP_AUTH_SUCCESS;
	}

	mutt_error("Login failed.");
	mutt_sleep (2);
	return IMAP_AUTH_FAILURE;
}
Пример #2
0
void imap_munge_mbox_name (char *dest, size_t dlen, const char *src)
{
  char *buf;

  buf = str_dup (src);
  imap_utf7_encode (&buf);

  imap_quote_string (dest, dlen, buf);

  mem_free (&buf);
}
Пример #3
0
/* imap_auth_login: Plain LOGIN support */
imap_auth_res_t imap_auth_login (IMAP_DATA* idata, const char* method)
{
  char q_user[SHORT_STRING], q_pass[SHORT_STRING];
  char buf[STRING];
  int rc;

  if (mutt_bit_isset (idata->capabilities, LOGINDISABLED))
  {
    mutt_message _("LOGIN disabled on this server.");
    return IMAP_AUTH_UNAVAIL;
  }

  if (mutt_account_getuser (&idata->conn->account))
    return IMAP_AUTH_FAILURE;
  if (mutt_account_getpass (&idata->conn->account))
    return IMAP_AUTH_FAILURE;

  mutt_message _("Logging in...");

  imap_quote_string (q_user, sizeof (q_user), idata->conn->account.user);
  imap_quote_string (q_pass, sizeof (q_pass), idata->conn->account.pass);

#ifdef DEBUG
  /* don't print the password unless we're at the ungodly debugging level
   * of 5 or higher */

  if (debuglevel < IMAP_LOG_PASS)
    dprint (2, (debugfile, "Sending LOGIN command for %s...\n",
      idata->conn->account.user));
#endif

  snprintf (buf, sizeof (buf), "LOGIN %s %s", q_user, q_pass);
  rc = imap_exec (idata, buf, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS);
  
  if (!rc)
    return IMAP_AUTH_SUCCESS;

  mutt_error _("Login failed.");
  mutt_sleep (2);
  return IMAP_AUTH_FAILURE;
}
static char *
imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt,
			     va_list ap)
{
	GPtrArray *args;
	const char *p, *start;
	char *out, *outptr, *string;
	int num, len, i, arglen;

	args = g_ptr_array_new ();

	/* Determine the length of the data */
	len = strlen (fmt);
	p = start = fmt;
	while (*p) {
		p = strchr (start, '%');
		if (!p)
			break;

		switch (*++p) {
		case 'd':
			num = va_arg (ap, int);
			g_ptr_array_add (args, GINT_TO_POINTER (num));
			start = p + 1;
			len += 10;
			break;
		case 's':
			string = va_arg (ap, char *);
			g_ptr_array_add (args, string);
			start = p + 1;
			len += strlen (string);
			break;
		case 'S':
		case 'F':
		case 'G':
			string = va_arg (ap, char *);
			/* NB: string is freed during output for %F and %G */
			if (*p == 'F') {
				char *s = camel_imap_store_summary_full_from_path(store->summary, string);
				if (s) {
					string = camel_utf8_utf7(s);
					g_free(s);
				} else {
					string = camel_utf8_utf7(string);
				}
			} else if (*p == 'G') {
				string = camel_utf8_utf7(string);
			}

			arglen = strlen (string);
			g_ptr_array_add (args, string);
			if (imap_is_atom (string)) {
				len += arglen;
			} else {
				if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS)
					len += arglen + 15;
				else
					len += arglen * 2;
			}
			start = p + 1;
			break;
		case '%':
			start = p;
			break;
		default:
			g_warning ("camel-imap-command is not printf. I don't "
				   "know what '%%%c' means.", *p);
			start = *p ? p + 1 : p;
			break;
		}
	}

	/* Now write out the string */
	outptr = out = g_malloc (len + 1);
	p = start = fmt;
	i = 0;
	while (*p) {
		p = strchr (start, '%');
		if (!p) {
			strcpy (outptr, start);
			break;
		} else {
			strncpy (outptr, start, p - start);
			outptr += p - start;
		}

		switch (*++p) {
		case 'd':
			num = GPOINTER_TO_INT (args->pdata[i++]);
			outptr += sprintf (outptr, "%d", num);
			break;

		case 's':
			string = args->pdata[i++];
			outptr += sprintf (outptr, "%s", string);
			break;
		case 'S':
		case 'F':
		case 'G':
			string = args->pdata[i++];
			if (imap_is_atom (string)) {
				outptr += sprintf (outptr, "%s", string);
			} else {
				len = strlen (string);
				if (len && store->capabilities & IMAP_CAPABILITY_LITERALPLUS) {
					outptr += sprintf (outptr, "{%d+}\r\n%s", len, string);
				} else {
					char *quoted = imap_quote_string (string);

					outptr += sprintf (outptr, "%s", quoted);
					g_free (quoted);
				}
			}

			if (*p == 'F' || *p == 'G')
				g_free (string);
			break;
		default:
			*outptr++ = '%';
			*outptr++ = *p;
		}

		start = *p ? p + 1 : p;
	}

	g_ptr_array_free (args, TRUE);

	return out;
}
Пример #5
0
/* imap_browse: IMAP hook into the folder browser, fills out browser_state,
 *   given a current folder to browse */
int imap_browse (char* path, struct browser_state* state)
{
  IMAP_DATA* idata;
  char buf[LONG_STRING];
  char buf2[LONG_STRING];
  char nsbuf[LONG_STRING];
  char mbox[LONG_STRING];
  char list_cmd[5];
  IMAP_NAMESPACE_INFO nsi[16];
  int home_namespace = 0;
  int n;
  int i;
  int nsup;
  char ctmp;
  int nns;
  char *cur_folder;
  short showparents = 0;
  int noselect;
  int noinferiors;
  IMAP_MBOX mx;

  if (imap_parse_path (path, &mx))
  {
    mutt_error (_("%s is an invalid IMAP path"), path);
    return -1;
  }

  strfcpy (list_cmd, option (OPTIMAPLSUB) ? "LSUB" : "LIST", sizeof (list_cmd));

  if (!(idata = imap_conn_find (&(mx.account), 0)))
    goto fail;

  if (!mx.mbox)
  {
    home_namespace = 1;
    mbox[0] = '\0';		/* Do not replace "" with "INBOX" here */
    mx.mbox = safe_strdup(ImapHomeNamespace);
    nns = 0;
    if (mutt_bit_isset(idata->capabilities,NAMESPACE))
    {
      mutt_message _("Getting namespaces...");
      if (browse_get_namespace (idata, nsbuf, sizeof (nsbuf), 
				nsi, sizeof (nsi),  &nns) != 0)
	goto fail;
      if (browse_verify_namespace (idata, nsi, nns) != 0)
	goto fail;
    }
  }

  mutt_message _("Getting folder list...");

  /* skip check for parents when at the root */
  if (mx.mbox && mx.mbox[0] != '\0')
  {
    imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
    imap_munge_mbox_name (buf, sizeof (buf), mbox);
    imap_unquote_string(buf); /* As kludgy as it gets */
    mbox[sizeof (mbox) - 1] = '\0';
    strncpy (mbox, buf, sizeof (mbox) - 1);
    n = mutt_strlen (mbox);

    dprint (3, (debugfile, "imap_browse: mbox: %s\n", mbox));

    /* if our target exists and has inferiors, enter it if we
     * aren't already going to */
    if (mbox[n-1] != idata->delim)
    {
      snprintf (buf, sizeof (buf), "%s \"\" \"%s\"", list_cmd, mbox);
      imap_cmd_start (idata, buf);
      do 
      {
        if (imap_parse_list_response (idata, &cur_folder, &noselect,
            &noinferiors, &idata->delim) != 0)
	  goto fail;

        if (cur_folder)
        {
          imap_unmunge_mbox_name (cur_folder);

          if (!noinferiors && cur_folder[0] &&
            (n = strlen (mbox)) < LONG_STRING-1)
          {
            mbox[n++] = idata->delim;
            mbox[n] = '\0';
          }
        }
      }
      while (ascii_strncmp (idata->cmd.buf, idata->cmd.seq, SEQLEN));
    }

    /* if we're descending a folder, mark it as current in browser_state */
    if (mbox[n-1] == idata->delim)
    {
      /* don't show parents in the home namespace */
      if (!home_namespace)
	showparents = 1;
      imap_qualify_path (buf, sizeof (buf), &mx, mbox);
      state->folder = safe_strdup (buf);
      n--;
    }

    /* Find superiors to list
     * Note: UW-IMAP servers return folder + delimiter when asked to list
     *  folder + delimiter. Cyrus servers don't. So we ask for folder,
     *  and tack on delimiter ourselves.
     * Further note: UW-IMAP servers return nothing when asked for 
     *  NAMESPACES without delimiters at the end. Argh! */
    for (n--; n >= 0 && mbox[n] != idata->delim ; n--);
    if (n > 0)			/* "aaaa/bbbb/" -> "aaaa" */
    {
      /* forget the check, it is too delicate (see above). Have we ever
       * had the parent not exist? */
      ctmp = mbox[n];
      mbox[n] = '\0';

      if (showparents)
      {
	dprint (3, (debugfile, "imap_init_browse: adding parent %s\n", mbox));
	imap_add_folder (idata->delim, mbox, 1, 0, state, 1);
      }

      /* if our target isn't a folder, we are in our superior */
      if (!state->folder)
      {
        /* store folder with delimiter */
        mbox[n++] = ctmp;
        ctmp = mbox[n];
        mbox[n] = '\0';
        imap_qualify_path (buf, sizeof (buf), &mx, mbox);
        state->folder = safe_strdup (buf);
      }
      mbox[n] = ctmp;
    } 
    /* "/bbbb/" -> add  "/", "aaaa/" -> add "" */
    else
    {
      char relpath[2];
      /* folder may be "/" */
      snprintf (relpath, sizeof (relpath), "%c" , n < 0 ? '\0' : idata->delim);
      if (showparents)
        imap_add_folder (idata->delim, relpath, 1, 0, state, 1); 
      if (!state->folder)
      {
        imap_qualify_path (buf, sizeof (buf), &mx, relpath);
        state->folder = safe_strdup (buf);
      }
    }
  }

  /* no namespace, no folder: set folder to host only */
  if (!state->folder)
  {
    imap_qualify_path (buf, sizeof (buf), &mx, NULL);
    state->folder = safe_strdup (buf);
  }

  if (home_namespace && mbox[0] != '\0')
  {
    /* Listing the home namespace, so INBOX should be included. Home 
     * namespace is not "", so we have to list it explicitly. We ask the 
     * server to see if it has descendants. */
    dprint (2, (debugfile, "imap_init_browse: adding INBOX\n"));
    if (browse_add_list_result (idata, "LIST \"\" \"INBOX\"", state, 0))
      goto fail;

    if (!state->entrylen)
    {
      mutt_error _("No such folder");
      goto fail;
    }
  }

  nsup = state->entrylen;

  dprint (3, (debugfile, "imap_browse: Quoting mailbox scan: %s -> ", mbox));
  snprintf (buf, sizeof (buf), "%s%%", mbox);
  imap_quote_string (buf2, sizeof (buf2), buf);
  dprint (3, (debugfile, "%s\n", buf2));
  snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, buf2);
  if (browse_add_list_result (idata, buf, state, 0))
    goto fail;

  mutt_clear_error ();

  qsort(&(state->entry[nsup]),state->entrylen-nsup,sizeof(state->entry[0]),
	(int (*)(const void*,const void*)) compare_names);
  if (home_namespace)
  {				/* List additional namespaces */
    for (i = 0; i < nns; i++)
      if (nsi[i].listable && !nsi[i].home_namespace) {
	imap_add_folder(nsi[i].delim, nsi[i].prefix, nsi[i].noselect,
			nsi[i].noinferiors, state, 0);
	dprint (3, (debugfile, "imap_init_browse: adding namespace: %s\n",
		    nsi[i].prefix));
      }
  }

  FREE (&mx.mbox);
  return 0;

 fail:
  FREE (&mx.mbox);
  return -1;
}