pop3protocol.h 3.49 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/*
 * SPDX-FileCopyrightText: 1999, 2000 Alex Zepeda <zipzippy@sonic.net>
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 *
 */

#pragma once

11
#include "result.h"
12

13
14
15
#include <KJob>

#include <QObject>
16
17
18

#include <sys/types.h>

19
class KSslErrorUiData;
20
class QSslSocket;
21
22
#define MAX_PACKET_LEN 4096

23
24
25
class Settings;

class POP3Protocol : public QObject
26
{
27
    Q_OBJECT
28
public:
29
    POP3Protocol(const Settings &settings, const QString &password);
30
31
    ~POP3Protocol() override;

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    // clang-format off
    enum {
        ERR_LOGIN_FAILED_TRY_FALLBACKS = KJob::UserDefinedError + 1,
        ERR_SASL_FAILURE,
        ERR_SSL_FAILURE,
        ERR_CANNOT_LOGIN,
        ERR_USER_CANCELED,
        ERR_INTERNAL,
        ERR_PROTOCOL,
        ERR_DISCONNECTED,
    };
    // clang-format on

    static bool initSASL();

    /**
     * Attempt to initiate a POP3 connection via a TCP socket.
     */
    Q_REQUIRED_RESULT Result openConnection();

    /**
     *  Attempt to properly shut down the POP3 connection by sending
     *  "QUIT\r\n" before closing the socket.
     */
    void closeConnection();
57

58
59
60
61
62
    /**
     * Entry point for all features
     * TODO: this could be split up!
     */
    Q_REQUIRED_RESULT Result get(const QString &command);
63

64
65
66
67
68
    /**
     * Sets whether to continue or abort after a SSL error
     */
    void setContinueAfterSslError(bool b);

69
Q_SIGNALS:
70
    void sslError(const KSslErrorUiData &);
71
72
73
74
    void data(const QByteArray &data);
    void messageComplete();

private:
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
    ssize_t myRead(void *data, ssize_t len);
    ssize_t myReadLine(char *data, ssize_t len);

    /**
     * This returns the size of a message as a long integer.
     * This is useful as an internal member, because the "other"
     * getSize command will emit a signal, which would be harder
     * to trap when doing something like listing a directory.
     */
    size_t realGetSize(unsigned int msg_num);

    /**
     *  Send a command to the server. Using this function, getResponse
     *  has to be called separately.
     */
    bool sendCommand(const QByteArray &cmd);

    enum Resp {
        Err,
        Ok,
        Cont,
        Invalid,
    };
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
    /**
     *  Send a command to the server, and wait for the  one-line-status
     *  reply via getResponse.  Similar rules apply.  If no buffer is
     *  specified, no data is passed back.
     */
    Resp command(const QByteArray &buf, char *r_buf = nullptr, unsigned int r_len = 0);

    /**
     *  All POP3 commands will generate a response.  Each response will
     *  either be prefixed with a "+OK " or a "-ERR ".  The getResponse
     *  function will wait until there's data to be read, and then read in
     *  the first line (the response), and copy the response sans +OK/-ERR
     *  into a buffer (up to len bytes) if one was passed to it.
     */
    Resp getResponse(char *buf, unsigned int len);

    /**
     * Authenticate via APOP
     */
118
    Q_REQUIRED_RESULT Result loginAPOP(const char *challenge);
119

120
    bool saslInteract(void *in);
121
122
123
    /**
     * Authenticate via SASL
     */
124
    Q_REQUIRED_RESULT Result loginSASL();
125
126
127
    /**
     * Authenticate via traditional USER/PASS
     */
128
    Q_REQUIRED_RESULT Result loginPASS();
129

130
131
    const Settings &mSettings;
    QSslSocket *mSocket = nullptr;
132
133
    unsigned short int m_iPort;
    QString m_sServer, m_sPass, m_sUser;
134
135
    bool m_try_apop, m_try_sasl, supports_apop;
    bool mConnected = false;
136
    bool mContinueAfterSslError = false;
137
138
139
140
    QString m_sError;
    char readBuffer[MAX_PACKET_LEN];
    ssize_t readBufferLen;
};