mirror of
https://github.com/mirror/wget.git
synced 2025-01-07 19:00:30 +08:00
[svn] Correctly print SSL errors.
This commit is contained in:
parent
10f290cdf3
commit
550c39e714
@ -1,3 +1,19 @@
|
|||||||
|
2005-07-03 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
|
* ftp.c (getftp): Ditto.
|
||||||
|
|
||||||
|
* http.c (gethttp): Use fd_errstr.
|
||||||
|
|
||||||
|
* connect.c (fd_register_transport): Restructure parameters to
|
||||||
|
include only a single structure that describes transport
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
* openssl.c (openssl_errstr): New function: dump SSL error strings
|
||||||
|
into a static buffer and return a pointer to the buffer.
|
||||||
|
|
||||||
|
* connect.c (fd_errstr): New function; returns transport-specific
|
||||||
|
error message, or strerror(errno) if transport doesn't supply one.
|
||||||
|
|
||||||
2005-07-03 Hrvoje Niksic <hniksic@xemacs.org>
|
2005-07-03 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* mswindows.h: Also wrap accept() and listen().
|
* mswindows.h: Also wrap accept() and listen().
|
||||||
|
@ -732,14 +732,10 @@ sock_close (int fd)
|
|||||||
or SSL_read or whatever is necessary. */
|
or SSL_read or whatever is necessary. */
|
||||||
|
|
||||||
static struct hash_table *transport_map;
|
static struct hash_table *transport_map;
|
||||||
static int transport_map_modified_tick;
|
static unsigned int transport_map_modified_tick;
|
||||||
|
|
||||||
struct transport_info {
|
struct transport_info {
|
||||||
fd_reader_t reader;
|
struct transport_implementation *imp;
|
||||||
fd_writer_t writer;
|
|
||||||
fd_poller_t poller;
|
|
||||||
fd_peeker_t peeker;
|
|
||||||
fd_closer_t closer;
|
|
||||||
void *ctx;
|
void *ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -751,9 +747,7 @@ struct transport_info {
|
|||||||
call getpeername, etc. */
|
call getpeername, etc. */
|
||||||
|
|
||||||
void
|
void
|
||||||
fd_register_transport (int fd, fd_reader_t reader, fd_writer_t writer,
|
fd_register_transport (int fd, struct transport_implementation *imp, void *ctx)
|
||||||
fd_poller_t poller, fd_peeker_t peeker,
|
|
||||||
fd_closer_t closer, void *ctx)
|
|
||||||
{
|
{
|
||||||
struct transport_info *info;
|
struct transport_info *info;
|
||||||
|
|
||||||
@ -763,11 +757,7 @@ fd_register_transport (int fd, fd_reader_t reader, fd_writer_t writer,
|
|||||||
assert (fd >= 0);
|
assert (fd >= 0);
|
||||||
|
|
||||||
info = xnew (struct transport_info);
|
info = xnew (struct transport_info);
|
||||||
info->reader = reader;
|
info->imp = imp;
|
||||||
info->writer = writer;
|
|
||||||
info->poller = poller;
|
|
||||||
info->peeker = peeker;
|
|
||||||
info->closer = closer;
|
|
||||||
info->ctx = ctx;
|
info->ctx = ctx;
|
||||||
if (!transport_map)
|
if (!transport_map)
|
||||||
transport_map = hash_table_new (0, NULL, NULL);
|
transport_map = hash_table_new (0, NULL, NULL);
|
||||||
@ -819,8 +809,8 @@ poll_internal (int fd, struct transport_info *info, int wf, double timeout)
|
|||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
int test;
|
int test;
|
||||||
if (info && info->poller)
|
if (info && info->imp->poller)
|
||||||
test = info->poller (fd, timeout, wf, info->ctx);
|
test = info->imp->poller (fd, timeout, wf, info->ctx);
|
||||||
else
|
else
|
||||||
test = sock_poll (fd, timeout, wf);
|
test = sock_poll (fd, timeout, wf);
|
||||||
if (test == 0)
|
if (test == 0)
|
||||||
@ -843,8 +833,8 @@ fd_read (int fd, char *buf, int bufsize, double timeout)
|
|||||||
LAZY_RETRIEVE_INFO (info);
|
LAZY_RETRIEVE_INFO (info);
|
||||||
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
||||||
return -1;
|
return -1;
|
||||||
if (info && info->reader)
|
if (info && info->imp->reader)
|
||||||
return info->reader (fd, buf, bufsize, info->ctx);
|
return info->imp->reader (fd, buf, bufsize, info->ctx);
|
||||||
else
|
else
|
||||||
return sock_read (fd, buf, bufsize);
|
return sock_read (fd, buf, bufsize);
|
||||||
}
|
}
|
||||||
@ -868,8 +858,8 @@ fd_peek (int fd, char *buf, int bufsize, double timeout)
|
|||||||
LAZY_RETRIEVE_INFO (info);
|
LAZY_RETRIEVE_INFO (info);
|
||||||
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
|
||||||
return -1;
|
return -1;
|
||||||
if (info && info->peeker)
|
if (info && info->imp->peeker)
|
||||||
return info->peeker (fd, buf, bufsize, info->ctx);
|
return info->imp->peeker (fd, buf, bufsize, info->ctx);
|
||||||
else
|
else
|
||||||
return sock_peek (fd, buf, bufsize);
|
return sock_peek (fd, buf, bufsize);
|
||||||
}
|
}
|
||||||
@ -893,8 +883,8 @@ fd_write (int fd, char *buf, int bufsize, double timeout)
|
|||||||
{
|
{
|
||||||
if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout))
|
if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout))
|
||||||
return -1;
|
return -1;
|
||||||
if (info && info->writer)
|
if (info && info->imp->writer)
|
||||||
res = info->writer (fd, buf, bufsize, info->ctx);
|
res = info->imp->writer (fd, buf, bufsize, info->ctx);
|
||||||
else
|
else
|
||||||
res = sock_write (fd, buf, bufsize);
|
res = sock_write (fd, buf, bufsize);
|
||||||
if (res <= 0)
|
if (res <= 0)
|
||||||
@ -905,6 +895,34 @@ fd_write (int fd, char *buf, int bufsize, double timeout)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Report the most recent error(s) on FD. This should only be called
|
||||||
|
after fd_* functions, such as fd_read and fd_write, and only if
|
||||||
|
they return a negative result. For errors coming from other calls
|
||||||
|
such as setsockopt or fopen, strerror should continue to be
|
||||||
|
used.
|
||||||
|
|
||||||
|
If the transport doesn't support error messages or doesn't supply
|
||||||
|
one, strerror(errno) is returned. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
fd_errstr (int fd)
|
||||||
|
{
|
||||||
|
/* Don't bother with LAZY_RETRIEVE_INFO, as this will only be called
|
||||||
|
in case of error, never in a tight loop. */
|
||||||
|
struct transport_info *info = NULL;
|
||||||
|
if (transport_map)
|
||||||
|
info = hash_table_get (transport_map, (void *) fd);
|
||||||
|
|
||||||
|
if (info && info->imp->errstr)
|
||||||
|
{
|
||||||
|
const char *err = info->imp->errstr (fd, info->ctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
/* else, fall through and print the system error. */
|
||||||
|
}
|
||||||
|
return strerror (errno);
|
||||||
|
}
|
||||||
|
|
||||||
/* Close the file descriptor FD. */
|
/* Close the file descriptor FD. */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -920,8 +938,8 @@ fd_close (int fd)
|
|||||||
if (transport_map)
|
if (transport_map)
|
||||||
info = hash_table_get (transport_map, (void *) fd);
|
info = hash_table_get (transport_map, (void *) fd);
|
||||||
|
|
||||||
if (info && info->closer)
|
if (info && info->imp->closer)
|
||||||
info->closer (fd, info->ctx);
|
info->imp->closer (fd, info->ctx);
|
||||||
else
|
else
|
||||||
sock_close (fd);
|
sock_close (fd);
|
||||||
|
|
||||||
|
@ -60,17 +60,21 @@ enum {
|
|||||||
int select_fd (int, double, int);
|
int select_fd (int, double, int);
|
||||||
bool test_socket_open (int);
|
bool test_socket_open (int);
|
||||||
|
|
||||||
typedef int (*fd_reader_t) (int, char *, int, void *);
|
struct transport_implementation {
|
||||||
typedef int (*fd_writer_t) (int, char *, int, void *);
|
int (*reader) (int, char *, int, void *);
|
||||||
typedef int (*fd_poller_t) (int, double, int, void *);
|
int (*writer) (int, char *, int, void *);
|
||||||
typedef int (*fd_peeker_t) (int, char *, int, void *);
|
int (*poller) (int, double, int, void *);
|
||||||
typedef void (*fd_closer_t) (int, void *);
|
int (*peeker) (int, char *, int, void *);
|
||||||
void fd_register_transport (int, fd_reader_t, fd_writer_t,
|
const char *(*errstr) (int, void *);
|
||||||
fd_poller_t, fd_peeker_t, fd_closer_t, void *);
|
void (*closer) (int, void *);
|
||||||
void *fd_transport_context (int);
|
};
|
||||||
|
|
||||||
|
void fd_register_transport (int, struct transport_implementation *, void *);
|
||||||
|
void *fd_transport_context (int);
|
||||||
int fd_read (int, char *, int, double);
|
int fd_read (int, char *, int, double);
|
||||||
int fd_write (int, char *, int, double);
|
int fd_write (int, char *, int, double);
|
||||||
int fd_peek (int, char *, int, double);
|
int fd_peek (int, char *, int, double);
|
||||||
|
const char *fd_errstr (int);
|
||||||
void fd_close (int);
|
void fd_close (int);
|
||||||
|
|
||||||
#endif /* CONNECT_H */
|
#endif /* CONNECT_H */
|
||||||
|
24
src/ftp.c
24
src/ftp.c
@ -952,7 +952,7 @@ Error in server response, closing control connection.\n"));
|
|||||||
if (*len)
|
if (*len)
|
||||||
{
|
{
|
||||||
print_length (*len, restval, true);
|
print_length (*len, restval, true);
|
||||||
expected_bytes = *len; /* for get_contents/show_progress */
|
expected_bytes = *len; /* for fd_read_body's progress bar */
|
||||||
}
|
}
|
||||||
else if (expected_bytes)
|
else if (expected_bytes)
|
||||||
print_length (expected_bytes, restval, false);
|
print_length (expected_bytes, restval, false);
|
||||||
@ -971,39 +971,29 @@ Error in server response, closing control connection.\n"));
|
|||||||
tmrate = retr_rate (rd_size, con->dltime);
|
tmrate = retr_rate (rd_size, con->dltime);
|
||||||
total_download_time += con->dltime;
|
total_download_time += con->dltime;
|
||||||
|
|
||||||
/* Close data connection socket. */
|
|
||||||
fd_close (dtsock);
|
|
||||||
fd_close (local_sock);
|
fd_close (local_sock);
|
||||||
/* Close the local file. */
|
/* Close the local file. */
|
||||||
{
|
if (!output_stream || con->cmd & DO_LIST)
|
||||||
/* Close or flush the file. We have to be careful to check for
|
fclose (fp);
|
||||||
error here. Checking the result of fwrite() is not enough --
|
|
||||||
errors could go unnoticed! */
|
|
||||||
int flush_res;
|
|
||||||
if (!output_stream || con->cmd & DO_LIST)
|
|
||||||
flush_res = fclose (fp);
|
|
||||||
else
|
|
||||||
flush_res = fflush (fp);
|
|
||||||
if (flush_res == EOF)
|
|
||||||
res = -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If get_contents couldn't write to fp, bail out. */
|
/* If fd_read_body couldn't write to fp, bail out. */
|
||||||
if (res == -2)
|
if (res == -2)
|
||||||
{
|
{
|
||||||
logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
|
logprintf (LOG_NOTQUIET, _("%s: %s, closing control connection.\n"),
|
||||||
con->target, strerror (errno));
|
con->target, strerror (errno));
|
||||||
fd_close (csock);
|
fd_close (csock);
|
||||||
con->csock = -1;
|
con->csock = -1;
|
||||||
|
fd_close (dtsock);
|
||||||
return FWRITEERR;
|
return FWRITEERR;
|
||||||
}
|
}
|
||||||
else if (res == -1)
|
else if (res == -1)
|
||||||
{
|
{
|
||||||
logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
|
logprintf (LOG_NOTQUIET, _("%s (%s) - Data connection: %s; "),
|
||||||
tms, tmrate, strerror (errno));
|
tms, tmrate, fd_errstr (dtsock));
|
||||||
if (opt.server_response)
|
if (opt.server_response)
|
||||||
logputs (LOG_ALWAYS, "\n");
|
logputs (LOG_ALWAYS, "\n");
|
||||||
}
|
}
|
||||||
|
fd_close (dtsock);
|
||||||
|
|
||||||
/* Get the server to tell us if everything is retrieved. */
|
/* Get the server to tell us if everything is retrieved. */
|
||||||
err = ftp_response (csock, &respline);
|
err = ftp_response (csock, &respline);
|
||||||
|
38
src/http.c
38
src/http.c
@ -352,7 +352,7 @@ request_send (const struct request *req, int fd)
|
|||||||
write_error = fd_write (fd, request_string, size - 1, -1);
|
write_error = fd_write (fd, request_string, size - 1, -1);
|
||||||
if (write_error < 0)
|
if (write_error < 0)
|
||||||
logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
|
logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
|
||||||
strerror (errno));
|
fd_errstr (fd));
|
||||||
return write_error;
|
return write_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -838,7 +838,7 @@ skip_short_body (int fd, wgint contlen)
|
|||||||
/* Don't normally report the error since this is an
|
/* Don't normally report the error since this is an
|
||||||
optimization that should be invisible to the user. */
|
optimization that should be invisible to the user. */
|
||||||
DEBUGP (("] aborting (%s).\n",
|
DEBUGP (("] aborting (%s).\n",
|
||||||
ret < 0 ? strerror (errno) : "EOF received"));
|
ret < 0 ? fd_errstr (fd) : "EOF received"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
contlen -= ret;
|
contlen -= ret;
|
||||||
@ -1075,6 +1075,7 @@ struct http_stat
|
|||||||
wgint contlen; /* expected length */
|
wgint contlen; /* expected length */
|
||||||
wgint restval; /* the restart value */
|
wgint restval; /* the restart value */
|
||||||
int res; /* the result of last read */
|
int res; /* the result of last read */
|
||||||
|
const char *errstr; /* error message from read error */
|
||||||
char *newloc; /* new location (redirection) */
|
char *newloc; /* new location (redirection) */
|
||||||
char *remote_time; /* remote time-stamp string */
|
char *remote_time; /* remote time-stamp string */
|
||||||
char *error; /* textual HTTP error */
|
char *error; /* textual HTTP error */
|
||||||
@ -1212,6 +1213,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
hs->len = 0;
|
hs->len = 0;
|
||||||
hs->contlen = -1;
|
hs->contlen = -1;
|
||||||
hs->res = -1;
|
hs->res = -1;
|
||||||
|
hs->errstr = "";
|
||||||
hs->newloc = NULL;
|
hs->newloc = NULL;
|
||||||
hs->remote_time = NULL;
|
hs->remote_time = NULL;
|
||||||
hs->error = NULL;
|
hs->error = NULL;
|
||||||
@ -1484,7 +1486,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
if (write_error < 0)
|
if (write_error < 0)
|
||||||
{
|
{
|
||||||
logprintf (LOG_VERBOSE, _("Failed writing to proxy: %s.\n"),
|
logprintf (LOG_VERBOSE, _("Failed writing to proxy: %s.\n"),
|
||||||
strerror (errno));
|
fd_errstr (sock));
|
||||||
CLOSE_INVALIDATE (sock);
|
CLOSE_INVALIDATE (sock);
|
||||||
return WRITEFAILED;
|
return WRITEFAILED;
|
||||||
}
|
}
|
||||||
@ -1493,7 +1495,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
if (!head)
|
if (!head)
|
||||||
{
|
{
|
||||||
logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
|
logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
|
||||||
strerror (errno));
|
fd_errstr (sock));
|
||||||
CLOSE_INVALIDATE (sock);
|
CLOSE_INVALIDATE (sock);
|
||||||
return HERR;
|
return HERR;
|
||||||
}
|
}
|
||||||
@ -1554,7 +1556,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
if (write_error < 0)
|
if (write_error < 0)
|
||||||
{
|
{
|
||||||
logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
|
logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
|
||||||
strerror (errno));
|
fd_errstr (sock));
|
||||||
CLOSE_INVALIDATE (sock);
|
CLOSE_INVALIDATE (sock);
|
||||||
request_free (req);
|
request_free (req);
|
||||||
return WRITEFAILED;
|
return WRITEFAILED;
|
||||||
@ -1578,7 +1580,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
|
logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
|
||||||
strerror (errno));
|
fd_errstr (sock));
|
||||||
CLOSE_INVALIDATE (sock);
|
CLOSE_INVALIDATE (sock);
|
||||||
request_free (req);
|
request_free (req);
|
||||||
return HERR;
|
return HERR;
|
||||||
@ -1966,20 +1968,14 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
|
|||||||
if (hs->res >= 0)
|
if (hs->res >= 0)
|
||||||
CLOSE_FINISH (sock);
|
CLOSE_FINISH (sock);
|
||||||
else
|
else
|
||||||
CLOSE_INVALIDATE (sock);
|
{
|
||||||
|
if (hs->res < 0)
|
||||||
|
hs->errstr = fd_errstr (sock);
|
||||||
|
CLOSE_INVALIDATE (sock);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
if (!output_stream)
|
||||||
/* Close or flush the file. We have to be careful to check for
|
fclose (fp);
|
||||||
error here. Checking the result of fwrite() is not enough --
|
|
||||||
errors could go unnoticed! */
|
|
||||||
int flush_res;
|
|
||||||
if (!output_stream)
|
|
||||||
flush_res = fclose (fp);
|
|
||||||
else
|
|
||||||
flush_res = fflush (fp);
|
|
||||||
if (flush_res == EOF)
|
|
||||||
hs->res = -2;
|
|
||||||
}
|
|
||||||
if (hs->res == -2)
|
if (hs->res == -2)
|
||||||
return FWRITEERR;
|
return FWRITEERR;
|
||||||
return RETRFINISHED;
|
return RETRFINISHED;
|
||||||
@ -2502,7 +2498,7 @@ The sizes do not match (local %s) -- retrieving.\n"),
|
|||||||
logprintf (LOG_VERBOSE,
|
logprintf (LOG_VERBOSE,
|
||||||
_("%s (%s) - Read error at byte %s (%s)."),
|
_("%s (%s) - Read error at byte %s (%s)."),
|
||||||
tms, tmrate, number_to_static_string (hstat.len),
|
tms, tmrate, number_to_static_string (hstat.len),
|
||||||
strerror (errno));
|
hstat.errstr);
|
||||||
printwhat (count, opt.ntry);
|
printwhat (count, opt.ntry);
|
||||||
free_hstat (&hstat);
|
free_hstat (&hstat);
|
||||||
continue;
|
continue;
|
||||||
@ -2514,7 +2510,7 @@ The sizes do not match (local %s) -- retrieving.\n"),
|
|||||||
tms, tmrate,
|
tms, tmrate,
|
||||||
number_to_static_string (hstat.len),
|
number_to_static_string (hstat.len),
|
||||||
number_to_static_string (hstat.contlen),
|
number_to_static_string (hstat.contlen),
|
||||||
strerror (errno));
|
hstat.errstr);
|
||||||
printwhat (count, opt.ntry);
|
printwhat (count, opt.ntry);
|
||||||
free_hstat (&hstat);
|
free_hstat (&hstat);
|
||||||
continue;
|
continue;
|
||||||
|
@ -709,7 +709,7 @@ run_with_timeout (double seconds, void (*fun) (void *), void *arg)
|
|||||||
&thread_arg, 0, &thread_id);
|
&thread_arg, 0, &thread_id);
|
||||||
if (!thread_hnd)
|
if (!thread_hnd)
|
||||||
{
|
{
|
||||||
DEBUGP (("CreateThread() failed; %s\n", strerror (GetLastError ())));
|
DEBUGP (("CreateThread() failed; [0x%x]\n", GetLastError ()));
|
||||||
goto blocking_fallback;
|
goto blocking_fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,9 +126,9 @@ init_prng (void)
|
|||||||
static void
|
static void
|
||||||
print_errors (void)
|
print_errors (void)
|
||||||
{
|
{
|
||||||
unsigned long curerr = 0;
|
unsigned long err;
|
||||||
while ((curerr = ERR_get_error ()) != 0)
|
while ((err = ERR_get_error ()) != 0)
|
||||||
logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (curerr, NULL));
|
logprintf (LOG_NOTQUIET, "OpenSSL: %s\n", ERR_error_string (err, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert keyfile type as used by options.h to a type as accepted by
|
/* Convert keyfile type as used by options.h to a type as accepted by
|
||||||
@ -238,7 +238,7 @@ static int
|
|||||||
openssl_read (int fd, char *buf, int bufsize, void *ctx)
|
openssl_read (int fd, char *buf, int bufsize, void *ctx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
SSL *ssl = (SSL *) ctx;
|
SSL *ssl = ctx;
|
||||||
do
|
do
|
||||||
ret = SSL_read (ssl, buf, bufsize);
|
ret = SSL_read (ssl, buf, bufsize);
|
||||||
while (ret == -1
|
while (ret == -1
|
||||||
@ -251,7 +251,7 @@ static int
|
|||||||
openssl_write (int fd, char *buf, int bufsize, void *ctx)
|
openssl_write (int fd, char *buf, int bufsize, void *ctx)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
SSL *ssl = (SSL *) ctx;
|
SSL *ssl = ctx;
|
||||||
do
|
do
|
||||||
ret = SSL_write (ssl, buf, bufsize);
|
ret = SSL_write (ssl, buf, bufsize);
|
||||||
while (ret == -1
|
while (ret == -1
|
||||||
@ -263,7 +263,7 @@ openssl_write (int fd, char *buf, int bufsize, void *ctx)
|
|||||||
static int
|
static int
|
||||||
openssl_poll (int fd, double timeout, int wait_for, void *ctx)
|
openssl_poll (int fd, double timeout, int wait_for, void *ctx)
|
||||||
{
|
{
|
||||||
SSL *ssl = (SSL *) ctx;
|
SSL *ssl = ctx;
|
||||||
if (timeout == 0)
|
if (timeout == 0)
|
||||||
return 1;
|
return 1;
|
||||||
if (SSL_pending (ssl))
|
if (SSL_pending (ssl))
|
||||||
@ -275,7 +275,7 @@ static int
|
|||||||
openssl_peek (int fd, char *buf, int bufsize, void *ctx)
|
openssl_peek (int fd, char *buf, int bufsize, void *ctx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
SSL *ssl = (SSL *) ctx;
|
SSL *ssl = ctx;
|
||||||
do
|
do
|
||||||
ret = SSL_peek (ssl, buf, bufsize);
|
ret = SSL_peek (ssl, buf, bufsize);
|
||||||
while (ret == -1
|
while (ret == -1
|
||||||
@ -284,10 +284,43 @@ openssl_peek (int fd, char *buf, int bufsize, void *ctx)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
openssl_errstr (int fd, void *ctx)
|
||||||
|
{
|
||||||
|
/* Unfortunately we cannot use ERR_error_string's internal buf
|
||||||
|
because we must be prepared to printing more than one error in
|
||||||
|
succession. */
|
||||||
|
static char errbuf[512];
|
||||||
|
char *p = errbuf, *end = errbuf + sizeof errbuf;
|
||||||
|
unsigned long err;
|
||||||
|
|
||||||
|
if ((err = ERR_get_error ()) == 0)
|
||||||
|
/* Inform the caller that there have been no errors */
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Iterate over OpenSSL's error stack and print errors to ERRBUF,
|
||||||
|
each followed by '\n', while being careful not to overrun
|
||||||
|
ERRBUF. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ERR_error_string_n (err, p, end - p);
|
||||||
|
p = strchr (p, '\0');
|
||||||
|
if (p < end)
|
||||||
|
*p++ = '\n';
|
||||||
|
}
|
||||||
|
while ((err = ERR_get_error ()) != 0);
|
||||||
|
|
||||||
|
if (p < end)
|
||||||
|
*p++ = '\0';
|
||||||
|
else
|
||||||
|
end[-1] = '\0';
|
||||||
|
return errbuf;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
openssl_close (int fd, void *ctx)
|
openssl_close (int fd, void *ctx)
|
||||||
{
|
{
|
||||||
SSL *ssl = (SSL *) ctx;
|
SSL *ssl = ctx;
|
||||||
SSL_shutdown (ssl);
|
SSL_shutdown (ssl);
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
|
|
||||||
@ -300,6 +333,14 @@ openssl_close (int fd, void *ctx)
|
|||||||
DEBUGP (("Closed %d/SSL 0x%0lx\n", fd, (unsigned long) ssl));
|
DEBUGP (("Closed %d/SSL 0x%0lx\n", fd, (unsigned long) ssl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* openssl_transport is the singleton that describes the SSL transport
|
||||||
|
methods provided by this file. */
|
||||||
|
|
||||||
|
static struct transport_implementation openssl_transport = {
|
||||||
|
openssl_read, openssl_write, openssl_poll,
|
||||||
|
openssl_peek, openssl_errstr, openssl_close
|
||||||
|
};
|
||||||
|
|
||||||
/* Perform the SSL handshake on file descriptor FD, which is assumed
|
/* Perform the SSL handshake on file descriptor FD, which is assumed
|
||||||
to be connected to an SSL server. The SSL handle provided by
|
to be connected to an SSL server. The SSL handle provided by
|
||||||
OpenSSL is registered with the file descriptor FD using
|
OpenSSL is registered with the file descriptor FD using
|
||||||
@ -327,8 +368,7 @@ ssl_connect (int fd)
|
|||||||
|
|
||||||
/* Register FD with Wget's transport layer, i.e. arrange that our
|
/* Register FD with Wget's transport layer, i.e. arrange that our
|
||||||
functions are used for reading, writing, and polling. */
|
functions are used for reading, writing, and polling. */
|
||||||
fd_register_transport (fd, openssl_read, openssl_write, openssl_poll,
|
fd_register_transport (fd, &openssl_transport, ssl);
|
||||||
openssl_peek, openssl_close, ssl);
|
|
||||||
DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
|
DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
|
||||||
fd, PTR_FORMAT (ssl)));
|
fd, PTR_FORMAT (ssl)));
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user