~ubuntu-branches/ubuntu/lucid/wget/lucid

« back to all changes in this revision

Viewing changes to src/gen_sslfunc.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2005-06-26 16:46:25 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050626164625-jjcde8hyztx7xq7o
Tags: 1.10-2
* wget-fix_error--save-headers patch from upstream
  (closes: Bug#314728)
* don't pattern-match server redirects patch from upstream
  (closes: Bug#163243)
* correct de.po typos
  (closes: Bug#313883)
* wget-E_html_behind_file_counting fix problem with adding the
  numbers after the html extension
* updated Standards-Version: to 3.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* SSL support.
2
 
   Copyright (C) 2000 Free Software Foundation, Inc.
3
 
   Contributed by Christian Fraenkel.
4
 
 
5
 
This file is part of GNU Wget.
6
 
 
7
 
GNU Wget is free software; you can redistribute it and/or modify
8
 
it under the terms of the GNU General Public License as published by
9
 
the Free Software Foundation; either version 2 of the License, or
10
 
(at your option) any later version.
11
 
 
12
 
GNU Wget is distributed in the hope that it will be useful,
13
 
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
GNU General Public License for more details.
16
 
 
17
 
You should have received a copy of the GNU General Public License
18
 
along with Wget; if not, write to the Free Software
19
 
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
 
 
21
 
In addition, as a special exception, the Free Software Foundation
22
 
gives permission to link the code of its release of Wget with the
23
 
OpenSSL project's "OpenSSL" library (or with modified versions of it
24
 
that use the same license as the "OpenSSL" library), and distribute
25
 
the linked executables.  You must obey the GNU General Public License
26
 
in all respects for all of the code used other than "OpenSSL".  If you
27
 
modify this file, you may extend this exception to your version of the
28
 
file, but you are not obligated to do so.  If you do not wish to do
29
 
so, delete this exception statement from your version.  */
30
 
 
31
 
#include <config.h>
32
 
 
33
 
#ifdef HAVE_SSL
34
 
 
35
 
#include <assert.h>
36
 
#include <errno.h>
37
 
#ifdef HAVE_UNISTD_H
38
 
# include <unistd.h>
39
 
#endif
40
 
#ifdef HAVE_STRING_H
41
 
# include <string.h>
42
 
#else
43
 
# include <strings.h>
44
 
#endif
45
 
 
46
 
#include <openssl/bio.h>
47
 
#include <openssl/crypto.h>
48
 
#include <openssl/x509.h>
49
 
#include <openssl/ssl.h>
50
 
#include <openssl/err.h>
51
 
#include <openssl/pem.h>
52
 
#include <openssl/rand.h>
53
 
 
54
 
#include "wget.h"
55
 
#include "utils.h"
56
 
#include "connect.h"
57
 
#include "url.h"
58
 
 
59
 
#ifndef errno
60
 
extern int errno;
61
 
#endif
62
 
 
63
 
void
64
 
ssl_init_prng (void)
65
 
{
66
 
  /* It is likely that older versions of OpenSSL will fail on
67
 
     non-Linux machines because this code is unable to seed the PRNG
68
 
     on older versions of the library.  */
69
 
 
70
 
#if SSLEAY_VERSION_NUMBER >= 0x00905100
71
 
  char rand_file[256];
72
 
  int maxrand = 500;
73
 
 
74
 
  /* First, seed from a file specified by the user.  This will be
75
 
     $RANDFILE, if set, or ~/.rnd.  */
76
 
  RAND_file_name (rand_file, sizeof (rand_file));
77
 
  if (rand_file)
78
 
    /* Seed at most 16k (value borrowed from curl) from random file. */
79
 
    RAND_load_file (rand_file, 16384);
80
 
 
81
 
  if (RAND_status ())
82
 
    return;
83
 
 
84
 
  /* Get random data from EGD if opt.sslegdsock was set.  */
85
 
  if (opt.sslegdsock && *opt.sslegdsock)
86
 
    RAND_egd (opt.sslegdsock);
87
 
 
88
 
  if (RAND_status ())
89
 
    return;
90
 
 
91
 
#ifdef WINDOWS
92
 
  /* Under Windows, we can try to seed the PRNG using screen content.
93
 
     This may or may not work, depending on whether we'll calling Wget
94
 
     interactively.  */
95
 
 
96
 
  RAND_screen ();
97
 
  if (RAND_status ())
98
 
    return;
99
 
#endif
100
 
 
101
 
  /* Still not enough randomness, presumably because neither random
102
 
     file nor EGD have been available.  Use the stupidest possible
103
 
     method -- seed OpenSSL's PRNG with the system's PRNG.  This is
104
 
     insecure in the cryptographic sense, but people who care about
105
 
     security will use /dev/random or their own source of randomness
106
 
     anyway.  */
107
 
 
108
 
  while (RAND_status () == 0 && maxrand-- > 0)
109
 
    {
110
 
      unsigned char rnd = random_number (256);
111
 
      RAND_seed (&rnd, sizeof (rnd));
112
 
    }
113
 
 
114
 
  if (RAND_status () == 0)
115
 
    {
116
 
      logprintf (LOG_NOTQUIET,
117
 
                 _("Could not seed OpenSSL PRNG; disabling SSL.\n"));
118
 
      scheme_disable (SCHEME_HTTPS);
119
 
    }
120
 
#endif /* SSLEAY_VERSION_NUMBER >= 0x00905100 */
121
 
}
122
 
 
123
 
int
124
 
verify_callback (int ok, X509_STORE_CTX *ctx)
125
 
{
126
 
  char *s, buf[256];
127
 
  s = X509_NAME_oneline (X509_get_subject_name (ctx->current_cert), buf, 256);
128
 
  if (ok == 0) {
129
 
    switch (ctx->error) {
130
 
    case X509_V_ERR_CERT_NOT_YET_VALID:
131
 
    case X509_V_ERR_CERT_HAS_EXPIRED:
132
 
      /* This mean the CERT is not valid !!! */
133
 
      ok = 0;
134
 
      break;
135
 
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
136
 
      /* Unsure if we should handle that this way */
137
 
      ok = 1;
138
 
      break;
139
 
    }
140
 
  }
141
 
  return ok;
142
 
}
143
 
 
144
 
/* pass all ssl errors to DEBUGP
145
 
   returns the number of printed errors */
146
 
int
147
 
ssl_printerrors (void) 
148
 
{
149
 
  int ocerr = 0;
150
 
  unsigned long curerr = 0;
151
 
  char errbuff[1024];
152
 
  memset(errbuff, 0, sizeof(errbuff));
153
 
  while ( 0 != (curerr = ERR_get_error ()))
154
 
    {
155
 
      DEBUGP (("OpenSSL: %s\n", ERR_error_string (curerr, errbuff)));
156
 
      ++ocerr;
157
 
    }
158
 
  return ocerr;
159
 
}
160
 
 
161
 
/* Creates a SSL Context and sets some defaults for it */
162
 
uerr_t
163
 
init_ssl (SSL_CTX **ctx)
164
 
{
165
 
  SSL_METHOD *meth = NULL;
166
 
  int verify;
167
 
  int can_validate;
168
 
  SSL_library_init ();
169
 
  SSL_load_error_strings ();
170
 
  SSLeay_add_all_algorithms ();
171
 
  SSLeay_add_ssl_algorithms ();
172
 
  switch (opt.sslprotocol)
173
 
    {
174
 
      default:
175
 
        meth = SSLv23_client_method ();
176
 
        break;
177
 
      case 1 :
178
 
        meth = SSLv2_client_method ();
179
 
        break;
180
 
      case 2 :
181
 
        meth = SSLv3_client_method ();
182
 
        break;
183
 
      case 3 :
184
 
        meth = TLSv1_client_method ();
185
 
        break;
186
 
    }
187
 
  if (meth == NULL)
188
 
    {
189
 
      ssl_printerrors ();
190
 
      return SSLERRCTXCREATE;
191
 
    }
192
 
 
193
 
  *ctx = SSL_CTX_new (meth);
194
 
  if (meth == NULL)
195
 
    {
196
 
      ssl_printerrors ();
197
 
      return SSLERRCTXCREATE;
198
 
    }
199
 
  /* Can we validate the server Cert ? */
200
 
  if (opt.sslcadir != NULL || opt.sslcafile != NULL)
201
 
    {
202
 
      SSL_CTX_load_verify_locations (*ctx, opt.sslcafile, opt.sslcadir);
203
 
      can_validate = 1;
204
 
    }
205
 
  else
206
 
    {
207
 
      can_validate = 0;
208
 
    }
209
 
 
210
 
  if (!opt.sslcheckcert)
211
 
    {
212
 
      /* check cert but ignore error, do not break handshake on error */
213
 
      verify = SSL_VERIFY_NONE;
214
 
    }
215
 
  else
216
 
    {
217
 
      if (!can_validate)
218
 
        {
219
 
          logprintf (LOG_NOTQUIET, "Warrining validation of Server Cert not possible!\n");
220
 
          verify = SSL_VERIFY_NONE;
221
 
        }
222
 
     else
223
 
        {
224
 
          /* break handshake if server cert is not valid but allow NO-Cert mode */
225
 
          verify = SSL_VERIFY_PEER;
226
 
        }
227
 
    }
228
 
 
229
 
  SSL_CTX_set_verify (*ctx, verify, verify_callback);
230
 
 
231
 
  if (opt.sslcertfile != NULL || opt.sslcertkey != NULL)
232
 
    {
233
 
      int ssl_cert_type;
234
 
      if (!opt.sslcerttype)
235
 
        ssl_cert_type = SSL_FILETYPE_PEM;
236
 
      else
237
 
        ssl_cert_type = SSL_FILETYPE_ASN1;
238
 
 
239
 
      if (opt.sslcertkey == NULL) 
240
 
        opt.sslcertkey = opt.sslcertfile;
241
 
      if (opt.sslcertfile == NULL)
242
 
        opt.sslcertfile = opt.sslcertkey; 
243
 
 
244
 
      if (SSL_CTX_use_certificate_file (*ctx, opt.sslcertfile, ssl_cert_type) <= 0)
245
 
        {
246
 
          ssl_printerrors ();
247
 
          return SSLERRCERTFILE;
248
 
        }
249
 
      if (SSL_CTX_use_PrivateKey_file  (*ctx, opt.sslcertkey , ssl_cert_type) <= 0)
250
 
        {
251
 
          ssl_printerrors ();
252
 
          return SSLERRCERTKEY;
253
 
        }
254
 
    }
255
 
 
256
 
  return 0; /* Succeded */
257
 
}
258
 
 
259
 
void
260
 
shutdown_ssl (SSL* con)
261
 
{
262
 
  if (con == NULL)
263
 
    return;
264
 
  if (0==SSL_shutdown (con))
265
 
    SSL_shutdown (con);
266
 
  SSL_free (con);
267
 
}
268
 
 
269
 
/* Sets up a SSL structure and performs the handshake on fd 
270
 
   Returns 0 if everything went right
271
 
   Returns 1 if something went wrong ----- TODO: More exit codes
272
 
*/
273
 
int
274
 
connect_ssl (SSL **con, SSL_CTX *ctx, int fd) 
275
 
{
276
 
  if (NULL == (*con = SSL_new (ctx)))
277
 
    {
278
 
      ssl_printerrors ();
279
 
      return 1;
280
 
    }
281
 
  if (!SSL_set_fd (*con, fd))
282
 
    {
283
 
      ssl_printerrors ();
284
 
      return 1;
285
 
    }
286
 
  SSL_set_connect_state (*con);
287
 
  switch (SSL_connect (*con))
288
 
    {
289
 
      case 1 : 
290
 
        return (*con)->state != SSL_ST_OK;
291
 
      default:
292
 
        ssl_printerrors ();
293
 
        shutdown_ssl (*con);
294
 
        *con = NULL;
295
 
        return 1;
296
 
      case 0 :
297
 
        ssl_printerrors ();
298
 
        SSL_free (*con);
299
 
        *con = NULL;
300
 
        return 1;
301
 
    }
302
 
  return 0;
303
 
}
304
 
 
305
 
void
306
 
free_ssl_ctx (SSL_CTX * ctx)
307
 
{
308
 
  SSL_CTX_free (ctx);
309
 
}
310
 
 
311
 
/* SSL version of iread.  Only exchanged read for SSL_read Read at
312
 
   most LEN bytes from FD, storing them to BUF. */
313
 
 
314
 
int
315
 
ssl_iread (SSL *con, char *buf, int len)
316
 
{
317
 
  int res, fd;
318
 
  BIO_get_fd (con->rbio, &fd);
319
 
#ifdef HAVE_SELECT
320
 
  if (opt.read_timeout && !SSL_pending (con))
321
 
    if (select_fd (fd, opt.read_timeout, 0) <= 0)
322
 
      return -1;
323
 
#endif
324
 
  do
325
 
    res = SSL_read (con, buf, len);
326
 
  while (res == -1 && errno == EINTR);
327
 
 
328
 
  return res;
329
 
}
330
 
 
331
 
/* SSL version of iwrite.  Only exchanged write for SSL_write Write
332
 
   LEN bytes from BUF to FD.  */
333
 
 
334
 
int
335
 
ssl_iwrite (SSL *con, char *buf, int len)
336
 
{
337
 
  int res = 0, fd;
338
 
  BIO_get_fd (con->rbio, &fd);
339
 
  /* `write' may write less than LEN bytes, thus the outward loop
340
 
     keeps trying it until all was written, or an error occurred.  The
341
 
     inner loop is reserved for the usual EINTR f*kage, and the
342
 
     innermost loop deals with the same during select().  */
343
 
  while (len > 0)
344
 
    {
345
 
#ifdef HAVE_SELECT
346
 
      if (opt.read_timeout)
347
 
        if (select_fd (fd, opt.read_timeout, 1) <= 0)
348
 
          return -1;
349
 
#endif
350
 
      do
351
 
        res = SSL_write (con, buf, len);
352
 
      while (res == -1 && errno == EINTR);
353
 
      if (res <= 0)
354
 
        break;
355
 
      buf += res;
356
 
      len -= res;
357
 
    }
358
 
  return res;
359
 
}
360
 
#endif /* HAVE_SSL */