Add setsockopt(sd, SOL_SOCKET, SO_PEERCRED, NULL, 0) to disable
initial handshake on AF_LOCAL sockets. * fhandler.h (class fhandler_socket): Add no_getpeereid status flag. (fhandler_socket::af_local_set_no_getpeereid): New prototype. * fhandler_socket.cc (fhandler_socket::af_local_connect): Skip handshake if no_getpeereid is set. Add debug output. (fhandler_socket::af_local_accept): Likewise. (fhandler_socket::af_local_set_no_getpeereid): New function. (fhandler_socket::af_local_copy): Copy no_getpeereid. (fhandler_socket::getpeereid): Fail if no_getpeereid is set. * net.cc (cygwin_setsockopt): Add SO_PEERCRED for AF_LOCAL/SOCK_STREAM sockets. Add comment to explain why we need it. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
This commit is contained in:
parent
a85ab1d482
commit
697b9afe00
|
@ -1,3 +1,19 @@
|
||||||
|
2014-10-11 Christian Franke <franke@computer.org>
|
||||||
|
|
||||||
|
Add setsockopt(sd, SOL_SOCKET, SO_PEERCRED, NULL, 0) to disable
|
||||||
|
initial handshake on AF_LOCAL sockets.
|
||||||
|
* fhandler.h (class fhandler_socket): Add no_getpeereid status flag.
|
||||||
|
(fhandler_socket::af_local_set_no_getpeereid): New prototype.
|
||||||
|
* fhandler_socket.cc (fhandler_socket::af_local_connect): Skip handshake
|
||||||
|
if no_getpeereid is set. Add debug output.
|
||||||
|
(fhandler_socket::af_local_accept): Likewise.
|
||||||
|
(fhandler_socket::af_local_set_no_getpeereid): New function.
|
||||||
|
(fhandler_socket::af_local_copy): Copy no_getpeereid.
|
||||||
|
(fhandler_socket::getpeereid): Fail if no_getpeereid is set.
|
||||||
|
* net.cc (cygwin_setsockopt): Add SO_PEERCRED for AF_LOCAL/SOCK_STREAM
|
||||||
|
sockets. Add comment to explain why we need it.
|
||||||
|
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||||
|
|
||||||
2014-10-11 Corinna Vinschen <corinna@vinschen.de>
|
2014-10-11 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_socket.cc (fhandler_socket::af_local_connect): Drop outdated
|
* fhandler_socket.cc (fhandler_socket::af_local_connect): Drop outdated
|
||||||
|
|
|
@ -504,6 +504,7 @@ class fhandler_socket: public fhandler_base
|
||||||
int af_local_accept ();
|
int af_local_accept ();
|
||||||
public:
|
public:
|
||||||
int af_local_connect ();
|
int af_local_connect ();
|
||||||
|
int af_local_set_no_getpeereid ();
|
||||||
void af_local_set_sockpair_cred ();
|
void af_local_set_sockpair_cred ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -531,10 +532,11 @@ class fhandler_socket: public fhandler_base
|
||||||
unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */
|
unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */
|
||||||
unsigned saw_reuseaddr : 1; /* Socket saw SO_REUSEADDR call */
|
unsigned saw_reuseaddr : 1; /* Socket saw SO_REUSEADDR call */
|
||||||
unsigned connect_state : 3;
|
unsigned connect_state : 3;
|
||||||
|
unsigned no_getpeereid : 1;
|
||||||
public:
|
public:
|
||||||
status_flags () :
|
status_flags () :
|
||||||
async_io (0), saw_shutdown_read (0), saw_shutdown_write (0),
|
async_io (0), saw_shutdown_read (0), saw_shutdown_write (0),
|
||||||
connect_state (unconnected)
|
connect_state (unconnected), no_getpeereid (0)
|
||||||
{}
|
{}
|
||||||
} status;
|
} status;
|
||||||
|
|
||||||
|
@ -556,6 +558,7 @@ class fhandler_socket: public fhandler_base
|
||||||
IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write)
|
IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, saw_reuseaddr)
|
IMPLEMENT_STATUS_FLAG (bool, saw_reuseaddr)
|
||||||
IMPLEMENT_STATUS_FLAG (conn_state, connect_state)
|
IMPLEMENT_STATUS_FLAG (conn_state, connect_state)
|
||||||
|
IMPLEMENT_STATUS_FLAG (bool, no_getpeereid)
|
||||||
|
|
||||||
int bind (const struct sockaddr *name, int namelen);
|
int bind (const struct sockaddr *name, int namelen);
|
||||||
int connect (const struct sockaddr *name, int namelen);
|
int connect (const struct sockaddr *name, int namelen);
|
||||||
|
|
|
@ -401,7 +401,10 @@ fhandler_socket::af_local_connect ()
|
||||||
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
debug_printf ("af_local_connect called");
|
debug_printf ("af_local_connect called, no_getpeereid=%d", no_getpeereid ());
|
||||||
|
if (no_getpeereid ())
|
||||||
|
return 0;
|
||||||
|
|
||||||
connect_state (connect_credxchg);
|
connect_state (connect_credxchg);
|
||||||
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
||||||
if (!af_local_send_secret () || !af_local_recv_secret ()
|
if (!af_local_send_secret () || !af_local_recv_secret ()
|
||||||
|
@ -421,7 +424,10 @@ fhandler_socket::af_local_accept ()
|
||||||
{
|
{
|
||||||
bool orig_async_io, orig_is_nonblocking;
|
bool orig_async_io, orig_is_nonblocking;
|
||||||
|
|
||||||
debug_printf ("af_local_accept called");
|
debug_printf ("af_local_accept called, no_getpeereid=%d", no_getpeereid ());
|
||||||
|
if (no_getpeereid ())
|
||||||
|
return 0;
|
||||||
|
|
||||||
connect_state (connect_credxchg);
|
connect_state (connect_credxchg);
|
||||||
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
||||||
if (!af_local_recv_secret () || !af_local_send_secret ()
|
if (!af_local_recv_secret () || !af_local_send_secret ()
|
||||||
|
@ -437,6 +443,25 @@ fhandler_socket::af_local_accept ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_socket::af_local_set_no_getpeereid ()
|
||||||
|
{
|
||||||
|
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (connect_state () != unconnected)
|
||||||
|
{
|
||||||
|
set_errno (EALREADY);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf ("no_getpeereid set");
|
||||||
|
no_getpeereid (true);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_socket::af_local_set_cred ()
|
fhandler_socket::af_local_set_cred ()
|
||||||
{
|
{
|
||||||
|
@ -461,6 +486,7 @@ fhandler_socket::af_local_copy (fhandler_socket *sock)
|
||||||
sock->sec_peer_pid = sec_peer_pid;
|
sock->sec_peer_pid = sec_peer_pid;
|
||||||
sock->sec_peer_uid = sec_peer_uid;
|
sock->sec_peer_uid = sec_peer_uid;
|
||||||
sock->sec_peer_gid = sec_peer_gid;
|
sock->sec_peer_gid = sec_peer_gid;
|
||||||
|
sock->no_getpeereid (no_getpeereid ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2303,6 +2329,11 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (no_getpeereid ())
|
||||||
|
{
|
||||||
|
set_errno (ENOTSUP);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (connect_state () != connected)
|
if (connect_state () != connected)
|
||||||
{
|
{
|
||||||
set_errno (ENOTCONN);
|
set_errno (ENOTCONN);
|
||||||
|
|
|
@ -452,12 +452,13 @@ details. */
|
||||||
CW_GETENT, CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID, CW_GETGRSID,
|
CW_GETENT, CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID, CW_GETGRSID,
|
||||||
CW_CYGNAME_FROM_WINNAME.
|
CW_CYGNAME_FROM_WINNAME.
|
||||||
276: Export ffsl, ffsll.
|
276: Export ffsl, ffsll.
|
||||||
|
277: Add setsockopt(SO_PEERCRED).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_API_MAJOR 0
|
#define CYGWIN_VERSION_API_MAJOR 0
|
||||||
#define CYGWIN_VERSION_API_MINOR 276
|
#define CYGWIN_VERSION_API_MINOR 277
|
||||||
|
|
||||||
/* There is also a compatibity version number associated with the
|
/* There is also a compatibity version number associated with the
|
||||||
shared memory regions. It is incremented when incompatible
|
shared memory regions. It is incremented when incompatible
|
||||||
|
|
|
@ -810,6 +810,25 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
|
||||||
fhandler_socket *fh = get (fd);
|
fhandler_socket *fh = get (fd);
|
||||||
if (!fh)
|
if (!fh)
|
||||||
__leave;
|
__leave;
|
||||||
|
|
||||||
|
/* Switch off the AF_LOCAL handshake and thus SO_PEERCRED handling
|
||||||
|
for AF_LOCAL/SOCK_STREAM sockets. This allows to handle special
|
||||||
|
situations in which connect is called before a listening socket
|
||||||
|
accepts connections.
|
||||||
|
FIXME: In the long run we should find a more generic solution which
|
||||||
|
doesn't require a blocking handshake in accept/connect to exchange
|
||||||
|
SO_PEERCRED credentials. */
|
||||||
|
if (level == SOL_SOCKET && optname == SO_PEERCRED)
|
||||||
|
{
|
||||||
|
if (optval || optlen
|
||||||
|
|| fh->get_addr_family () != AF_LOCAL
|
||||||
|
|| fh->get_socket_type () != SOCK_STREAM)
|
||||||
|
set_errno (EINVAL);
|
||||||
|
else
|
||||||
|
res = fh->af_local_set_no_getpeereid ();
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
/* Old applications still use the old WinSock1 IPPROTO_IP values. */
|
/* Old applications still use the old WinSock1 IPPROTO_IP values. */
|
||||||
if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES)
|
if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES)
|
||||||
optname = convert_ws1_ip_optname (optname);
|
optname = convert_ws1_ip_optname (optname);
|
||||||
|
|
Loading…
Reference in New Issue