Unverified Commit befaa7b1 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

imap: support PREAUTH

It is a defined possible greeting at server startup that means the
connection is already authenticated. See
https://tools.ietf.org/html/rfc3501#section-7.1.4

Test 846 added to verify.

Fixes #1818
Closes #1820
parent 00da16ca
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -254,6 +254,8 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
      *resp = 'N';
    else if(len >= 3 && !memcmp(line, "BAD", 3))
      *resp = 'B';
    else if(len >= 7 && !memcmp(line, "PREAUTH", 7))
      *resp = 'P';
    else {
      failf(conn->data, "Bad tagged response");
      *resp = -1;
@@ -563,9 +565,10 @@ static CURLcode imap_perform_authentication(struct connectdata *conn)
  struct imap_conn *imapc = &conn->proto.imapc;
  saslprogress progress;

  /* Check we have enough data to authenticate with and end the
     connect phase if we don't */
  if(!Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
  /* Check if already authenticated OR if there is enough data to authenticate
     with and end the connect phase if we don't */
  if(imapc->preauth ||
     !Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
    state(conn, IMAP_STOP);
    return result;
  }
@@ -789,19 +792,21 @@ static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
                                            int imapcode,
                                            imapstate instate)
{
  CURLcode result = CURLE_OK;
  struct Curl_easy *data = conn->data;

  (void)instate; /* no use for this yet */

  if(imapcode != 'O') {
  if(imapcode == 'P') {
    /* PREAUTH */
    struct imap_conn *imapc = &conn->proto.imapc;
    imapc->preauth = TRUE;
    infof(data, "PREAUTH connection, already authenticated!\n");
  }
  else if(imapcode != 'O') {
    failf(data, "Got unexpected imap-server response");
    result = CURLE_WEIRD_SERVER_REPLY;
    return CURLE_WEIRD_SERVER_REPLY;
  }
  else
    result = imap_perform_capability(conn);

  return result;
  return imap_perform_capability(conn);
}

/* For CAPABILITY responses */
+2 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 2009 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -71,6 +71,7 @@ struct imap_conn {
  struct pingpong pp;
  imapstate state;            /* Always use imap.c:state() to change state! */
  bool ssldone;               /* Is connect() over SSL done? */
  bool preauth;               /* Is this connection PREAUTH? */
  struct SASL sasl;           /* SASL-related parameters */
  unsigned int preftype;      /* Preferred authentication type */
  int cmdid;                  /* Last used command ID */
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ test809 test810 test811 test812 test813 test814 test815 test816 test817 \
test818 test819 test820 test821 test822 test823 test824 test825 test826 \
test827 test828 test829 test830 test831 test832 test833 test834 test835 \
test836 test837 test838 test839 test840 test841 test842 test843 test844 \
test845 \
test845 test846 \
\
test850 test851 test852 test853 test854 test855 test856 test857 test858 \
test859 test860 test861 test862 test863 test864 test865 test866 test867 \

tests/data/test846

0 → 100644
+50 −0
Original line number Diff line number Diff line
<testcase>
<info>
<keywords>
IMAP
</keywords>
</info>

#
# Server-side
<reply>
<servercmd>
REPLY welcome * PREAUTH ready to serve already!
REPLY CAPABILITY * CAPABILITY IMAP4REV1 I18NLEVEL=1 LITERAL+ IDLE UIDPLUS NAMESPACE CHILDREN MAILBOX-REFERRALS BINARY UNSELECT ESEARCH WITHIN SCAN SORT THREAD=REFERENCES THREAD=ORDEREDSUBJECT MULTIAPPEND SASL-IR LOGIN-REFERRALS STARTTLS LOGINDISABLED\r\nA001 OK CAPABILITY completed
</servercmd>
<data>
From: me@somewhere
To: fake@nowhere

body

--
  yours sincerely
</data>
</reply>

#
# Client-side
<client>
<server>
imap
</server>
 <name>
IMAP PREAUTH response
 </name>
 <command>
'imap://%HOSTIP:%IMAPPORT/846/;UID=1' -u notused:still-provided
</command>
</client>

#
# Verify data after the test has been "shot"
<verify>
<protocol>
A001 CAPABILITY
A002 SELECT 846
A003 FETCH 1 BODY[]
A004 LOGOUT
</protocol>
</verify>
</testcase>