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
6e4bbf22
Commit
6e4bbf22
authored
May 12, 2023
by
Edward Thomson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
net: move rfc2818 hostname / wildcard matching to util
parent
dbe343b6
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
80 additions
and
78 deletions
+80
-78
src/libgit2/netops.c
+0
-39
src/libgit2/netops.h
+0
-13
src/libgit2/streams/openssl.c
+6
-13
src/util/net.c
+44
-0
src/util/net.h
+17
-0
tests/libgit2/network/matchhost.c
+0
-13
tests/util/hostname.c
+13
-0
No files found.
src/libgit2/netops.c
View file @
6e4bbf22
...
...
@@ -83,42 +83,3 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons)
memset
(
buf
->
data
+
cons
,
0x0
,
buf
->
len
-
buf
->
offset
);
buf
->
offset
-=
cons
;
}
/* Match host names according to RFC 2818 rules */
int
gitno__match_host
(
const
char
*
pattern
,
const
char
*
host
)
{
for
(;;)
{
char
c
=
git__tolower
(
*
pattern
++
);
if
(
c
==
'\0'
)
return
*
host
?
-
1
:
0
;
if
(
c
==
'*'
)
{
c
=
*
pattern
;
/* '*' at the end matches everything left */
if
(
c
==
'\0'
)
return
0
;
/*
* We've found a pattern, so move towards the next matching
* char. The '.' is handled specially because wildcards aren't
* allowed to cross subdomains.
*/
while
(
*
host
)
{
char
h
=
git__tolower
(
*
host
);
if
(
c
==
h
)
return
gitno__match_host
(
pattern
,
host
++
);
if
(
h
==
'.'
)
return
gitno__match_host
(
pattern
,
host
);
host
++
;
}
return
-
1
;
}
if
(
c
!=
git__tolower
(
*
host
++
))
return
-
1
;
}
return
-
1
;
}
src/libgit2/netops.h
View file @
6e4bbf22
...
...
@@ -45,19 +45,6 @@ enum {
GITNO_CONNECT_SSL
=
1
};
/**
* Check if the name in a cert matches the wanted hostname
*
* Check if a pattern from a certificate matches the hostname we
* wanted to connect to according to RFC2818 rules (which specifies
* HTTP over TLS). Mainly, an asterisk matches anything, but is
* limited to a single url component.
*
* Note that this does not set an error message. It expects the user
* to provide the message for the user.
*/
int
gitno__match_host
(
const
char
*
pattern
,
const
char
*
host
);
void
gitno_buffer_setup_fromstream
(
git_stream
*
st
,
gitno_buffer
*
buf
,
char
*
data
,
size_t
len
);
void
gitno_buffer_setup_callback
(
gitno_buffer
*
buf
,
char
*
data
,
size_t
len
,
int
(
*
recv
)(
gitno_buffer
*
buf
),
void
*
cb_data
);
int
gitno_recv
(
gitno_buffer
*
buf
);
...
...
src/libgit2/streams/openssl.c
View file @
6e4bbf22
...
...
@@ -18,6 +18,7 @@
#include "settings.h"
#include "posix.h"
#include "stream.h"
#include "net.h"
#include "streams/socket.h"
#include "netops.h"
#include "git2/transport.h"
...
...
@@ -357,15 +358,10 @@ static int ssl_teardown(SSL *ssl)
return
ret
;
}
static
int
check_host_name
(
const
char
*
name
,
const
char
*
host
)
static
bool
check_host_name
(
const
char
*
host
,
const
char
*
name
)
{
if
(
!
strcasecmp
(
name
,
host
))
return
0
;
if
(
gitno__match_host
(
name
,
host
)
<
0
)
return
-
1
;
return
0
;
return
!
strcasecmp
(
host
,
name
)
||
git_net_hostname_matches_cert
(
host
,
name
);
}
static
int
verify_server_cert
(
SSL
*
ssl
,
const
char
*
host
)
...
...
@@ -425,10 +421,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
if
(
memchr
(
name
,
'\0'
,
namelen
))
continue
;
if
(
check_host_name
(
name
,
host
)
<
0
)
matched
=
0
;
else
matched
=
1
;
matched
=
!!
check_host_name
(
host
,
name
);
}
else
if
(
type
==
GEN_IPADD
)
{
/* Here name isn't so much a name but a binary representation of the IP */
matched
=
addr
&&
!!
memcmp
(
name
,
addr
,
namelen
);
...
...
@@ -481,7 +474,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
goto
cert_fail_name
;
}
if
(
check_host_name
((
char
*
)
peer_cn
,
host
)
<
0
)
if
(
!
check_host_name
(
host
,
(
char
*
)
peer_cn
)
)
goto
cert_fail_name
;
goto
cleanup
;
...
...
src/util/net.c
View file @
6e4bbf22
...
...
@@ -19,6 +19,50 @@
#define DEFAULT_PORT_GIT "9418"
#define DEFAULT_PORT_SSH "22"
bool
git_net_hostname_matches_cert
(
const
char
*
hostname
,
const
char
*
pattern
)
{
for
(;;)
{
char
c
=
git__tolower
(
*
pattern
++
);
if
(
c
==
'\0'
)
return
*
hostname
?
false
:
true
;
if
(
c
==
'*'
)
{
c
=
*
pattern
;
/* '*' at the end matches everything left */
if
(
c
==
'\0'
)
return
true
;
/*
* We've found a pattern, so move towards the
* next matching char. The '.' is handled
* specially because wildcards aren't allowed
* to cross subdomains.
*/
while
(
*
hostname
)
{
char
h
=
git__tolower
(
*
hostname
);
if
(
h
==
c
)
return
git_net_hostname_matches_cert
(
hostname
++
,
pattern
);
else
if
(
h
==
'.'
)
return
git_net_hostname_matches_cert
(
hostname
,
pattern
);
hostname
++
;
}
return
false
;
}
if
(
c
!=
git__tolower
(
*
hostname
++
))
return
false
;
}
return
false
;
}
bool
git_net_str_is_url
(
const
char
*
str
)
{
const
char
*
c
;
...
...
src/util/net.h
View file @
6e4bbf22
...
...
@@ -9,6 +9,23 @@
#include "git2_util.h"
/*
* Hostname handling
*/
/*
* See if a given hostname matches a certificate name pattern, according
* to RFC2818 rules (which specifies HTTP over TLS). Mainly, an asterisk
* matches anything, but is limited to a single url component.
*/
extern
bool
git_net_hostname_matches_cert
(
const
char
*
hostname
,
const
char
*
pattern
);
/*
* URL handling
*/
typedef
struct
git_net_url
{
char
*
scheme
;
char
*
host
;
...
...
tests/libgit2/network/matchhost.c
deleted
100644 → 0
View file @
dbe343b6
#include "clar_libgit2.h"
#include "netops.h"
void
test_network_matchhost__match
(
void
)
{
cl_git_pass
(
gitno__match_host
(
"*.example.org"
,
"www.example.org"
));
cl_git_pass
(
gitno__match_host
(
"*.foo.example.org"
,
"www.foo.example.org"
));
cl_git_fail
(
gitno__match_host
(
"*.foo.example.org"
,
"foo.example.org"
));
cl_git_fail
(
gitno__match_host
(
"*.foo.example.org"
,
"www.example.org"
));
cl_git_fail
(
gitno__match_host
(
"*.example.org"
,
"example.org"
));
cl_git_fail
(
gitno__match_host
(
"*.example.org"
,
"www.foo.example.org"
));
cl_git_fail
(
gitno__match_host
(
"*.example.org"
,
"blah.www.www.example.org"
));
}
tests/util/hostname.c
0 → 100644
View file @
6e4bbf22
#include "clar_libgit2.h"
#include "net.h"
void
test_hostname__matches_cert
(
void
)
{
cl_assert_equal_b
(
true
,
git_net_hostname_matches_cert
(
"www.example.org"
,
"*.example.org"
));
cl_assert_equal_b
(
true
,
git_net_hostname_matches_cert
(
"www.foo.example.org"
,
"*.foo.example.org"
));
cl_assert_equal_b
(
false
,
git_net_hostname_matches_cert
(
"foo.example.org"
,
"*.foo.example.org"
));
cl_assert_equal_b
(
false
,
git_net_hostname_matches_cert
(
"www.example.org"
,
"*.foo.example.org"
));
cl_assert_equal_b
(
false
,
git_net_hostname_matches_cert
(
"example.org"
,
"*.example.org"
));
cl_assert_equal_b
(
false
,
git_net_hostname_matches_cert
(
"www.foo.example.org"
,
"*.example.org"
));
cl_assert_equal_b
(
false
,
git_net_hostname_matches_cert
(
"blah.www.www.example.org"
,
"*.example.org"
));
}
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