* fhandler.h (class fhandler_socket): Declare new method

set_socketpair_eids.
	* fhandler_socket.cc (fhandler_socket::set_socketpair_eids): New method.
	(fhandler_socket::dup): Duplicate sec_pipe if necessary.
	(fhandler_socket::listen): Only create sec_pipe if named pipes are
	available. Initialized sec_peer_pid to 0 as on Linux.
	(fhandler_socket::connect): Only run eid credential transaction if
	named pipes are available.  Fake otherwise. Initialized sec_peer_pid
	to 0 as on Linux.
	(fhandler_socket::accept): Ditto.
	(fhandler_socket::close): Move closing sec_pipe handle from here...
	(fhandler_socket::~fhandler_socket): ... to here.
	* net.cc (socketpair): Set eid credentials by calling
	fhandler_socket::set_socketpair_eids() on both socket ends.
	* wincap.h (wincaps::has_named_pipes): New element.
	* wincap.cc: Implement above element throughout.
This commit is contained in:
Corinna Vinschen 2005-02-28 13:11:50 +00:00
parent 882a0c8507
commit 496337c9a5
6 changed files with 132 additions and 36 deletions

View File

@ -1,3 +1,22 @@
2005-02-28 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_socket): Declare new method
set_socketpair_eids.
* fhandler_socket.cc (fhandler_socket::set_socketpair_eids): New method.
(fhandler_socket::dup): Duplicate sec_pipe if necessary.
(fhandler_socket::listen): Only create sec_pipe if named pipes are
available. Initialized sec_peer_pid to 0 as on Linux.
(fhandler_socket::connect): Only run eid credential transaction if
named pipes are available. Fake otherwise. Initialized sec_peer_pid
to 0 as on Linux.
(fhandler_socket::accept): Ditto.
(fhandler_socket::close): Move closing sec_pipe handle from here...
(fhandler_socket::~fhandler_socket): ... to here.
* net.cc (socketpair): Set eid credentials by calling
fhandler_socket::set_socketpair_eids() on both socket ends.
* wincap.h (wincaps::has_named_pipes): New element.
* wincap.cc: Implement above element throughout.
2005-02-26 Christopher Faylor <cgf@timesys.com>
* sigproc.cc (_pinfo::set_ctty): Move function

View File

@ -365,7 +365,10 @@ class fhandler_socket: public fhandler_base
__uid32_t sec_peer_uid;
__gid32_t sec_peer_gid;
char *eid_pipe_name (char *buf);
public:
void set_socketpair_eids (void);
private:
struct _WSAPROTOCOL_INFOA *prot_info_ptr;
char *sun_path;
struct status_flags

View File

@ -60,6 +60,14 @@ fhandler_socket::eid_pipe_name (char *buf)
return buf;
}
void
fhandler_socket::set_socketpair_eids (void)
{
sec_pid = sec_peer_pid = getpid ();
sec_uid = sec_peer_uid = geteuid32 ();
sec_gid = sec_peer_gid = getegid32 ();
}
/* cygwin internal: map sockaddr into internet domain address */
static int
get_inet_addr (const struct sockaddr *in, int inlen,
@ -154,6 +162,9 @@ fhandler_socket::~fhandler_socket ()
cfree (prot_info_ptr);
if (sun_path)
cfree (sun_path);
/* Close eid credentials pipe handle. */
if (sec_pipe != INVALID_HANDLE_VALUE)
CloseHandle (sec_pipe);
}
char *fhandler_socket::get_proc_fd_name (char *buf)
@ -341,12 +352,37 @@ fhandler_socket::fixup_after_exec ()
int
fhandler_socket::dup (fhandler_base *child)
{
HANDLE nh;
debug_printf ("here");
fhandler_socket *fhs = (fhandler_socket *) child;
fhs->addr_family = addr_family;
if (get_addr_family () == AF_LOCAL)
fhs->set_sun_path (get_sun_path ());
fhs->set_socket_type (get_socket_type ());
if (get_addr_family () == AF_LOCAL)
{
fhs->set_sun_path (get_sun_path ());
if (get_socket_type () == SOCK_STREAM)
{
fhs->sec_pid = sec_pid;
fhs->sec_uid = sec_uid;
fhs->sec_gid = sec_gid;
fhs->sec_peer_pid = sec_peer_pid;
fhs->sec_peer_uid = sec_peer_uid;
fhs->sec_peer_gid = sec_peer_gid;
if (sec_pipe != INVALID_HANDLE_VALUE)
{
if (!DuplicateHandle (hMainProc, sec_pipe, hMainProc, &nh, 0,
TRUE, DUPLICATE_SAME_ACCESS))
{
system_printf ("!DuplicateHandle(%x) failed, %E", sec_pipe);
__seterrno ();
return -1;
}
else
fhs->sec_pipe = nh;
}
}
}
fhs->connect_state (connect_state ());
if (winsock2_active)
@ -378,12 +414,13 @@ fhandler_socket::dup (fhandler_base *child)
having winsock called from fhandler_base and it creates only
inheritable sockets which is wrong for winsock2. */
HANDLE nh;
if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
!winsock2_active, DUPLICATE_SAME_ACCESS))
{
system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
__seterrno ();
if (fhs->sec_pipe != INVALID_HANDLE_VALUE)
CloseHandle (fhs->sec_pipe);
return -1;
}
VerifyHandle (nh);
@ -630,20 +667,30 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
}
/* eid credential transaction. */
struct ucred in = { getpid (), geteuid32 (), getegid32 () };
struct ucred out = { (pid_t) -1, (__uid32_t) -1, (__gid32_t) -1 };
DWORD bytes = 0;
if (CallNamedPipe(eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
&in, sizeof in, &out, sizeof out, &bytes, 1000))
{
debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
out.pid, out.uid, out.gid);
sec_peer_pid = out.pid;
sec_peer_uid = out.uid;
sec_peer_gid = out.gid;
}
else
debug_printf ("Receiving eid credentials failed: %E");
if (wincap.has_named_pipes ())
{
struct ucred in = { getpid (), geteuid32 (), getegid32 () };
struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
DWORD bytes = 0;
if (CallNamedPipe(eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
&in, sizeof in, &out, sizeof out, &bytes, 1000))
{
debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
out.pid, out.uid, out.gid);
sec_peer_pid = out.pid;
sec_peer_uid = out.uid;
sec_peer_gid = out.gid;
}
else
debug_printf ("Receiving eid credentials failed: %E");
}
else /* 9x */
{
/* Incorrect but wrong pid at least doesn't break getpeereid. */
sec_peer_pid = getpid ();
sec_peer_uid = geteuid32 ();
sec_peer_gid = getegid32 ();
}
}
err = WSAGetLastError ();
@ -669,10 +716,13 @@ fhandler_socket::listen (int backlog)
sec_pid = getpid ();
sec_uid = geteuid32 ();
sec_gid = getegid32 ();
sec_peer_pid = (pid_t) -1;
sec_peer_pid = (pid_t) 0;
sec_peer_uid = (__uid32_t) -1;
sec_peer_gid = (__gid32_t) -1;
sec_pipe =
/* A listening socket can call listen again, but that shouldn't
result in trying to create another pipe. */
if (wincap.has_named_pipes () && sec_pipe == INVALID_HANDLE_VALUE)
sec_pipe =
CreateNamedPipe (eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
@ -692,7 +742,7 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
bool secret_check_failed = false;
bool in_progress = false;
struct ucred in = { sec_pid, sec_uid, sec_gid };
struct ucred out = { (pid_t) -1, (__uid32_t) -1, (__gid32_t) -1 };
struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
/* Allows NULL peer and len parameters. */
struct sockaddr_in peer_dummy;
@ -747,21 +797,31 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
}
/* eid credential transaction. */
DWORD bytes = 0;
bool ret = ConnectNamedPipe (sec_pipe, NULL);
if (ret || GetLastError () == ERROR_PIPE_CONNECTED)
if (wincap.has_named_pipes ())
{
if (!ReadFile (sec_pipe, &out, sizeof out, &bytes, NULL))
debug_printf ("Receiving eid credentials failed: %E");
DWORD bytes = 0;
bool ret = ConnectNamedPipe (sec_pipe, NULL);
if (ret || GetLastError () == ERROR_PIPE_CONNECTED)
{
if (!ReadFile (sec_pipe, &out, sizeof out, &bytes, NULL))
debug_printf ("Receiving eid credentials failed: %E");
else
debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
out.pid, out.uid, out.gid);
if (!WriteFile (sec_pipe, &in, sizeof in, &bytes, NULL))
debug_printf ("Sending eid credentials failed: %E");
DisconnectNamedPipe (sec_pipe);
}
else
debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
out.pid, out.uid, out.gid);
if (!WriteFile (sec_pipe, &in, sizeof in, &bytes, NULL))
debug_printf ("Sending eid credentials failed: %E");
DisconnectNamedPipe (sec_pipe);
debug_printf ("Connecting the eid credential pipe failed: %E");
}
else /* 9x */
{
/* Incorrect but wrong pid at least doesn't break getpeereid. */
out.pid = sec_pid;
out.uid = sec_uid;
out.gid = sec_gid;
}
else
debug_printf ("Connecting the eid credential pipe failed: %E");
}
if ((SOCKET) res == INVALID_SOCKET)
@ -1392,10 +1452,6 @@ fhandler_socket::close ()
setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
(const char *)&linger, sizeof linger);
/* Close eid credentials pipe handle. */
if (sec_pipe != INVALID_HANDLE_VALUE)
CloseHandle (sec_pipe);
while ((res = closesocket (get_socket ())) != 0)
{
if (WSAGetLastError () != WSAEWOULDBLOCK)

View File

@ -2198,6 +2198,8 @@ socketpair (int family, int type, int protocol, int *sb)
((fhandler_socket *) sb0)->set_addr_family (family);
((fhandler_socket *) sb0)->set_socket_type (type);
((fhandler_socket *) sb0)->connect_state (connected);
if (family == AF_LOCAL && type == SOCK_STREAM)
((fhandler_socket *) sb0)->set_socketpair_eids ();
cygheap_fdnew sb1 (sb0, false);
@ -2207,6 +2209,8 @@ socketpair (int family, int type, int protocol, int *sb)
((fhandler_socket *) sb1)->set_addr_family (family);
((fhandler_socket *) sb1)->set_socket_type (type);
((fhandler_socket *) sb1)->connect_state (connected);
if (family == AF_LOCAL && type == SOCK_STREAM)
((fhandler_socket *) sb1)->set_socketpair_eids ();
sb[0] = sb0;
sb[1] = sb1;

View File

@ -42,6 +42,7 @@ static NO_COPY wincaps wincap_unknown = {
has_move_file_ex:false,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:false,
@ -90,6 +91,7 @@ static NO_COPY wincaps wincap_95 = {
has_move_file_ex:false,
has_negative_pids:true,
has_unreliable_pipes:true,
has_named_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:false,
@ -138,6 +140,7 @@ static NO_COPY wincaps wincap_95osr2 = {
has_move_file_ex:false,
has_negative_pids:true,
has_unreliable_pipes:true,
has_named_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:false,
@ -186,6 +189,7 @@ static NO_COPY wincaps wincap_98 = {
has_move_file_ex:false,
has_negative_pids:true,
has_unreliable_pipes:true,
has_named_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:true,
@ -234,6 +238,7 @@ static NO_COPY wincaps wincap_98se = {
has_move_file_ex:false,
has_negative_pids:true,
has_unreliable_pipes:true,
has_named_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:true,
@ -282,6 +287,7 @@ static NO_COPY wincaps wincap_me = {
has_move_file_ex:false,
has_negative_pids:true,
has_unreliable_pipes:true,
has_named_pipes:false,
has_try_enter_critical_section:false,
has_raw_devices:false,
has_valid_processorlevel:true,
@ -330,6 +336,7 @@ static NO_COPY wincaps wincap_nt3 = {
has_move_file_ex:true,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:true,
has_try_enter_critical_section:false,
has_raw_devices:true,
has_valid_processorlevel:true,
@ -378,6 +385,7 @@ static NO_COPY wincaps wincap_nt4 = {
has_move_file_ex:true,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:true,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
@ -426,6 +434,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_move_file_ex:true,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:true,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
@ -474,6 +483,7 @@ static NO_COPY wincaps wincap_2000 = {
has_move_file_ex:true,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:true,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
@ -522,6 +532,7 @@ static NO_COPY wincaps wincap_xp = {
has_move_file_ex:true,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:true,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,
@ -570,6 +581,7 @@ static NO_COPY wincaps wincap_2003 = {
has_move_file_ex:true,
has_negative_pids:false,
has_unreliable_pipes:false,
has_named_pipes:true,
has_try_enter_critical_section:true,
has_raw_devices:true,
has_valid_processorlevel:true,

View File

@ -43,6 +43,7 @@ struct wincaps
unsigned has_move_file_ex : 1;
unsigned has_negative_pids : 1;
unsigned has_unreliable_pipes : 1;
unsigned has_named_pipes : 1;
unsigned has_try_enter_critical_section : 1;
unsigned has_raw_devices : 1;
unsigned has_valid_processorlevel : 1;
@ -105,6 +106,7 @@ public:
bool IMPLEMENT (has_move_file_ex)
bool IMPLEMENT (has_negative_pids)
bool IMPLEMENT (has_unreliable_pipes)
bool IMPLEMENT (has_named_pipes)
bool IMPLEMENT (has_try_enter_critical_section)
bool IMPLEMENT (has_raw_devices)
bool IMPLEMENT (has_valid_processorlevel)