Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1e5153cf
Commit
1e5153cf
authored
Dec 01, 2005
by
Robert Shearman
Committed by
Alexandre Julliard
Dec 01, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup SSL connections properly, do a few security checks in
NETCON_secure_connect and display errors from SSL on failure. Don't use SSL_set_bio as SSL_set_fd is cleaner for us.
parent
b43afeef
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
119 additions
and
27 deletions
+119
-27
configure
configure
+2
-0
configure.ac
configure.ac
+1
-0
netconnection.c
dlls/wininet/netconnection.c
+113
-27
config.h.in
include/config.h.in
+3
-0
No files found.
configure
View file @
1e5153cf
...
@@ -7037,6 +7037,7 @@ done
...
@@ -7037,6 +7037,7 @@ done
for
ac_header
in
\
for
ac_header
in
\
IOKit/IOKitLib.h
\
IOKit/IOKitLib.h
\
alsa/asoundlib.h
\
alsa/asoundlib.h
\
...
@@ -7085,6 +7086,7 @@ for ac_header in \
...
@@ -7085,6 +7086,7 @@ for ac_header in \
netinet/in_systm.h
\
netinet/in_systm.h
\
netinet/tcp.h
\
netinet/tcp.h
\
netinet/tcp_fsm.h
\
netinet/tcp_fsm.h
\
openssl/err.h
\
openssl/ssl.h
\
openssl/ssl.h
\
poll.h
\
poll.h
\
process.h
\
process.h
\
...
...
configure.ac
View file @
1e5153cf
...
@@ -219,6 +219,7 @@ AC_CHECK_HEADERS(\
...
@@ -219,6 +219,7 @@ AC_CHECK_HEADERS(\
netinet/in_systm.h \
netinet/in_systm.h \
netinet/tcp.h \
netinet/tcp.h \
netinet/tcp_fsm.h \
netinet/tcp_fsm.h \
openssl/err.h \
openssl/ssl.h \
openssl/ssl.h \
poll.h \
poll.h \
process.h \
process.h \
...
...
dlls/wininet/netconnection.c
View file @
1e5153cf
...
@@ -57,7 +57,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
...
@@ -57,7 +57,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
* SSL stuff should use crypt32.dll
* SSL stuff should use crypt32.dll
*/
*/
#ifdef HAVE_OPENSSL_SSL_H
#if defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#ifndef SONAME_LIBSSL
#ifndef SONAME_LIBSSL
#define SONAME_LIBSSL "libssl.so"
#define SONAME_LIBSSL "libssl.so"
...
@@ -80,16 +82,22 @@ MAKE_FUNCPTR(SSL_load_error_strings);
...
@@ -80,16 +82,22 @@ MAKE_FUNCPTR(SSL_load_error_strings);
MAKE_FUNCPTR
(
SSLv23_method
);
MAKE_FUNCPTR
(
SSLv23_method
);
MAKE_FUNCPTR
(
SSL_CTX_new
);
MAKE_FUNCPTR
(
SSL_CTX_new
);
MAKE_FUNCPTR
(
SSL_new
);
MAKE_FUNCPTR
(
SSL_new
);
MAKE_FUNCPTR
(
SSL_set_bio
);
MAKE_FUNCPTR
(
SSL_free
);
MAKE_FUNCPTR
(
SSL_set_fd
);
MAKE_FUNCPTR
(
SSL_connect
);
MAKE_FUNCPTR
(
SSL_connect
);
MAKE_FUNCPTR
(
SSL_shutdown
);
MAKE_FUNCPTR
(
SSL_write
);
MAKE_FUNCPTR
(
SSL_write
);
MAKE_FUNCPTR
(
SSL_read
);
MAKE_FUNCPTR
(
SSL_read
);
MAKE_FUNCPTR
(
SSL_get_verify_result
);
MAKE_FUNCPTR
(
SSL_get_peer_certificate
);
MAKE_FUNCPTR
(
SSL_CTX_get_timeout
);
MAKE_FUNCPTR
(
SSL_CTX_get_timeout
);
MAKE_FUNCPTR
(
SSL_CTX_set_timeout
);
MAKE_FUNCPTR
(
SSL_CTX_set_timeout
);
MAKE_FUNCPTR
(
SSL_CTX_set_default_verify_paths
);
/* OpenSSL's libcrypto functions that we use */
/* OpenSSL's libcrypto functions that we use */
MAKE_FUNCPTR
(
BIO_new_socket
);
MAKE_FUNCPTR
(
BIO_new_fp
);
MAKE_FUNCPTR
(
BIO_new_fp
);
MAKE_FUNCPTR
(
ERR_get_error
);
MAKE_FUNCPTR
(
ERR_error_string
);
#undef MAKE_FUNCPTR
#undef MAKE_FUNCPTR
#endif
#endif
...
@@ -100,7 +108,7 @@ void NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
...
@@ -100,7 +108,7 @@ void NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
connection
->
socketFD
=
-
1
;
connection
->
socketFD
=
-
1
;
if
(
useSSL
)
if
(
useSSL
)
{
{
#if
def HAVE_OPENSSL_SSL
_H
#if
defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR
_H
TRACE
(
"using SSL connection
\n
"
);
TRACE
(
"using SSL connection
\n
"
);
if
(
OpenSSL_ssl_handle
)
/* already initilzed everything */
if
(
OpenSSL_ssl_handle
)
/* already initilzed everything */
return
;
return
;
...
@@ -136,12 +144,17 @@ void NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
...
@@ -136,12 +144,17 @@ void NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
DYNSSL
(
SSLv23_method
);
DYNSSL
(
SSLv23_method
);
DYNSSL
(
SSL_CTX_new
);
DYNSSL
(
SSL_CTX_new
);
DYNSSL
(
SSL_new
);
DYNSSL
(
SSL_new
);
DYNSSL
(
SSL_set_bio
);
DYNSSL
(
SSL_free
);
DYNSSL
(
SSL_set_fd
);
DYNSSL
(
SSL_connect
);
DYNSSL
(
SSL_connect
);
DYNSSL
(
SSL_shutdown
);
DYNSSL
(
SSL_write
);
DYNSSL
(
SSL_write
);
DYNSSL
(
SSL_read
);
DYNSSL
(
SSL_read
);
DYNSSL
(
SSL_get_verify_result
);
DYNSSL
(
SSL_get_peer_certificate
);
DYNSSL
(
SSL_CTX_get_timeout
);
DYNSSL
(
SSL_CTX_get_timeout
);
DYNSSL
(
SSL_CTX_set_timeout
);
DYNSSL
(
SSL_CTX_set_timeout
);
DYNSSL
(
SSL_CTX_set_default_verify_paths
);
#undef DYNSSL
#undef DYNSSL
#define DYNCRYPTO(x) \
#define DYNCRYPTO(x) \
...
@@ -153,7 +166,8 @@ void NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
...
@@ -153,7 +166,8 @@ void NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
return; \
return; \
}
}
DYNCRYPTO
(
BIO_new_fp
);
DYNCRYPTO
(
BIO_new_fp
);
DYNCRYPTO
(
BIO_new_socket
);
DYNCRYPTO
(
ERR_get_error
);
DYNCRYPTO
(
ERR_error_string
);
#undef DYNCRYPTO
#undef DYNCRYPTO
pSSL_library_init
();
pSSL_library_init
();
...
@@ -185,7 +199,7 @@ BOOL NETCON_connected(WININET_NETCONNECTION *connection)
...
@@ -185,7 +199,7 @@ BOOL NETCON_connected(WININET_NETCONNECTION *connection)
BOOL
NETCON_create
(
WININET_NETCONNECTION
*
connection
,
int
domain
,
BOOL
NETCON_create
(
WININET_NETCONNECTION
*
connection
,
int
domain
,
int
type
,
int
protocol
)
int
type
,
int
protocol
)
{
{
#if
ndef HAVE_OPENSSL_SSL
_H
#if
defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR
_H
if
(
connection
->
useSSL
)
if
(
connection
->
useSSL
)
return
FALSE
;
return
FALSE
;
#endif
#endif
...
@@ -206,56 +220,128 @@ BOOL NETCON_close(WININET_NETCONNECTION *connection)
...
@@ -206,56 +220,128 @@ BOOL NETCON_close(WININET_NETCONNECTION *connection)
if
(
!
NETCON_connected
(
connection
))
return
FALSE
;
if
(
!
NETCON_connected
(
connection
))
return
FALSE
;
result
=
closesocket
(
connection
->
socketFD
);
#if defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR_H
connection
->
socketFD
=
-
1
;
#ifdef HAVE_OPENSSL_SSL_H
if
(
connection
->
useSSL
)
if
(
connection
->
useSSL
)
{
{
HeapFree
(
GetProcessHeap
(),
0
,
connection
->
peek_msg_mem
);
HeapFree
(
GetProcessHeap
(),
0
,
connection
->
peek_msg_mem
);
connection
->
peek_msg
=
NULL
;
connection
->
peek_msg
=
NULL
;
connection
->
peek_msg_mem
=
NULL
;
connection
->
peek_msg_mem
=
NULL
;
/* FIXME should we call SSL_shutdown here?? Probably on whatever is the
* opposite of NETCON_secure_connect.... */
pSSL_shutdown
(
connection
->
ssl_s
);
pSSL_free
(
connection
->
ssl_s
);
connection
->
ssl_s
=
NULL
;
connection
->
useSSL
=
FALSE
;
connection
->
useSSL
=
FALSE
;
}
}
#endif
#endif
result
=
closesocket
(
connection
->
socketFD
);
connection
->
socketFD
=
-
1
;
if
(
result
==
-
1
)
if
(
result
==
-
1
)
return
FALSE
;
return
FALSE
;
return
TRUE
;
return
TRUE
;
}
}
static
BOOL
check_hostname
(
X509
*
cert
,
char
*
hostname
)
{
/* FIXME: implement */
return
TRUE
;
}
/******************************************************************************
/******************************************************************************
* NETCON_secure_connect
* NETCON_secure_connect
* Initiates a secure connection over an existing plaintext connection.
* Initiates a secure connection over an existing plaintext connection.
*/
*/
BOOL
NETCON_secure_connect
(
WININET_NETCONNECTION
*
connection
,
LPCWSTR
hostname
)
BOOL
NETCON_secure_connect
(
WININET_NETCONNECTION
*
connection
,
LPCWSTR
hostname
)
{
{
#ifdef HAVE_OPENSSL_SSL_H
#if defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR_H
BIO
*
sbio
;
long
verify_res
;
X509
*
cert
;
int
len
;
char
*
hostname_unix
;
/*
nothing to do
if we are already connected */
/*
can't connect
if we are already connected */
if
(
connection
->
useSSL
)
if
(
connection
->
useSSL
)
{
ERR
(
"already connected
\n
"
);
return
FALSE
;
return
FALSE
;
}
ctx
=
pSSL_CTX_new
(
meth
);
ctx
=
pSSL_CTX_new
(
meth
);
if
(
!
pSSL_CTX_set_default_verify_paths
(
ctx
))
{
ERR
(
"SSL_CTX_set_default_verify_paths failed: %s
\n
"
,
pERR_error_string
(
pERR_get_error
(),
0
));
return
FALSE
;
}
connection
->
ssl_s
=
pSSL_new
(
ctx
);
connection
->
ssl_s
=
pSSL_new
(
ctx
);
if
(
!
connection
->
ssl_s
)
{
ERR
(
"SSL_new failed: %s
\n
"
,
pERR_error_string
(
pERR_get_error
(),
0
));
goto
fail
;
}
if
(
!
pSSL_set_fd
(
connection
->
ssl_s
,
connection
->
socketFD
))
{
ERR
(
"SSL_set_fd failed: %s
\n
"
,
pERR_error_string
(
pERR_get_error
(),
0
));
goto
fail
;
}
sbio
=
pBIO_new_socket
(
connection
->
socketFD
,
BIO_NOCLOSE
);
pSSL_set_bio
(
connection
->
ssl_s
,
sbio
,
sbio
);
if
(
pSSL_connect
(
connection
->
ssl_s
)
<=
0
)
if
(
pSSL_connect
(
connection
->
ssl_s
)
<=
0
)
{
{
ERR
(
"ssl couldn't connect
\n
"
);
ERR
(
"SSL_connect failed: %s
\n
"
,
return
FALSE
;
pERR_error_string
(
pERR_get_error
(),
0
));
INTERNET_SetLastError
(
ERROR_INTERNET_SECURITY_CHANNEL_ERROR
);
goto
fail
;
}
cert
=
pSSL_get_peer_certificate
(
connection
->
ssl_s
);
if
(
!
cert
)
{
ERR
(
"no certificate for server %s
\n
"
,
debugstr_w
(
hostname
));
/* FIXME: is this the best error? */
INTERNET_SetLastError
(
ERROR_INTERNET_INVALID_CA
);
goto
fail
;
}
verify_res
=
pSSL_get_verify_result
(
connection
->
ssl_s
);
if
(
verify_res
!=
X509_V_OK
)
{
ERR
(
"couldn't verify the security of the connection, %ld
\n
"
,
verify_res
);
/* FIXME: we should set an error and return, but we only warn at
* the moment */
}
len
=
WideCharToMultiByte
(
CP_UNIXCP
,
0
,
hostname
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
hostname_unix
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
if
(
!
hostname_unix
)
{
INTERNET_SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
goto
fail
;
}
}
/* FIXME: verify the security of the connection and that the
WideCharToMultiByte
(
CP_UNIXCP
,
0
,
hostname
,
-
1
,
hostname_unix
,
len
,
NULL
,
NULL
);
* hostname of the certificate matches */
if
(
!
check_hostname
(
cert
,
hostname_unix
))
{
HeapFree
(
GetProcessHeap
(),
0
,
hostname_unix
);
INTERNET_SetLastError
(
ERROR_INTERNET_SEC_CERT_CN_INVALID
);
goto
fail
;
}
HeapFree
(
GetProcessHeap
(),
0
,
hostname_unix
);
connection
->
useSSL
=
TRUE
;
connection
->
useSSL
=
TRUE
;
return
TRUE
;
return
TRUE
;
#else
return
FALSE
;
fail:
if
(
connection
->
ssl_s
)
{
pSSL_shutdown
(
connection
->
ssl_s
);
pSSL_free
(
connection
->
ssl_s
);
connection
->
ssl_s
=
NULL
;
}
#endif
#endif
return
FALSE
;
}
}
/******************************************************************************
/******************************************************************************
...
@@ -298,7 +384,7 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
...
@@ -298,7 +384,7 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
}
}
else
else
{
{
#if
def HAVE_OPENSSL_SSL
_H
#if
defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR
_H
if
(
flags
)
if
(
flags
)
FIXME
(
"SSL_write doesn't support any flags (%08x)
\n
"
,
flags
);
FIXME
(
"SSL_write doesn't support any flags (%08x)
\n
"
,
flags
);
*
sent
=
pSSL_write
(
connection
->
ssl_s
,
msg
,
len
);
*
sent
=
pSSL_write
(
connection
->
ssl_s
,
msg
,
len
);
...
@@ -329,7 +415,7 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f
...
@@ -329,7 +415,7 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f
}
}
else
else
{
{
#if
def HAVE_OPENSSL_SSL
_H
#if
defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR
_H
if
(
flags
&
(
~
MSG_PEEK
))
if
(
flags
&
(
~
MSG_PEEK
))
FIXME
(
"SSL_read does not support the following flag: %08x
\n
"
,
flags
);
FIXME
(
"SSL_read does not support the following flag: %08x
\n
"
,
flags
);
...
@@ -446,7 +532,7 @@ BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPD
...
@@ -446,7 +532,7 @@ BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPD
}
}
else
else
{
{
#if
def HAVE_OPENSSL_SSL
_H
#if
defined HAVE_OPENSSL_SSL_H && defined HAVE_OPENSSL_ERR
_H
long
prev_timeout
;
long
prev_timeout
;
DWORD
nRecv
=
0
;
DWORD
nRecv
=
0
;
BOOL
success
=
TRUE
;
BOOL
success
=
TRUE
;
...
...
include/config.h.in
View file @
1e5153cf
...
@@ -431,6 +431,9 @@
...
@@ -431,6 +431,9 @@
/* Define if OpenGL is present on the system */
/* Define if OpenGL is present on the system */
#undef HAVE_OPENGL
#undef HAVE_OPENGL
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define to 1 if you have the <openssl/ssl.h> header file. */
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
#undef HAVE_OPENSSL_SSL_H
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment