~ubuntu-branches/ubuntu/oneiric/dma/oneiric

« back to all changes in this revision

Viewing changes to .pc/43_fix_ftbfs_Werror.patch/crypto.c

  • Committer: Bazaar Package Importer
  • Author(s): Tarun Kumar Mall
  • Date: 2011-03-09 17:46:56 UTC
  • mfrom: (7.2.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110309174656-7s0buxoxvsos8ua1
Tags: 0.0.2010.06.17-10ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Patch 38_fix_ftbfs_binutils-gold.patch imported from previous
    ubuntu version.
  - Patch 38_fix_ftbfs_binutils-gold.patch renamed to
    42_fix_ftbfs_binutils-gold.patch
  - Patch 43_fix_ftbfs_Werror.patch added to fix 
    crypto.c:92:7: error: assignment discards 'const' qualifier 
    from pointer target type [-Werror] "Closes: #622052"

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
 
3
 *
 
4
 * This code is derived from software contributed to The DragonFly Project
 
5
 * by Matthias Schmidt <matthias@dragonflybsd.org>, University of Marburg,
 
6
 * Germany.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions
 
10
 * are met:
 
11
 *
 
12
 * 1. Redistributions of source code must retain the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer.
 
14
 * 2. Redistributions in binary form must reproduce the above copyright
 
15
 *    notice, this list of conditions and the following disclaimer in
 
16
 *    the documentation and/or other materials provided with the
 
17
 *    distribution.
 
18
 * 3. Neither the name of The DragonFly Project nor the names of its
 
19
 *    contributors may be used to endorse or promote products derived
 
20
 *    from this software without specific, prior written permission.
 
21
 *
 
22
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
23
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
24
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
25
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 
26
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
27
 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 
28
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
29
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 
30
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
31
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 
32
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
33
 * SUCH DAMAGE.
 
34
 */
 
35
 
 
36
#include <openssl/x509.h>
 
37
#include <openssl/md5.h>
 
38
#include <openssl/ssl.h>
 
39
#include <openssl/err.h>
 
40
#include <openssl/pem.h>
 
41
#include <openssl/rand.h>
 
42
 
 
43
#include <syslog.h>
 
44
 
 
45
#include "dma.h"
 
46
 
 
47
static int
 
48
init_cert_file(SSL_CTX *ctx, const char *path)
 
49
{
 
50
        int error;
 
51
 
 
52
        /* Load certificate into ctx */
 
53
        error = SSL_CTX_use_certificate_chain_file(ctx, path);
 
54
        if (error < 1) {
 
55
                syslog(LOG_ERR, "SSL: Cannot load certificate `%s': %s", path, ssl_errstr());
 
56
                return (-1);
 
57
        }
 
58
 
 
59
        /* Add private key to ctx */
 
60
        error = SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM);
 
61
        if (error < 1) {
 
62
                syslog(LOG_ERR, "SSL: Cannot load private key `%s': %s", path, ssl_errstr());
 
63
                return (-1);
 
64
        }
 
65
 
 
66
        /*
 
67
         * Check the consistency of a private key with the corresponding
 
68
         * certificate
 
69
         */
 
70
        error = SSL_CTX_check_private_key(ctx);
 
71
        if (error < 1) {
 
72
                syslog(LOG_ERR, "SSL: Cannot check private key: %s", ssl_errstr());
 
73
                return (-1);
 
74
        }
 
75
 
 
76
        return (0);
 
77
}
 
78
 
 
79
int
 
80
smtp_init_crypto(int fd, int feature)
 
81
{
 
82
        SSL_CTX *ctx = NULL;
 
83
        SSL_METHOD *meth = NULL;
 
84
        X509 *cert;
 
85
        int error;
 
86
 
 
87
        /* XXX clean up on error/close */
 
88
        /* Init SSL library */
 
89
        SSL_library_init();
 
90
        SSL_load_error_strings();
 
91
 
 
92
        meth = TLSv1_client_method();
 
93
 
 
94
        ctx = SSL_CTX_new(meth);
 
95
        if (ctx == NULL) {
 
96
                syslog(LOG_WARNING, "remote delivery deferred: SSL init failed: %s", ssl_errstr());
 
97
                return (1);
 
98
        }
 
99
 
 
100
        /* User supplied a certificate */
 
101
        if (config.certfile != NULL) {
 
102
                error = init_cert_file(ctx, config.certfile);
 
103
                if (error) {
 
104
                        syslog(LOG_WARNING, "remote delivery deferred");
 
105
                        return (1);
 
106
                }
 
107
        }
 
108
 
 
109
        /*
 
110
         * If the user wants STARTTLS, we have to send EHLO here
 
111
         */
 
112
        if (((feature & SECURETRANS) != 0) &&
 
113
             (feature & STARTTLS) != 0) {
 
114
                /* TLS init phase, disable SSL_write */
 
115
                config.features |= NOSSL;
 
116
 
 
117
                send_remote_command(fd, "EHLO %s", hostname());
 
118
                if (read_remote(fd, 0, NULL) == 2) {
 
119
                        send_remote_command(fd, "STARTTLS");
 
120
                        if (read_remote(fd, 0, NULL) != 2) {
 
121
                                if ((feature & TLS_OPP) == 0) {
 
122
                                        syslog(LOG_ERR,
 
123
                                          "remote delivery deferred:"
 
124
                                          " STARTTLS not available: %s",
 
125
                                          neterr);
 
126
                                        return (1);
 
127
                                } else {
 
128
                                        syslog(LOG_ERR,
 
129
                                          "in opportunistic TLS mode,"
 
130
                                          " STARTTLS not available: %s",
 
131
                                          neterr);
 
132
                                        return (0);
 
133
                                }
 
134
                        }
 
135
                }
 
136
                /* End of TLS init phase, enable SSL_write/read */
 
137
                config.features &= ~NOSSL;
 
138
        }
 
139
 
 
140
        config.ssl = SSL_new(ctx);
 
141
        if (config.ssl == NULL) {
 
142
                syslog(LOG_NOTICE, "remote delivery deferred: SSL struct creation failed: %s",
 
143
                       ssl_errstr());
 
144
                return (1);
 
145
        }
 
146
 
 
147
        /* Set ssl to work in client mode */
 
148
        SSL_set_connect_state(config.ssl);
 
149
 
 
150
        /* Set fd for SSL in/output */
 
151
        error = SSL_set_fd(config.ssl, fd);
 
152
        if (error == 0) {
 
153
                syslog(LOG_NOTICE, "remote delivery deferred: SSL set fd failed: %s",
 
154
                       ssl_errstr());
 
155
                return (1);
 
156
        }
 
157
 
 
158
        /* Open SSL connection */
 
159
        error = SSL_connect(config.ssl);
 
160
        if (error < 0) {
 
161
                syslog(LOG_ERR, "remote delivery deferred: SSL handshake failed fatally: %s",
 
162
                       ssl_errstr());
 
163
                return (1);
 
164
        }
 
165
 
 
166
        /* Get peer certificate */
 
167
        cert = SSL_get_peer_certificate(config.ssl);
 
168
        if (cert == NULL) {
 
169
                syslog(LOG_WARNING, "remote delivery deferred: Peer did not provide certificate: %s",
 
170
                       ssl_errstr());
 
171
        }
 
172
        X509_free(cert);
 
173
 
 
174
        return (0);
 
175
}
 
176
 
 
177
/*
 
178
 * hmac_md5() taken out of RFC 2104.  This RFC was written by H. Krawczyk,
 
179
 * M. Bellare and R. Canetti.
 
180
 *
 
181
 * text      pointer to data stream
 
182
 * text_len  length of data stream
 
183
 * key       pointer to authentication key
 
184
 * key_len   length of authentication key
 
185
 * digest    caller digest to be filled int
 
186
 */
 
187
void
 
188
hmac_md5(unsigned char *text, int text_len, unsigned char *key, int key_len,
 
189
    caddr_t digest)
 
190
{
 
191
        MD5_CTX context;
 
192
        unsigned char k_ipad[65];    /* inner padding -
 
193
                                      * key XORd with ipad
 
194
                                      */
 
195
        unsigned char k_opad[65];    /* outer padding -
 
196
                                      * key XORd with opad
 
197
                                      */
 
198
        unsigned char tk[16];
 
199
        int i;
 
200
        /* if key is longer than 64 bytes reset it to key=MD5(key) */
 
201
        if (key_len > 64) {
 
202
 
 
203
                MD5_CTX      tctx;
 
204
 
 
205
                MD5_Init(&tctx);
 
206
                MD5_Update(&tctx, key, key_len);
 
207
                MD5_Final(tk, &tctx);
 
208
 
 
209
                key = tk;
 
210
                key_len = 16;
 
211
        }
 
212
 
 
213
        /*
 
214
         * the HMAC_MD5 transform looks like:
 
215
         *
 
216
         * MD5(K XOR opad, MD5(K XOR ipad, text))
 
217
         *
 
218
         * where K is an n byte key
 
219
         * ipad is the byte 0x36 repeated 64 times
 
220
         *
 
221
         * opad is the byte 0x5c repeated 64 times
 
222
         * and text is the data being protected
 
223
         */
 
224
 
 
225
        /* start out by storing key in pads */
 
226
        bzero( k_ipad, sizeof k_ipad);
 
227
        bzero( k_opad, sizeof k_opad);
 
228
        bcopy( key, k_ipad, key_len);
 
229
        bcopy( key, k_opad, key_len);
 
230
 
 
231
        /* XOR key with ipad and opad values */
 
232
        for (i=0; i<64; i++) {
 
233
                k_ipad[i] ^= 0x36;
 
234
                k_opad[i] ^= 0x5c;
 
235
        }
 
236
        /*
 
237
         * perform inner MD5
 
238
         */
 
239
        MD5_Init(&context);                   /* init context for 1st
 
240
                                              * pass */
 
241
        MD5_Update(&context, k_ipad, 64);     /* start with inner pad */
 
242
        MD5_Update(&context, text, text_len); /* then text of datagram */
 
243
        MD5_Final(digest, &context);          /* finish up 1st pass */
 
244
        /*
 
245
         * perform outer MD5
 
246
         */
 
247
        MD5_Init(&context);                   /* init context for 2nd
 
248
                                              * pass */
 
249
        MD5_Update(&context, k_opad, 64);     /* start with outer pad */
 
250
        MD5_Update(&context, digest, 16);     /* then results of 1st
 
251
                                              * hash */
 
252
        MD5_Final(digest, &context);          /* finish up 2nd pass */
 
253
}
 
254
 
 
255
/*
 
256
 * CRAM-MD5 authentication
 
257
 */
 
258
int
 
259
smtp_auth_md5(int fd, char *login, char *password)
 
260
{
 
261
        unsigned char buffer[BUF_SIZE], digest[BUF_SIZE], ascii_digest[33];
 
262
        char *temp;
 
263
        int len, i;
 
264
        static char hextab[] = "0123456789abcdef";
 
265
 
 
266
        temp = calloc(BUF_SIZE, 1);
 
267
        memset(buffer, 0, sizeof(buffer));
 
268
        memset(digest, 0, sizeof(digest));
 
269
        memset(ascii_digest, 0, sizeof(ascii_digest));
 
270
 
 
271
        /* Send AUTH command according to RFC 2554 */
 
272
        send_remote_command(fd, "AUTH CRAM-MD5");
 
273
        if (read_remote(fd, sizeof(buffer), buffer) != 3) {
 
274
                syslog(LOG_DEBUG, "smarthost authentication:"
 
275
                       " AUTH cram-md5 not available: %s", neterr);
 
276
                /* if cram-md5 is not available */
 
277
                free(temp);
 
278
                return (-1);
 
279
        }
 
280
 
 
281
        /* skip 3 char status + 1 char space */
 
282
        base64_decode(buffer + 4, temp);
 
283
        hmac_md5(temp, strlen(temp), password, strlen(password), digest);
 
284
        free(temp);
 
285
 
 
286
        ascii_digest[32] = 0;
 
287
        for (i = 0; i < 16; i++) {
 
288
                ascii_digest[2*i] = hextab[digest[i] >> 4];
 
289
                ascii_digest[2*i+1] = hextab[digest[i] & 15];
 
290
        }
 
291
 
 
292
        /* prepare answer */
 
293
        snprintf(buffer, BUF_SIZE, "%s %s", login, ascii_digest);
 
294
 
 
295
        /* encode answer */
 
296
        len = base64_encode(buffer, strlen(buffer), &temp);
 
297
        if (len < 0) {
 
298
                syslog(LOG_ERR, "can not encode auth reply: %m");
 
299
                return (-1);
 
300
        }
 
301
 
 
302
        /* send answer */
 
303
        send_remote_command(fd, "%s", temp);
 
304
        free(temp);
 
305
        if (read_remote(fd, 0, NULL) != 2) {
 
306
                syslog(LOG_WARNING, "remote delivery deferred:"
 
307
                                " AUTH cram-md5 failed: %s", neterr);
 
308
                return (-2);
 
309
        }
 
310
 
 
311
        return (0);
 
312
}