Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Pkcs11 Proxy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mirrored_repos
smallstep
Pkcs11 Proxy
Commits
218c41e2
Commit
218c41e2
authored
12 years ago
by
Fredrik Thulin
Browse files
Options
Downloads
Patches
Plain Diff
Add IPv6 support to listener.
Resolve host/service to listen on using getaddrinfo().
parent
50fd6e9f
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
config.h
+2
-0
2 additions, 0 deletions
config.h
gck-rpc-dispatch.c
+165
-69
165 additions, 69 deletions
gck-rpc-dispatch.c
with
167 additions
and
69 deletions
config.h
+
2
−
0
View file @
218c41e2
...
...
@@ -3,6 +3,8 @@
# define DEBUG_OUTPUT 0 // change to 1 to enable debugging
# define PKCS11PROXY_LISTEN_BACKLOG 128
#ifdef __MINGW32__
# include <stdint.h>
...
...
This diff is collapsed.
Click to expand it.
gck-rpc-dispatch.c
+
165
−
69
View file @
218c41e2
...
...
@@ -40,6 +40,8 @@
# include <arpa/inet.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <sys/types.h>
# include <netdb.h>
#endif
#include
<pthread.h>
...
...
@@ -2297,6 +2299,150 @@ void gck_rpc_layer_inetd(CK_FUNCTION_LIST_PTR module)
run_dispatch_thread
(
&
cs
);
}
/*
* Parses prefix into two strings (host and port). Port may be a NULL pointer
* if none is specified. Since this code does not decode port in any way, a
* service name works too (but requires other code (like
* _get_listening_socket()) able to resolve service names).
*
* This should work for IPv4 and IPv6 inputs :
*
* 0.0.0.0:2345
* 0.0.0.0
* [::]:2345
* [::]
* [::1]:2345
* localhost:2345
* localhost
*
* Returns 0 on failure, and 1 on success.
*/
static
int
_parse_host_port
(
const
char
*
prefix
,
char
**
host
,
char
**
port
)
{
char
*
p
=
NULL
;
int
is_ipv6
;
is_ipv6
=
(
prefix
[
0
]
==
'['
)
?
1
:
0
;
*
host
=
strdup
(
prefix
+
is_ipv6
);
*
port
=
NULL
;
if
(
*
host
==
NULL
)
{
gck_rpc_warn
(
"out of memory"
);
return
0
;
}
if
(
is_ipv6
&&
prefix
[
0
]
==
'['
)
p
=
strchr
(
*
host
,
']'
);
else
p
=
strchr
(
*
host
,
':'
);
if
(
p
)
{
is_ipv6
=
(
*
p
==
']'
);
/* remember if separator was ']' */
*
p
=
'\0'
;
/* replace separator will NULL to terminate *host */
*
port
=
p
+
1
;
if
(
is_ipv6
&&
(
**
port
==
':'
))
*
port
=
p
+
2
;
}
return
1
;
}
/*
* Try to get a listening socket for host and port (host may be either a name or
* an IP address, as string) and port (a string with a service name or a port
* number).
*
* Returns -1 on failure, and the socket fd otherwise.
*/
static
int
_get_listening_socket
(
char
*
host
,
char
*
port
)
{
char
hoststr
[
NI_MAXHOST
],
portstr
[
NI_MAXSERV
];
struct
addrinfo
*
ai
,
*
first
,
hints
;
int
res
,
sock
,
one
=
1
;
memset
(
&
hints
,
0
,
sizeof
(
struct
addrinfo
));
hints
.
ai_flags
=
AI_PASSIVE
;
/* Want addr for bind() */
hints
.
ai_family
=
AF_UNSPEC
;
/* Either IPv4 or IPv6 */
hints
.
ai_socktype
=
SOCK_STREAM
;
/* Only stream oriented sockets */
if
((
res
=
getaddrinfo
(
host
,
port
,
&
hints
,
&
ai
))
<
0
)
{
gck_rpc_warn
(
"couldn't resolve host '%.100s' or service '%.100s' : %.100s
\n
"
,
host
,
port
,
gai_strerror
(
res
));
return
-
1
;
}
sock
=
-
1
;
first
=
ai
;
/* Loop through the sockets returned and see if we can find one that accepts
* our options and bind()
*/
while
(
ai
)
{
sock
=
socket
(
ai
->
ai_family
,
ai
->
ai_socktype
,
ai
->
ai_protocol
);
if
(
sock
>=
0
)
{
if
(
setsockopt
(
sock
,
IPPROTO_TCP
,
TCP_NODELAY
,
(
char
*
)
&
one
,
sizeof
(
one
))
==
-
1
)
{
gck_rpc_warn
(
"couldn't set pkcs11 "
"socket protocol options (%.100s %.100s): %.100s"
,
host
,
port
,
strerror
(
errno
));
goto
next
;
}
if
(
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
one
,
sizeof
(
one
))
==
-
1
)
{
gck_rpc_warn
(
"couldn't set pkcs11 socket options (%.100s %.100s): %.100s"
,
host
,
port
,
strerror
(
errno
));
goto
next
;
}
if
(
bind
(
sock
,
ai
->
ai_addr
,
ai
->
ai_addrlen
)
==
0
)
break
;
next:
close
(
sock
);
sock
=
-
1
;
}
ai
=
ai
->
ai_next
;
}
if
(
sock
<
0
)
{
gck_rpc_warn
(
"couldn't create pkcs11 socket (%.100s %.100s): %.100s
\n
"
,
host
,
port
,
strerror
(
errno
));
sock
=
-
1
;
goto
out
;
}
if
(
listen
(
sock
,
PKCS11PROXY_LISTEN_BACKLOG
)
<
0
)
{
gck_rpc_warn
(
"couldn't listen on pkcs11 socket (%.100s %.100s): %.100s"
,
host
,
port
,
strerror
(
errno
));
sock
=
-
1
;
goto
out
;
}
/* Format a string describing the socket we're listening on into pkcs11_socket_path */
if
((
res
=
getnameinfo
(
ai
->
ai_addr
,
ai
->
ai_addrlen
,
hoststr
,
sizeof
(
hoststr
),
portstr
,
sizeof
(
portstr
),
NI_NUMERICHOST
|
NI_NUMERICSERV
))
!=
0
)
{
gck_rpc_warn
(
"couldn't call getnameinfo on pkcs11 socket (%.100s %.100s): %.100s"
,
host
,
port
,
gai_strerror
(
res
));
sock
=
-
1
;
goto
out
;
}
snprintf
(
pkcs11_socket_path
,
sizeof
(
pkcs11_socket_path
),
(
ai
->
ai_family
==
AF_INET6
)
?
"[%s]:%s"
:
"%s:%s"
,
hoststr
,
portstr
);
out:
freeaddrinfo
(
first
);
return
sock
;
}
int
gck_rpc_layer_initialize
(
const
char
*
prefix
,
CK_FUNCTION_LIST_PTR
module
)
{
struct
sockaddr_un
addr
;
...
...
@@ -2330,60 +2476,26 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module)
#endif
if
(
!
strncmp
(
"tcp://"
,
prefix
,
6
))
{
int
one
=
1
,
port
;
char
*
p
=
NULL
;
char
*
ip
;
ip
=
strdup
(
prefix
+
6
);
if
(
ip
==
NULL
)
{
gck_rpc_warn
(
"out of memory"
);
return
-
1
;
}
p
=
strchr
(
ip
,
':'
);
if
(
p
)
{
*
p
=
'\0'
;
port
=
strtol
(
p
+
1
,
NULL
,
0
);
}
else
port
=
0
;
sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
IPPROTO_TCP
);
if
(
sock
<
0
)
{
gck_rpc_warn
(
"couldn't create pkcs11 socket: %s"
,
strerror
(
errno
));
return
-
1
;
}
if
(
setsockopt
(
sock
,
IPPROTO_TCP
,
TCP_NODELAY
,
(
char
*
)
&
one
,
sizeof
(
one
))
==
-
1
)
{
gck_rpc_warn
(
"couldn't set pkcs11 "
"socket options : %s"
,
strerror
(
errno
));
return
-
1
;
}
/*
* TCP socket
*/
char
*
host
,
*
port
;
if
(
setsockopt
(
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
one
,
sizeof
(
one
))
==
-
1
)
{
gck_rpc_warn
(
"couldn't set pkcs11 socket options : %s"
,
strerror
(
errno
));
if
(
!
_parse_host_port
(
prefix
+
6
,
&
host
,
&
port
))
{
free
(
host
);
return
-
1
;
}
addr
.
sun_family
=
AF_INET
;
if
(
inet_aton
(
ip
,
&
((
struct
sockaddr_in
*
)
&
addr
)
->
sin_addr
)
==
0
)
{
gck_rpc_warn
(
"bad inet address : %s"
,
ip
);
if
((
sock
=
_get_listening_socket
(
host
,
port
))
==
-
1
)
{
free
(
host
);
return
-
1
;
}
((
struct
sockaddr_in
*
)
&
addr
)
->
sin_port
=
htons
(
port
);
snprintf
(
pkcs11_socket_path
,
sizeof
(
pkcs11_socket_path
),
"%s"
,
prefix
);
free
(
ip
);
free
(
host
);
}
else
{
/*
* UNIX domain socket
*/
snprintf
(
pkcs11_socket_path
,
sizeof
(
pkcs11_socket_path
),
"%s/socket.pkcs11"
,
prefix
);
...
...
@@ -2399,34 +2511,18 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module)
unlink
(
pkcs11_socket_path
);
strncpy
(
addr
.
sun_path
,
pkcs11_socket_path
,
sizeof
(
addr
.
sun_path
));
}
if
(
bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
<
0
)
{
gck_rpc_warn
(
"couldn't bind to pkcs11 socket: %s: %s"
,
pkcs11_socket_path
,
strerror
(
errno
));
return
-
1
;
}
if
(
listen
(
sock
,
128
)
<
0
)
{
gck_rpc_warn
(
"couldn't listen on pkcs11 socket: %s: %s"
,
pkcs11_socket_path
,
strerror
(
errno
));
return
-
1
;
}
if
(
!
strncmp
(
"tcp://"
,
prefix
,
6
))
{
struct
sockaddr_in
sa
;
socklen_t
sa_len
;
sa_len
=
sizeof
(
sa
);
if
(
getsockname
(
sock
,
(
struct
sockaddr
*
)
&
sa
,
&
sa_len
)
==
-
1
)
{
gck_rpc_warn
(
"getsockname failed on pkcs11 socket: %s: %s"
,
if
(
bind
(
sock
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
<
0
)
{
gck_rpc_warn
(
"couldn't bind to pkcs11 socket: %s: %s"
,
pkcs11_socket_path
,
strerror
(
errno
));
return
-
1
;
}
snprintf
(
pkcs11_socket_path
,
sizeof
(
pkcs11_socket_path
),
"%s:%d"
,
inet_ntoa
(
sa
.
sin_addr
),
ntohs
(
sa
.
sin_port
));
if
(
listen
(
sock
,
PKCS11PROXY_LISTEN_BACKLOG
)
<
0
)
{
gck_rpc_warn
(
"couldn't listen on pkcs11 socket: %s: %s"
,
pkcs11_socket_path
,
strerror
(
errno
));
return
-
1
;
}
}
gck_rpc_log
(
"Listening on: %s
\n
"
,
pkcs11_socket_path
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment