Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
e1f434f8
Commit
e1f434f8
authored
Jun 24, 2015
by
Carlos Martín Nieto
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3183 from libgit2/cmn/curl-stream
Implement a cURL stream
parents
9d5efab8
58ca8c7e
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
475 additions
and
23 deletions
+475
-23
CHANGELOG.md
+3
-0
CMakeLists.txt
+11
-0
THREADING.md
+17
-9
include/git2/sys/stream.h
+2
-0
include/git2/types.h
+12
-0
src/curl_stream.c
+257
-0
src/curl_stream.h
+14
-0
src/openssl_stream.c
+110
-12
src/stransport_stream.c
+17
-1
src/stream.h
+15
-0
src/transports/http.c
+17
-1
No files found.
CHANGELOG.md
View file @
e1f434f8
...
@@ -72,6 +72,9 @@ support for HTTPS connections insead of OpenSSL.
...
@@ -72,6 +72,9 @@ support for HTTPS connections insead of OpenSSL.
*
The race condition mitigations described in
`racy-git.txt`
have been
*
The race condition mitigations described in
`racy-git.txt`
have been
implemented.
implemented.
*
If libcurl is installed, we will use it to connect to HTTP(S)
servers.
### API additions
### API additions
*
The
`git_merge_options`
gained a
`file_flags`
member.
*
The
`git_merge_options`
gained a
`file_flags`
member.
...
...
CMakeLists.txt
View file @
e1f434f8
...
@@ -38,6 +38,7 @@ OPTION( USE_ICONV "Link with and use iconv library" OFF )
...
@@ -38,6 +38,7 @@ OPTION( USE_ICONV "Link with and use iconv library" OFF )
OPTION
(
USE_SSH
"Link with libssh to enable SSH support"
ON
)
OPTION
(
USE_SSH
"Link with libssh to enable SSH support"
ON
)
OPTION
(
USE_GSSAPI
"Link with libgssapi for SPNEGO auth"
OFF
)
OPTION
(
USE_GSSAPI
"Link with libgssapi for SPNEGO auth"
OFF
)
OPTION
(
VALGRIND
"Configure build for valgrind"
OFF
)
OPTION
(
VALGRIND
"Configure build for valgrind"
OFF
)
OPTION
(
CURL
"User curl for HTTP if available"
ON
)
IF
(
${
CMAKE_SYSTEM_NAME
}
MATCHES
"Darwin"
)
IF
(
${
CMAKE_SYSTEM_NAME
}
MATCHES
"Darwin"
)
SET
(
USE_ICONV ON
)
SET
(
USE_ICONV ON
)
...
@@ -199,10 +200,20 @@ IF (WIN32 AND WINHTTP)
...
@@ -199,10 +200,20 @@ IF (WIN32 AND WINHTTP)
LINK_LIBRARIES
(
winhttp rpcrt4 crypt32
)
LINK_LIBRARIES
(
winhttp rpcrt4 crypt32
)
ELSE
()
ELSE
()
IF
(
CURL
)
FIND_PACKAGE
(
CURL
)
ENDIF
()
IF
(
NOT AMIGA AND USE_OPENSSL
)
IF
(
NOT AMIGA AND USE_OPENSSL
)
FIND_PACKAGE
(
OpenSSL
)
FIND_PACKAGE
(
OpenSSL
)
ENDIF
()
ENDIF
()
IF
(
CURL_FOUND
)
ADD_DEFINITIONS
(
-DGIT_CURL
)
INCLUDE_DIRECTORIES
(
${
CURL_INCLUDE_DIRS
}
)
LINK_LIBRARIES
(
${
CURL_LIBRARIES
}
)
ENDIF
()
FIND_PACKAGE
(
HTTP_Parser
)
FIND_PACKAGE
(
HTTP_Parser
)
IF
(
HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2
)
IF
(
HTTP_PARSER_FOUND AND HTTP_PARSER_VERSION_MAJOR EQUAL 2
)
INCLUDE_DIRECTORIES
(
${
HTTP_PARSER_INCLUDE_DIRS
}
)
INCLUDE_DIRECTORIES
(
${
HTTP_PARSER_INCLUDE_DIRS
}
)
...
...
THREADING.md
View file @
e1f434f8
...
@@ -47,9 +47,14 @@ you.
...
@@ -47,9 +47,14 @@ you.
On Mac OS X
On Mac OS X
-----------
-----------
On OS X, the library makes use of CommonCrypto and SecureTransport for
By default we use libcurl to perform the encryption. The
cryptographic support. These are thread-safe and you do not need to do
system-provided libcurl uses SecureTransport, so no special steps are
anything special.
necessary. If you link against another libcurl (e.g. from homebrew)
refer to the general case.
If the option to use libcurl was deactivated, the library makes use of
CommonCrypto and SecureTransport for cryptographic support. These are
thread-safe and you do not need to do anything special.
Note that libssh2 may still use OpenSSL itself. In that case, the
Note that libssh2 may still use OpenSSL itself. In that case, the
general case still affects you if you use ssh.
general case still affects you if you use ssh.
...
@@ -57,12 +62,15 @@ general case still affects you if you use ssh.
...
@@ -57,12 +62,15 @@ general case still affects you if you use ssh.
General Case
General Case
------------
------------
On the rest of the platforms, libgit2 uses OpenSSL to be able to use
By default we use libcurl, which has its own !
[
recommendations for
HTTPS as a transport. This library is made to be thread-implementation
thread safety](http://curl.haxx.se/libcurl/c/libcurl-tutorial.html#Multi-threading).
agnostic, and the users of the library must set which locking function
it should use. This means that libgit2 cannot know what to set as the
If libcurl was not found or was disabled, libgit2 uses OpenSSL to be
user of libgit2 may use OpenSSL independently and the locking settings
able to use HTTPS as a transport. This library is made to be
must survive libgit2 shutting down.
thread-implementation agnostic, and the users of the library must set
which locking function it should use. This means that libgit2 cannot
know what to set as the user of libgit2 may use OpenSSL independently
and the locking settings must survive libgit2 shutting down.
libgit2 does provide a last-resort convenience function
libgit2 does provide a last-resort convenience function
`git_openssl_set_locking()`
(available in
`sys/openssl.h`
) to use the
`git_openssl_set_locking()`
(available in
`sys/openssl.h`
) to use the
...
...
include/git2/sys/stream.h
View file @
e1f434f8
...
@@ -29,8 +29,10 @@ typedef struct git_stream {
...
@@ -29,8 +29,10 @@ typedef struct git_stream {
int
version
;
int
version
;
int
encrypted
;
int
encrypted
;
int
proxy_support
;
int
(
*
connect
)(
struct
git_stream
*
);
int
(
*
connect
)(
struct
git_stream
*
);
int
(
*
certificate
)(
git_cert
**
,
struct
git_stream
*
);
int
(
*
certificate
)(
git_cert
**
,
struct
git_stream
*
);
int
(
*
set_proxy
)(
struct
git_stream
*
,
const
char
*
proxy_url
);
ssize_t
(
*
read
)(
struct
git_stream
*
,
void
*
,
size_t
);
ssize_t
(
*
read
)(
struct
git_stream
*
,
void
*
,
size_t
);
ssize_t
(
*
write
)(
struct
git_stream
*
,
const
char
*
,
size_t
,
int
);
ssize_t
(
*
write
)(
struct
git_stream
*
,
const
char
*
,
size_t
,
int
);
int
(
*
close
)(
struct
git_stream
*
);
int
(
*
close
)(
struct
git_stream
*
);
...
...
include/git2/types.h
View file @
e1f434f8
...
@@ -284,6 +284,11 @@ typedef int (*git_transport_message_cb)(const char *str, int len, void *payload)
...
@@ -284,6 +284,11 @@ typedef int (*git_transport_message_cb)(const char *str, int len, void *payload)
* Type of host certificate structure that is passed to the check callback
* Type of host certificate structure that is passed to the check callback
*/
*/
typedef
enum
git_cert_t
{
typedef
enum
git_cert_t
{
/**
* No information about the certificate is available. This may
* happen when using curl.
*/
GIT_CERT_NONE
,
/**
/**
* The `data` argument to the callback will be a pointer to
* The `data` argument to the callback will be a pointer to
* the DER-encoded data.
* the DER-encoded data.
...
@@ -294,6 +299,13 @@ typedef enum git_cert_t {
...
@@ -294,6 +299,13 @@ typedef enum git_cert_t {
* `git_cert_hostkey` structure.
* `git_cert_hostkey` structure.
*/
*/
GIT_CERT_HOSTKEY_LIBSSH2
,
GIT_CERT_HOSTKEY_LIBSSH2
,
/**
* The `data` argument to the callback will be a pointer to a
* `git_strarray` with `name:content` strings containing
* information about the certificate. This is used when using
* curl.
*/
GIT_CERT_STRARRAY
,
}
git_cert_t
;
}
git_cert_t
;
/**
/**
...
...
src/curl_stream.c
0 → 100644
View file @
e1f434f8
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifdef GIT_CURL
#include <curl/curl.h>
#include "stream.h"
#include "git2/transport.h"
#include "buffer.h"
#include "vector.h"
typedef
struct
{
git_stream
parent
;
CURL
*
handle
;
curl_socket_t
socket
;
char
curl_error
[
CURL_ERROR_SIZE
+
1
];
git_cert_x509
cert_info
;
git_strarray
cert_info_strings
;
}
curl_stream
;
static
int
seterr_curl
(
curl_stream
*
s
)
{
giterr_set
(
GITERR_NET
,
"curl error: %s
\n
"
,
s
->
curl_error
);
return
-
1
;
}
static
int
curls_connect
(
git_stream
*
stream
)
{
curl_stream
*
s
=
(
curl_stream
*
)
stream
;
long
sockextr
;
int
failed_cert
=
0
;
CURLcode
res
;
res
=
curl_easy_perform
(
s
->
handle
);
if
(
res
!=
CURLE_OK
&&
res
!=
CURLE_PEER_FAILED_VERIFICATION
)
return
seterr_curl
(
s
);
if
(
res
==
CURLE_PEER_FAILED_VERIFICATION
)
failed_cert
=
1
;
if
((
res
=
curl_easy_getinfo
(
s
->
handle
,
CURLINFO_LASTSOCKET
,
&
sockextr
))
!=
CURLE_OK
)
return
seterr_curl
(
s
);
s
->
socket
=
sockextr
;
if
(
s
->
parent
.
encrypted
&&
failed_cert
)
return
GIT_ECERTIFICATE
;
return
0
;
}
static
int
curls_certificate
(
git_cert
**
out
,
git_stream
*
stream
)
{
int
error
;
CURLcode
res
;
struct
curl_slist
*
slist
;
struct
curl_certinfo
*
certinfo
;
git_vector
strings
=
GIT_VECTOR_INIT
;
curl_stream
*
s
=
(
curl_stream
*
)
stream
;
if
((
res
=
curl_easy_getinfo
(
s
->
handle
,
CURLINFO_CERTINFO
,
&
certinfo
))
!=
CURLE_OK
)
return
seterr_curl
(
s
);
/* No information is available, can happen with SecureTransport */
if
(
certinfo
->
num_of_certs
==
0
)
{
s
->
cert_info
.
cert_type
=
GIT_CERT_NONE
;
s
->
cert_info
.
data
=
NULL
;
s
->
cert_info
.
len
=
0
;
return
0
;
}
if
((
error
=
git_vector_init
(
&
strings
,
8
,
NULL
))
<
0
)
return
error
;
for
(
slist
=
certinfo
->
certinfo
[
0
];
slist
;
slist
=
slist
->
next
)
{
char
*
str
=
git__strdup
(
slist
->
data
);
GITERR_CHECK_ALLOC
(
str
);
}
/* Copy the contents of the vector into a strarray so we can expose them */
s
->
cert_info_strings
.
strings
=
(
char
**
)
strings
.
contents
;
s
->
cert_info_strings
.
count
=
strings
.
length
;
s
->
cert_info
.
cert_type
=
GIT_CERT_STRARRAY
;
s
->
cert_info
.
data
=
&
s
->
cert_info_strings
;
s
->
cert_info
.
len
=
strings
.
length
;
*
out
=
(
git_cert
*
)
&
s
->
cert_info
;
return
0
;
}
static
int
curls_set_proxy
(
git_stream
*
stream
,
const
char
*
proxy_url
)
{
CURLcode
res
;
curl_stream
*
s
=
(
curl_stream
*
)
stream
;
if
((
res
=
curl_easy_setopt
(
s
->
handle
,
CURLOPT_PROXY
,
proxy_url
))
!=
CURLE_OK
)
return
seterr_curl
(
s
);
return
0
;
}
static
int
wait_for
(
curl_socket_t
fd
,
bool
reading
)
{
int
ret
;
fd_set
infd
,
outfd
,
errfd
;
FD_ZERO
(
&
infd
);
FD_ZERO
(
&
outfd
);
FD_ZERO
(
&
errfd
);
FD_SET
(
fd
,
&
errfd
);
if
(
reading
)
FD_SET
(
fd
,
&
infd
);
else
FD_SET
(
fd
,
&
outfd
);
if
((
ret
=
select
(
fd
+
1
,
&
infd
,
&
outfd
,
&
errfd
,
NULL
))
<
0
)
{
giterr_set
(
GITERR_OS
,
"error in select"
);
return
-
1
;
}
return
0
;
}
static
ssize_t
curls_write
(
git_stream
*
stream
,
const
char
*
data
,
size_t
len
,
int
flags
)
{
int
error
;
size_t
off
=
0
,
sent
;
CURLcode
res
;
curl_stream
*
s
=
(
curl_stream
*
)
stream
;
GIT_UNUSED
(
flags
);
do
{
if
((
error
=
wait_for
(
s
->
socket
,
false
))
<
0
)
return
error
;
res
=
curl_easy_send
(
s
->
handle
,
data
+
off
,
len
-
off
,
&
sent
);
if
(
res
==
CURLE_OK
)
off
+=
sent
;
}
while
((
res
==
CURLE_OK
||
res
==
CURLE_AGAIN
)
&&
off
<
len
);
if
(
res
!=
CURLE_OK
)
return
seterr_curl
(
s
);
return
len
;
}
static
ssize_t
curls_read
(
git_stream
*
stream
,
void
*
data
,
size_t
len
)
{
int
error
;
size_t
read
;
CURLcode
res
;
curl_stream
*
s
=
(
curl_stream
*
)
stream
;
do
{
if
((
error
=
wait_for
(
s
->
socket
,
true
))
<
0
)
return
error
;
res
=
curl_easy_recv
(
s
->
handle
,
data
,
len
,
&
read
);
}
while
(
res
==
CURLE_AGAIN
);
if
(
res
!=
CURLE_OK
)
return
seterr_curl
(
s
);
return
read
;
}
static
int
curls_close
(
git_stream
*
stream
)
{
curl_stream
*
s
=
(
curl_stream
*
)
stream
;
if
(
!
s
->
handle
)
return
0
;
curl_easy_cleanup
(
s
->
handle
);
s
->
handle
=
NULL
;
s
->
socket
=
0
;
return
0
;
}
static
void
curls_free
(
git_stream
*
stream
)
{
curl_stream
*
s
=
(
curl_stream
*
)
stream
;
curls_close
(
stream
);
git_strarray_free
(
&
s
->
cert_info_strings
);
git__free
(
s
);
}
int
git_curl_stream_new
(
git_stream
**
out
,
const
char
*
host
,
const
char
*
port
)
{
curl_stream
*
st
;
CURL
*
handle
;
int
iport
=
0
,
error
;
st
=
git__calloc
(
1
,
sizeof
(
curl_stream
));
GITERR_CHECK_ALLOC
(
st
);
handle
=
curl_easy_init
();
if
(
handle
==
NULL
)
{
giterr_set
(
GITERR_NET
,
"failed to create curl handle"
);
return
-
1
;
}
if
((
error
=
git__strtol32
(
&
iport
,
port
,
NULL
,
10
))
<
0
)
return
error
;
curl_easy_setopt
(
handle
,
CURLOPT_URL
,
host
);
curl_easy_setopt
(
handle
,
CURLOPT_ERRORBUFFER
,
st
->
curl_error
);
curl_easy_setopt
(
handle
,
CURLOPT_PORT
,
iport
);
curl_easy_setopt
(
handle
,
CURLOPT_CONNECT_ONLY
,
1
);
curl_easy_setopt
(
handle
,
CURLOPT_SSL_VERIFYPEER
,
1
);
curl_easy_setopt
(
handle
,
CURLOPT_CERTINFO
,
1
);
curl_easy_setopt
(
handle
,
CURLOPT_HTTPPROXYTUNNEL
,
1
);
/* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); */
st
->
parent
.
version
=
GIT_STREAM_VERSION
;
st
->
parent
.
encrypted
=
0
;
/* we don't encrypt ourselves */
st
->
parent
.
proxy_support
=
1
;
st
->
parent
.
connect
=
curls_connect
;
st
->
parent
.
certificate
=
curls_certificate
;
st
->
parent
.
set_proxy
=
curls_set_proxy
;
st
->
parent
.
read
=
curls_read
;
st
->
parent
.
write
=
curls_write
;
st
->
parent
.
close
=
curls_close
;
st
->
parent
.
free
=
curls_free
;
st
->
handle
=
handle
;
*
out
=
(
git_stream
*
)
st
;
return
0
;
}
#else
#include "stream.h"
int
git_curl_stream_new
(
git_stream
**
out
,
const
char
*
host
,
const
char
*
port
)
{
GIT_UNUSED
(
out
);
GIT_UNUSED
(
host
);
GIT_UNUSED
(
port
);
giterr_set
(
GITERR_NET
,
"curl is not supported in this version"
);
return
-
1
;
}
#endif
src/curl_stream.h
0 → 100644
View file @
e1f434f8
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_curl_stream_h__
#define INCLUDE_curl_stream_h__
#include "git2/sys/stream.h"
extern
int
git_curl_stream_new
(
git_stream
**
out
,
const
char
*
host
,
const
char
*
port
);
#endif
src/openssl_stream.c
View file @
e1f434f8
...
@@ -16,6 +16,10 @@
...
@@ -16,6 +16,10 @@
#include "netops.h"
#include "netops.h"
#include "git2/transport.h"
#include "git2/transport.h"
#ifdef GIT_CURL
# include "curl_stream.h"
#endif
#ifndef GIT_WIN32
#ifndef GIT_WIN32
# include <sys/types.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <sys/socket.h>
...
@@ -25,6 +29,79 @@
...
@@ -25,6 +29,79 @@
#include <openssl/ssl.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include <openssl/x509v3.h>
#include <openssl/bio.h>
static
int
bio_create
(
BIO
*
b
)
{
b
->
init
=
1
;
b
->
num
=
0
;
b
->
ptr
=
NULL
;
b
->
flags
=
0
;
return
1
;
}
static
int
bio_destroy
(
BIO
*
b
)
{
if
(
!
b
)
return
0
;
b
->
init
=
0
;
b
->
num
=
0
;
b
->
ptr
=
NULL
;
b
->
flags
=
0
;
return
1
;
}
static
int
bio_read
(
BIO
*
b
,
char
*
buf
,
int
len
)
{
git_stream
*
io
=
(
git_stream
*
)
b
->
ptr
;
return
(
int
)
git_stream_read
(
io
,
buf
,
len
);
}
static
int
bio_write
(
BIO
*
b
,
const
char
*
buf
,
int
len
)
{
git_stream
*
io
=
(
git_stream
*
)
b
->
ptr
;
return
(
int
)
git_stream_write
(
io
,
buf
,
len
,
0
);
}
static
long
bio_ctrl
(
BIO
*
b
,
int
cmd
,
long
num
,
void
*
ptr
)
{
GIT_UNUSED
(
b
);
GIT_UNUSED
(
num
);
GIT_UNUSED
(
ptr
);
if
(
cmd
==
BIO_CTRL_FLUSH
)
return
1
;
return
0
;
}
static
int
bio_gets
(
BIO
*
b
,
char
*
buf
,
int
len
)
{
GIT_UNUSED
(
b
);
GIT_UNUSED
(
buf
);
GIT_UNUSED
(
len
);
return
-
1
;
}
static
int
bio_puts
(
BIO
*
b
,
const
char
*
str
)
{
return
bio_write
(
b
,
str
,
strlen
(
str
));
}
static
BIO_METHOD
git_stream_bio_method
=
{
BIO_TYPE_SOURCE_SINK
,
"git_stream"
,
bio_write
,
bio_read
,
bio_puts
,
bio_gets
,
bio_ctrl
,
bio_create
,
bio_destroy
};
static
int
ssl_set_error
(
SSL
*
ssl
,
int
error
)
static
int
ssl_set_error
(
SSL
*
ssl
,
int
error
)
{
{
...
@@ -224,7 +301,8 @@ cert_fail_name:
...
@@ -224,7 +301,8 @@ cert_fail_name:
typedef
struct
{
typedef
struct
{
git_stream
parent
;
git_stream
parent
;
git_socket_stream
*
socket
;
git_stream
*
io
;
char
*
host
;
SSL
*
ssl
;
SSL
*
ssl
;
git_cert_x509
cert_info
;
git_cert_x509
cert_info
;
}
openssl_stream
;
}
openssl_stream
;
...
@@ -234,23 +312,24 @@ int openssl_close(git_stream *stream);
...
@@ -234,23 +312,24 @@ int openssl_close(git_stream *stream);
int
openssl_connect
(
git_stream
*
stream
)
int
openssl_connect
(
git_stream
*
stream
)
{
{
int
ret
;
int
ret
;
BIO
*
bio
;
openssl_stream
*
st
=
(
openssl_stream
*
)
stream
;
openssl_stream
*
st
=
(
openssl_stream
*
)
stream
;
if
((
ret
=
git_stream_connect
(
(
git_stream
*
)
st
->
socket
))
<
0
)
if
((
ret
=
git_stream_connect
(
st
->
io
))
<
0
)
return
ret
;
return
ret
;
if
((
ret
=
SSL_set_fd
(
st
->
ssl
,
st
->
socket
->
s
))
<=
0
)
{
bio
=
BIO_new
(
&
git_stream_bio_method
);
openssl_close
((
git_stream
*
)
st
);
GITERR_CHECK_ALLOC
(
bio
);
return
ssl_set_error
(
st
->
ssl
,
ret
);
bio
->
ptr
=
st
->
io
;
}
SSL_set_bio
(
st
->
ssl
,
bio
,
bio
);
/* specify the host in case SNI is needed */
/* specify the host in case SNI is needed */
SSL_set_tlsext_host_name
(
st
->
ssl
,
st
->
socket
->
host
);
SSL_set_tlsext_host_name
(
st
->
ssl
,
st
->
host
);
if
((
ret
=
SSL_connect
(
st
->
ssl
))
<=
0
)
if
((
ret
=
SSL_connect
(
st
->
ssl
))
<=
0
)
return
ssl_set_error
(
st
->
ssl
,
ret
);
return
ssl_set_error
(
st
->
ssl
,
ret
);
return
verify_server_cert
(
st
->
ssl
,
st
->
socket
->
host
);
return
verify_server_cert
(
st
->
ssl
,
st
->
host
);
}
}
int
openssl_certificate
(
git_cert
**
out
,
git_stream
*
stream
)
int
openssl_certificate
(
git_cert
**
out
,
git_stream
*
stream
)
...
@@ -287,6 +366,13 @@ int openssl_certificate(git_cert **out, git_stream *stream)
...
@@ -287,6 +366,13 @@ int openssl_certificate(git_cert **out, git_stream *stream)
return
0
;
return
0
;
}
}
static
int
openssl_set_proxy
(
git_stream
*
stream
,
const
char
*
proxy_url
)
{
openssl_stream
*
st
=
(
openssl_stream
*
)
stream
;
return
git_stream_set_proxy
(
st
->
io
,
proxy_url
);
}
ssize_t
openssl_write
(
git_stream
*
stream
,
const
char
*
data
,
size_t
len
,
int
flags
)
ssize_t
openssl_write
(
git_stream
*
stream
,
const
char
*
data
,
size_t
len
,
int
flags
)
{
{
openssl_stream
*
st
=
(
openssl_stream
*
)
stream
;
openssl_stream
*
st
=
(
openssl_stream
*
)
stream
;
...
@@ -320,7 +406,7 @@ int openssl_close(git_stream *stream)
...
@@ -320,7 +406,7 @@ int openssl_close(git_stream *stream)
if
((
ret
=
ssl_teardown
(
st
->
ssl
))
<
0
)
if
((
ret
=
ssl_teardown
(
st
->
ssl
))
<
0
)
return
-
1
;
return
-
1
;
return
git_stream_close
(
(
git_stream
*
)
st
->
socket
);
return
git_stream_close
(
st
->
io
);
}
}
void
openssl_free
(
git_stream
*
stream
)
void
openssl_free
(
git_stream
*
stream
)
...
@@ -328,19 +414,26 @@ void openssl_free(git_stream *stream)
...
@@ -328,19 +414,26 @@ void openssl_free(git_stream *stream)
openssl_stream
*
st
=
(
openssl_stream
*
)
stream
;
openssl_stream
*
st
=
(
openssl_stream
*
)
stream
;
git__free
(
st
->
cert_info
.
data
);
git__free
(
st
->
cert_info
.
data
);
git_stream_free
(
(
git_stream
*
)
st
->
socket
);
git_stream_free
(
st
->
io
);
git__free
(
st
);
git__free
(
st
);
}
}
int
git_openssl_stream_new
(
git_stream
**
out
,
const
char
*
host
,
const
char
*
port
)
int
git_openssl_stream_new
(
git_stream
**
out
,
const
char
*
host
,
const
char
*
port
)
{
{
int
error
;
openssl_stream
*
st
;
openssl_stream
*
st
;
st
=
git__calloc
(
1
,
sizeof
(
openssl_stream
));
st
=
git__calloc
(
1
,
sizeof
(
openssl_stream
));
GITERR_CHECK_ALLOC
(
st
);
GITERR_CHECK_ALLOC
(
st
);
if
(
git_socket_stream_new
((
git_stream
**
)
&
st
->
socket
,
host
,
port
))
#ifdef GIT_CURL
return
-
1
;
error
=
git_curl_stream_new
(
&
st
->
io
,
host
,
port
);
#else
error
=
git_socket_stream_new
(
&
st
->
io
,
host
,
port
)
#endif
if
(
error
<
0
)
return
error
;
st
->
ssl
=
SSL_new
(
git__ssl_ctx
);
st
->
ssl
=
SSL_new
(
git__ssl_ctx
);
if
(
st
->
ssl
==
NULL
)
{
if
(
st
->
ssl
==
NULL
)
{
...
@@ -348,10 +441,15 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
...
@@ -348,10 +441,15 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
return
-
1
;
return
-
1
;
}
}
st
->
host
=
git__strdup
(
host
);
GITERR_CHECK_ALLOC
(
st
->
host
);
st
->
parent
.
version
=
GIT_STREAM_VERSION
;
st
->
parent
.
version
=
GIT_STREAM_VERSION
;
st
->
parent
.
encrypted
=
1
;
st
->
parent
.
encrypted
=
1
;
st
->
parent
.
proxy_support
=
git_stream_supports_proxy
(
st
->
io
);
st
->
parent
.
connect
=
openssl_connect
;
st
->
parent
.
connect
=
openssl_connect
;
st
->
parent
.
certificate
=
openssl_certificate
;
st
->
parent
.
certificate
=
openssl_certificate
;
st
->
parent
.
set_proxy
=
openssl_set_proxy
;
st
->
parent
.
read
=
openssl_read
;
st
->
parent
.
read
=
openssl_read
;
st
->
parent
.
write
=
openssl_write
;
st
->
parent
.
write
=
openssl_write
;
st
->
parent
.
close
=
openssl_close
;
st
->
parent
.
close
=
openssl_close
;
...
...
src/stransport_stream.c
View file @
e1f434f8
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
#include "git2/transport.h"
#include "git2/transport.h"
#include "socket_stream.h"
#include "socket_stream.h"
#include "curl_stream.h"
int
stransport_error
(
OSStatus
ret
)
int
stransport_error
(
OSStatus
ret
)
{
{
...
@@ -115,6 +116,13 @@ int stransport_certificate(git_cert **out, git_stream *stream)
...
@@ -115,6 +116,13 @@ int stransport_certificate(git_cert **out, git_stream *stream)
return
0
;
return
0
;
}
}
int
stransport_set_proxy
(
git_stream
*
stream
,
const
char
*
proxy
)
{
stransport_stream
*
st
=
(
stransport_stream
*
)
stream
;
return
git_stream_set_proxy
(
st
->
io
,
proxy
);
}
/*
/*
* Contrary to typical network IO callbacks, Secure Transport write callback is
* Contrary to typical network IO callbacks, Secure Transport write callback is
* expected to write *all* passed data, not just as much as it can, and any
* expected to write *all* passed data, not just as much as it can, and any
...
@@ -233,7 +241,13 @@ int git_stransport_stream_new(git_stream **out, const char *host, const char *po
...
@@ -233,7 +241,13 @@ int git_stransport_stream_new(git_stream **out, const char *host, const char *po
st
=
git__calloc
(
1
,
sizeof
(
stransport_stream
));
st
=
git__calloc
(
1
,
sizeof
(
stransport_stream
));
GITERR_CHECK_ALLOC
(
st
);
GITERR_CHECK_ALLOC
(
st
);
if
((
error
=
git_socket_stream_new
(
&
st
->
io
,
host
,
port
))
<
0
){
#ifdef GIT_CURL
error
=
git_curl_stream_new
(
&
st
->
io
,
host
,
port
);
#else
error
=
git_socket_stream_new
(
&
st
->
io
,
host
,
port
)
#endif
if
(
error
<
0
){
git__free
(
st
);
git__free
(
st
);
return
error
;
return
error
;
}
}
...
@@ -256,8 +270,10 @@ int git_stransport_stream_new(git_stream **out, const char *host, const char *po
...
@@ -256,8 +270,10 @@ int git_stransport_stream_new(git_stream **out, const char *host, const char *po
st
->
parent
.
version
=
GIT_STREAM_VERSION
;
st
->
parent
.
version
=
GIT_STREAM_VERSION
;
st
->
parent
.
encrypted
=
1
;
st
->
parent
.
encrypted
=
1
;
st
->
parent
.
proxy_support
=
git_stream_supports_proxy
(
st
->
io
);
st
->
parent
.
connect
=
stransport_connect
;
st
->
parent
.
connect
=
stransport_connect
;
st
->
parent
.
certificate
=
stransport_certificate
;
st
->
parent
.
certificate
=
stransport_certificate
;
st
->
parent
.
set_proxy
=
stransport_set_proxy
;
st
->
parent
.
read
=
stransport_read
;
st
->
parent
.
read
=
stransport_read
;
st
->
parent
.
write
=
stransport_write
;
st
->
parent
.
write
=
stransport_write
;
st
->
parent
.
close
=
stransport_close
;
st
->
parent
.
close
=
stransport_close
;
...
...
src/stream.h
View file @
e1f434f8
...
@@ -30,6 +30,21 @@ GIT_INLINE(int) git_stream_certificate(git_cert **out, git_stream *st)
...
@@ -30,6 +30,21 @@ GIT_INLINE(int) git_stream_certificate(git_cert **out, git_stream *st)
return
st
->
certificate
(
out
,
st
);
return
st
->
certificate
(
out
,
st
);
}
}
GIT_INLINE
(
int
)
git_stream_supports_proxy
(
git_stream
*
st
)
{
return
st
->
proxy_support
;
}
GIT_INLINE
(
int
)
git_stream_set_proxy
(
git_stream
*
st
,
const
char
*
proxy_url
)
{
if
(
!
st
->
proxy_support
)
{
giterr_set
(
GITERR_INVALID
,
"proxy not supported on this stream"
);
return
-
1
;
}
return
st
->
set_proxy
(
st
,
proxy_url
);
}
GIT_INLINE
(
ssize_t
)
git_stream_read
(
git_stream
*
st
,
void
*
data
,
size_t
len
)
GIT_INLINE
(
ssize_t
)
git_stream_read
(
git_stream
*
st
,
void
*
data
,
size_t
len
)
{
{
return
st
->
read
(
st
,
data
,
len
);
return
st
->
read
(
st
,
data
,
len
);
...
...
src/transports/http.c
View file @
e1f434f8
...
@@ -10,11 +10,13 @@
...
@@ -10,11 +10,13 @@
#include "http_parser.h"
#include "http_parser.h"
#include "buffer.h"
#include "buffer.h"
#include "netops.h"
#include "netops.h"
#include "remote.h"
#include "smart.h"
#include "smart.h"
#include "auth.h"
#include "auth.h"
#include "auth_negotiate.h"
#include "auth_negotiate.h"
#include "tls_stream.h"
#include "tls_stream.h"
#include "socket_stream.h"
#include "socket_stream.h"
#include "curl_stream.h"
git_http_auth_scheme
auth_schemes
[]
=
{
git_http_auth_scheme
auth_schemes
[]
=
{
{
GIT_AUTHTYPE_NEGOTIATE
,
"Negotiate"
,
GIT_CREDTYPE_DEFAULT
,
git_http_auth_negotiate
},
{
GIT_AUTHTYPE_NEGOTIATE
,
"Negotiate"
,
GIT_CREDTYPE_DEFAULT
,
git_http_auth_negotiate
},
...
@@ -532,6 +534,7 @@ static int write_chunk(git_stream *io, const char *buffer, size_t len)
...
@@ -532,6 +534,7 @@ static int write_chunk(git_stream *io, const char *buffer, size_t len)
static
int
http_connect
(
http_subtransport
*
t
)
static
int
http_connect
(
http_subtransport
*
t
)
{
{
int
error
;
int
error
;
char
*
proxy_url
;
if
(
t
->
connected
&&
if
(
t
->
connected
&&
http_should_keep_alive
(
&
t
->
parser
)
&&
http_should_keep_alive
(
&
t
->
parser
)
&&
...
@@ -547,7 +550,11 @@ static int http_connect(http_subtransport *t)
...
@@ -547,7 +550,11 @@ static int http_connect(http_subtransport *t)
if
(
t
->
connection_data
.
use_ssl
)
{
if
(
t
->
connection_data
.
use_ssl
)
{
error
=
git_tls_stream_new
(
&
t
->
io
,
t
->
connection_data
.
host
,
t
->
connection_data
.
port
);
error
=
git_tls_stream_new
(
&
t
->
io
,
t
->
connection_data
.
host
,
t
->
connection_data
.
port
);
}
else
{
}
else
{
#ifdef GIT_CURL
error
=
git_curl_stream_new
(
&
t
->
io
,
t
->
connection_data
.
host
,
t
->
connection_data
.
port
);
#else
error
=
git_socket_stream_new
(
&
t
->
io
,
t
->
connection_data
.
host
,
t
->
connection_data
.
port
);
error
=
git_socket_stream_new
(
&
t
->
io
,
t
->
connection_data
.
host
,
t
->
connection_data
.
port
);
#endif
}
}
if
(
error
<
0
)
if
(
error
<
0
)
...
@@ -555,9 +562,18 @@ static int http_connect(http_subtransport *t)
...
@@ -555,9 +562,18 @@ static int http_connect(http_subtransport *t)
GITERR_CHECK_VERSION
(
t
->
io
,
GIT_STREAM_VERSION
,
"git_stream"
);
GITERR_CHECK_VERSION
(
t
->
io
,
GIT_STREAM_VERSION
,
"git_stream"
);
if
(
git_stream_supports_proxy
(
t
->
io
)
&&
!
git_remote__get_http_proxy
(
t
->
owner
->
owner
,
!!
t
->
connection_data
.
use_ssl
,
&
proxy_url
))
{
error
=
git_stream_set_proxy
(
t
->
io
,
proxy_url
);
git__free
(
proxy_url
);
if
(
error
<
0
)
return
error
;
}
error
=
git_stream_connect
(
t
->
io
);
error
=
git_stream_connect
(
t
->
io
);
#if defined(GIT_OPENSSL) || defined(GIT_SECURE_TRANSPORT)
#if defined(GIT_OPENSSL) || defined(GIT_SECURE_TRANSPORT)
|| defined(GIT_CURL)
if
((
!
error
||
error
==
GIT_ECERTIFICATE
)
&&
t
->
owner
->
certificate_check_cb
!=
NULL
&&
if
((
!
error
||
error
==
GIT_ECERTIFICATE
)
&&
t
->
owner
->
certificate_check_cb
!=
NULL
&&
git_stream_is_encrypted
(
t
->
io
))
{
git_stream_is_encrypted
(
t
->
io
))
{
git_cert
*
cert
;
git_cert
*
cert
;
...
...
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