~ubuntu-branches/ubuntu/saucy/geary/saucy-updates

« back to all changes in this revision

Viewing changes to src/engine/smtp/smtp-client-connection.vala

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2013-03-14 13:48:23 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20130314134823-gyk5av1g508zyj8a
Tags: 0.3.0~pr1-0ubuntu1
New upstream version (FFE lp: #1154316), supports multiple account as
well as full conversation views with inline replies

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
        throws Error {
62
62
        check_connected();
63
63
        
64
 
        switch (endpoint.attempt_starttls(capabilities.has_capability(Capabilities.STARTTLS))) {
65
 
            case Endpoint.AttemptStarttls.YES:
66
 
                Response response = yield transaction_async(new Request(Command.STARTTLS));
67
 
                if (!response.code.is_starttls_ready()) {
68
 
                    throw new SmtpError.STARTTLS_FAILED("STARTTLS failed: %s", response.to_string());
69
 
                }
70
 
                
71
 
                // TLS started, lets wrap the connection and shake hands.
72
 
                TlsClientConnection tls_cx = TlsClientConnection.new(cx, socket_cx.get_remote_address());
73
 
                cx = tls_cx;
74
 
                tls_cx.set_validation_flags(TlsCertificateFlags.UNKNOWN_CA);
75
 
                set_data_streams(tls_cx);
76
 
                yield tls_cx.handshake_async(Priority.DEFAULT, cancellable);
77
 
                
78
 
                // Now that we are on an encrypted line we need to say hello again in order to get the
79
 
                // updated capabilities.
80
 
                yield say_hello_async(cancellable);
81
 
            break;
82
 
            
83
 
            case Endpoint.AttemptStarttls.NO:
84
 
                // do nothing
85
 
            break;
86
 
            
87
 
            case Endpoint.AttemptStarttls.HALT:
88
 
            default:
89
 
                throw new SmtpError.NOT_SUPPORTED("STARTTLS not available for %s", endpoint.to_string());
90
 
        }
91
 
        
92
64
        Response response = yield transaction_async(authenticator.initiate(), cancellable);
93
65
        
94
66
        Logging.debug(Logging.Flag.NETWORK, "[%s] Initiated SMTP %s authentication", to_string(),
107
79
            if (data == null || data.length == 0)
108
80
                data = DataFormat.CANCEL_AUTHENTICATION.data;
109
81
            
110
 
            Logging.debug(Logging.Flag.NETWORK, "[%s] SMTP AUTH Challenge: %s <%ldb>", to_string(),
111
 
                Geary.String.uint8_to_string(data), data.length);
 
82
            Logging.debug(Logging.Flag.NETWORK, "[%s] SMTP AUTH Challenge recvd", to_string());
112
83
            
113
84
            yield Stream.write_all_async(douts, data, 0, -1, Priority.DEFAULT, cancellable);
114
85
            douts.put_string(DataFormat.LINE_TERMINATOR);
181
152
        
182
153
        return response;
183
154
    }
184
 
 
185
 
    public async Response say_hello_async(Cancellable? cancellable = null) throws Error {
186
 
        check_connected();
187
 
        
 
155
    
 
156
    /**
 
157
     * Sends the appropriate HELO/EHLO command and returns the response of the one that worked.
 
158
     * Also saves the server's capabilities in the capabilties property (overwriting any that may
 
159
     * already be present).
 
160
     */
 
161
    public async Response say_hello_async(Cancellable? cancellable) throws Error {
188
162
        // get local address as FQDN to greet server ... note that this merely returns the DHCP address
189
163
        // for machines behind a NAT
190
164
        InetAddress local_addr = ((InetSocketAddress) socket_cx.get_local_address()).get_address();
205
179
        EhloRequest ehlo = !String.is_empty(fqdn) ? new EhloRequest(fqdn) : new EhloRequest.for_local_address(local_addr);
206
180
        Response response = yield transaction_async(ehlo, cancellable);
207
181
        if (response.code.is_success_completed()) {
208
 
            // save list of caps returned in EHLO command, skipping first line because it's the 
209
 
            // EHLO response
 
182
            // save list of caps returned in EHLO command
210
183
            capabilities = new Geary.Smtp.Capabilities();
211
184
            capabilities.add_ehlo_response(response);
212
185
        } else {
221
194
        
222
195
        return response;
223
196
    }
224
 
 
 
197
    
 
198
    /**
 
199
     * Sends the appropriate hello command to the server (EHLO / HELO) and establishes whatever
 
200
     * additional connection features are available (STARTTLS, compression).  For general-purpose
 
201
     * use, this is the preferred method for establishing a session with a server, as it will do
 
202
     * whatever is necessary to ensure quality-of-service and security.
 
203
     *
 
204
     * Note that this does *not* connect to the server; connect_async() should be used before
 
205
     * calling this method.
 
206
     *
 
207
     * Returns the Response of the final hello command (there may be more than one).
 
208
     */
 
209
    public async Response establish_connection_async(Cancellable? cancellable = null) throws Error {
 
210
        check_connected();
 
211
        
 
212
        // issue first HELO/EHLO, which will generate a set of capabiltiies
 
213
        Smtp.Response response = yield say_hello_async(cancellable);
 
214
        
 
215
        // STARTTLS, if required
 
216
        switch (endpoint.attempt_starttls(capabilities.has_capability(Capabilities.STARTTLS))) {
 
217
            case Endpoint.AttemptStarttls.YES:
 
218
                Response starttls_response = yield transaction_async(new Request(Command.STARTTLS));
 
219
                if (!starttls_response.code.is_starttls_ready())
 
220
                    throw new SmtpError.STARTTLS_FAILED("STARTTLS failed: %s", response.to_string());
 
221
                
 
222
                TlsClientConnection tls_cx = yield endpoint.starttls_handshake_async(cx,
 
223
                    socket_cx.get_remote_address(), cancellable);
 
224
                cx = tls_cx;
 
225
                set_data_streams(tls_cx);
 
226
                
 
227
                // Now that we are on an encrypted line we need to say hello again in order to get the
 
228
                // updated capabilities.
 
229
                response = yield say_hello_async(cancellable);
 
230
            break;
 
231
            
 
232
            case Endpoint.AttemptStarttls.NO:
 
233
                // do nothing
 
234
            break;
 
235
            
 
236
            case Endpoint.AttemptStarttls.HALT:
 
237
            default:
 
238
                throw new SmtpError.NOT_SUPPORTED("STARTTLS not available for %s", endpoint.to_string());
 
239
        }
 
240
        
 
241
        return response;
 
242
    }
 
243
    
225
244
    public async Response quit_async(Cancellable? cancellable = null) throws Error {
226
245
        capabilities = null;
227
246
        return yield transaction_async(new Request(Command.QUIT), cancellable);