* fhandler.h (fhandler_socket::eid_connect): Make private.
(fhandler_socket::set_connect_secret): Ditto. (fhandler_socket::get_connect_secret): Ditto. (fhandler_socket::create_secret_event): Ditto. Remove secret argument. (fhandler_socket::check_peer_secret_event): Ditto. (fhandler_socket::signal_secret_event): Make private. (fhandler_socket::close_secret_event): Ditto. (fhandler_socket::sec_event_accept): New private method. (fhandler_socket::sec_event_connect): Ditto. (fhandler_socket::af_local_connect): New public method. * fhandler_socket.cc: Use 'struct sockaddr' and 'struct sockaddr_in' rather than just 'sockaddr' and 'sockaddr_in' throughout. (fhandler_socket::eid_connect): Drop AF_LOCAL/SOCK_STREAM test. (fhandler_socket::create_secret_event): Remove secret argument. Always use connect_secret instead. (fhandler_socket::check_peer_secret_event): Ditto. (fhandler_socket::sec_event_connect): New method, combining entire secret event handshake on connect side. (fhandler_socket::af_local_connect): New method, combining secret event handshake and eid credential transaction on connect side, to be called from select. (fhandler_socket::sec_event_accept): New method, combining entire secret event handshake on accept side. (fhandler_socket::connect): Drop secret, use connect_secret instead. Move entire secret event handshake to sec_event_connect. (fhandler_socket::accept): Move entire secret event handshake to sec_event_accept. * select.cc (set_bits): Just call af_local_connect here.
This commit is contained in:
		| @@ -1,3 +1,34 @@ | |||||||
|  | 2005-03-23  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* fhandler.h (fhandler_socket::eid_connect): Make private. | ||||||
|  | 	(fhandler_socket::set_connect_secret): Ditto. | ||||||
|  | 	(fhandler_socket::get_connect_secret): Ditto. | ||||||
|  | 	(fhandler_socket::create_secret_event): Ditto. Remove secret argument. | ||||||
|  | 	(fhandler_socket::check_peer_secret_event): Ditto. | ||||||
|  | 	(fhandler_socket::signal_secret_event): Make private. | ||||||
|  | 	(fhandler_socket::close_secret_event): Ditto. | ||||||
|  | 	(fhandler_socket::sec_event_accept): New private method. | ||||||
|  | 	(fhandler_socket::sec_event_connect): Ditto. | ||||||
|  | 	(fhandler_socket::af_local_connect): New public method. | ||||||
|  | 	* fhandler_socket.cc: Use 'struct sockaddr' and 'struct sockaddr_in' | ||||||
|  | 	rather than just 'sockaddr' and 'sockaddr_in' throughout. | ||||||
|  | 	(fhandler_socket::eid_connect): Drop AF_LOCAL/SOCK_STREAM test. | ||||||
|  | 	(fhandler_socket::create_secret_event): Remove secret argument. | ||||||
|  | 	Always use connect_secret instead. | ||||||
|  | 	(fhandler_socket::check_peer_secret_event): Ditto. | ||||||
|  | 	(fhandler_socket::sec_event_connect): New method, combining entire | ||||||
|  | 	secret event handshake on connect side. | ||||||
|  | 	(fhandler_socket::af_local_connect): New method, combining secret | ||||||
|  | 	event handshake and eid credential transaction on connect side, to | ||||||
|  | 	be called from select. | ||||||
|  | 	(fhandler_socket::sec_event_accept): New method, combining entire | ||||||
|  | 	secret event handshake on accept side. | ||||||
|  | 	(fhandler_socket::connect): Drop secret, use connect_secret instead. | ||||||
|  | 	Move entire secret event handshake to sec_event_connect. | ||||||
|  | 	(fhandler_socket::accept): Move entire secret event handshake to | ||||||
|  | 	sec_event_accept. | ||||||
|  | 	* select.cc (set_bits): Just call af_local_connect here. | ||||||
|  |  | ||||||
| 2005-03-23  Christopher Faylor  <cgf@timesys.com> | 2005-03-23  Christopher Faylor  <cgf@timesys.com> | ||||||
|  |  | ||||||
| 	* include/cygwin/version.h: Change coment for most recent API version | 	* include/cygwin/version.h: Change coment for most recent API version | ||||||
|   | |||||||
| @@ -376,8 +376,8 @@ class fhandler_socket: public fhandler_base | |||||||
|   bool eid_recv (void); |   bool eid_recv (void); | ||||||
|   bool eid_send (void); |   bool eid_send (void); | ||||||
|   void eid_accept (void); |   void eid_accept (void); | ||||||
|  public: |  | ||||||
|   void eid_connect (void); |   void eid_connect (void); | ||||||
|  |  public: | ||||||
|   void set_socketpair_eids (void); |   void set_socketpair_eids (void); | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
| @@ -458,12 +458,19 @@ class fhandler_socket: public fhandler_base | |||||||
|   int get_socket_type () {return type;} |   int get_socket_type () {return type;} | ||||||
|   void set_sun_path (const char *path); |   void set_sun_path (const char *path); | ||||||
|   char *get_sun_path () {return sun_path;} |   char *get_sun_path () {return sun_path;} | ||||||
|  |  | ||||||
|  |  private: | ||||||
|   void set_connect_secret (); |   void set_connect_secret (); | ||||||
|   void get_connect_secret (char*); |   void get_connect_secret (char*); | ||||||
|   HANDLE create_secret_event (int *secret = NULL); |   HANDLE create_secret_event (); | ||||||
|   int check_peer_secret_event (struct sockaddr_in *peer, int *secret = NULL); |   int check_peer_secret_event (struct sockaddr_in *peer); | ||||||
|   void signal_secret_event (); |   void signal_secret_event (); | ||||||
|   void close_secret_event (); |   void close_secret_event (); | ||||||
|  |   int sec_event_accept (int, struct sockaddr_in *); | ||||||
|  |   int sec_event_connect (struct sockaddr_in *peer); | ||||||
|  |  public: | ||||||
|  |   int af_local_connect (void); | ||||||
|  |  | ||||||
|   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); |   int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); | ||||||
|   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); |   int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1))); | ||||||
|   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); |   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2))); | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ get_inet_addr (const struct sockaddr *in, int inlen, | |||||||
|  |  | ||||||
|   if (in->sa_family == AF_INET) |   if (in->sa_family == AF_INET) | ||||||
|     { |     { | ||||||
|       *out = * (sockaddr_in *)in; |       *out = * (struct sockaddr_in *)in; | ||||||
|       *outlen = inlen; |       *outlen = inlen; | ||||||
|       return 1; |       return 1; | ||||||
|     } |     } | ||||||
| @@ -100,7 +100,7 @@ get_inet_addr (const struct sockaddr *in, int inlen, | |||||||
|       memset (buf, 0, sizeof buf); |       memset (buf, 0, sizeof buf); | ||||||
|       if (ReadFile (fh, buf, 128, &len, 0)) |       if (ReadFile (fh, buf, 128, &len, 0)) | ||||||
| 	{ | 	{ | ||||||
| 	  sockaddr_in sin; | 	  struct sockaddr_in sin; | ||||||
| 	  sin.sin_family = AF_INET; | 	  sin.sin_family = AF_INET; | ||||||
| 	  sscanf (buf + strlen (SOCKET_COOKIE), "%hu %08x-%08x-%08x-%08x", | 	  sscanf (buf + strlen (SOCKET_COOKIE), "%hu %08x-%08x-%08x-%08x", | ||||||
| 		  &sin.sin_port, | 		  &sin.sin_port, | ||||||
| @@ -238,10 +238,6 @@ fhandler_socket::eid_send (void) | |||||||
| void | void | ||||||
| fhandler_socket::eid_connect (void) | fhandler_socket::eid_connect (void) | ||||||
| { | { | ||||||
|   /* This test allows to keep select.cc clean from boring implementation |  | ||||||
|      details. */ |  | ||||||
|   if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM) |  | ||||||
|     return; |  | ||||||
|   debug_printf ("eid_connect called"); |   debug_printf ("eid_connect called"); | ||||||
|   bool orig_async_io, orig_is_nonblocking; |   bool orig_async_io, orig_is_nonblocking; | ||||||
|   eid_setblocking (orig_async_io, orig_is_nonblocking); |   eid_setblocking (orig_async_io, orig_is_nonblocking); | ||||||
| @@ -306,7 +302,7 @@ fhandler_socket::get_connect_secret (char* buf) | |||||||
| } | } | ||||||
|  |  | ||||||
| HANDLE | HANDLE | ||||||
| fhandler_socket::create_secret_event (int* secret) | fhandler_socket::create_secret_event () | ||||||
| { | { | ||||||
|   struct sockaddr_in sin; |   struct sockaddr_in sin; | ||||||
|   int sin_len = sizeof (sin); |   int sin_len = sizeof (sin); | ||||||
| @@ -321,7 +317,7 @@ fhandler_socket::create_secret_event (int* secret) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   char event_name[CYG_MAX_PATH]; |   char event_name[CYG_MAX_PATH]; | ||||||
|   secret_event_name (event_name, sin.sin_port, secret ?: connect_secret); |   secret_event_name (event_name, sin.sin_port, connect_secret); | ||||||
|   secret_event = CreateEvent (&sec_all, FALSE, FALSE, event_name); |   secret_event = CreateEvent (&sec_all, FALSE, FALSE, event_name); | ||||||
|  |  | ||||||
|   if (!secret_event) |   if (!secret_event) | ||||||
| @@ -354,12 +350,12 @@ fhandler_socket::close_secret_event () | |||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| fhandler_socket::check_peer_secret_event (struct sockaddr_in* peer, int* secret) | fhandler_socket::check_peer_secret_event (struct sockaddr_in *peer) | ||||||
| { | { | ||||||
|  |  | ||||||
|   char event_name[CYG_MAX_PATH]; |   char event_name[CYG_MAX_PATH]; | ||||||
|  |  | ||||||
|   secret_event_name (event_name, peer->sin_port, secret ?: connect_secret); |   secret_event_name (event_name, peer->sin_port, connect_secret); | ||||||
|   HANDLE ev = CreateEvent (&sec_all_nih, FALSE, FALSE, event_name); |   HANDLE ev = CreateEvent (&sec_all_nih, FALSE, FALSE, event_name); | ||||||
|   if (!ev) |   if (!ev) | ||||||
|     debug_printf("create event %E"); |     debug_printf("create event %E"); | ||||||
| @@ -377,6 +373,78 @@ fhandler_socket::check_peer_secret_event (struct sockaddr_in* peer, int* secret) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | fhandler_socket::sec_event_connect (struct sockaddr_in *peer) | ||||||
|  | { | ||||||
|  |   bool secret_check_failed = false; | ||||||
|  |   struct sockaddr_in sin; | ||||||
|  |   int siz = sizeof sin; | ||||||
|  |  | ||||||
|  |   debug_printf ("sec_event_connect called"); | ||||||
|  |   if (!peer) | ||||||
|  |     { | ||||||
|  |       if (::getpeername (get_socket (), (struct sockaddr *) &sin, &siz)) | ||||||
|  |         goto err; | ||||||
|  |       peer = &sin; | ||||||
|  |     } | ||||||
|  |   if (!create_secret_event ()) | ||||||
|  |     secret_check_failed = true; | ||||||
|  |   if (!secret_check_failed && !check_peer_secret_event (peer)) | ||||||
|  |     { | ||||||
|  |       debug_printf ("accept from unauthorized server"); | ||||||
|  |       secret_check_failed = true; | ||||||
|  |     } | ||||||
|  |   if (!secret_check_failed) | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|  | err: | ||||||
|  |   close_secret_event (); | ||||||
|  |   closesocket (get_socket ()); | ||||||
|  |   WSASetLastError (WSAECONNREFUSED); | ||||||
|  |   set_winsock_errno (); | ||||||
|  |   return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Called from select().  It combines the secret event handshake and | ||||||
|  |    the eid credential transaction into one call.  This keeps implementation | ||||||
|  |    details from select. */ | ||||||
|  | int | ||||||
|  | fhandler_socket::af_local_connect (void) | ||||||
|  | { | ||||||
|  |   if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM) | ||||||
|  |     return 0; | ||||||
|  |   int ret = sec_event_connect (NULL); | ||||||
|  |   if (!ret) | ||||||
|  |     eid_connect (); | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | fhandler_socket::sec_event_accept (int sock, struct sockaddr_in *peer) | ||||||
|  | { | ||||||
|  |   bool secret_check_failed = false; | ||||||
|  |  | ||||||
|  |   debug_printf ("sec_event_accept called"); | ||||||
|  |  | ||||||
|  |   if (!create_secret_event ()) | ||||||
|  |     secret_check_failed = true; | ||||||
|  |  | ||||||
|  |   if (!secret_check_failed | ||||||
|  |       && !check_peer_secret_event (peer)) | ||||||
|  |     { | ||||||
|  |       debug_printf ("connect from unauthorized client"); | ||||||
|  |       secret_check_failed = true; | ||||||
|  |     } | ||||||
|  |   if (secret_check_failed) | ||||||
|  |     { | ||||||
|  |       close_secret_event (); | ||||||
|  |       closesocket (sock); | ||||||
|  |       set_errno (ECONNABORTED); | ||||||
|  |       return -1; | ||||||
|  |     } | ||||||
|  |   return sock; | ||||||
|  | } | ||||||
|  |  | ||||||
| void | void | ||||||
| fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id) | fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id) | ||||||
| { | { | ||||||
| @@ -687,16 +755,14 @@ int | |||||||
| fhandler_socket::connect (const struct sockaddr *name, int namelen) | fhandler_socket::connect (const struct sockaddr *name, int namelen) | ||||||
| { | { | ||||||
|   int res = -1; |   int res = -1; | ||||||
|   bool secret_check_failed = false; |  | ||||||
|   bool in_progress = false; |   bool in_progress = false; | ||||||
|   sockaddr_in sin; |   struct sockaddr_in sin; | ||||||
|   int secret [4]; |  | ||||||
|   DWORD err; |   DWORD err; | ||||||
|  |  | ||||||
|   if (!get_inet_addr (name, namelen, &sin, &namelen, secret)) |   if (!get_inet_addr (name, namelen, &sin, &namelen, connect_secret)) | ||||||
|     return -1; |     return -1; | ||||||
|  |  | ||||||
|   res = ::connect (get_socket (), (sockaddr *) &sin, namelen); |   res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen); | ||||||
|  |  | ||||||
|   if (!res) |   if (!res) | ||||||
|     err = 0; |     err = 0; | ||||||
| @@ -723,34 +789,6 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) | |||||||
|  |  | ||||||
|   if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM) |   if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM) | ||||||
|     { |     { | ||||||
|       if (!res || in_progress) |  | ||||||
| 	{ |  | ||||||
| 	  if (!create_secret_event (secret)) |  | ||||||
| 	    { |  | ||||||
| 	      secret_check_failed = true; |  | ||||||
| 	    } |  | ||||||
| 	  else if (in_progress) |  | ||||||
| 	    signal_secret_event (); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|       if (!secret_check_failed && !res) |  | ||||||
| 	{ |  | ||||||
| 	  if (!check_peer_secret_event (&sin, secret)) |  | ||||||
| 	    { |  | ||||||
| 	      debug_printf ("accept from unauthorized server"); |  | ||||||
| 	      secret_check_failed = true; |  | ||||||
| 	    } |  | ||||||
|        } |  | ||||||
|  |  | ||||||
|       if (secret_check_failed) |  | ||||||
| 	{ |  | ||||||
| 	  close_secret_event (); |  | ||||||
| 	  if (res) |  | ||||||
| 	    closesocket (res); |  | ||||||
| 	  set_errno (ECONNREFUSED); |  | ||||||
| 	  res = -1; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|       /* Prepare eid credential transaction. */ |       /* Prepare eid credential transaction. */ | ||||||
|       sec_pid = getpid (); |       sec_pid = getpid (); | ||||||
|       sec_uid = geteuid32 (); |       sec_uid = geteuid32 (); | ||||||
| @@ -759,6 +797,9 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) | |||||||
|       sec_peer_uid = (__uid32_t) -1; |       sec_peer_uid = (__uid32_t) -1; | ||||||
|       sec_peer_gid = (__gid32_t) -1; |       sec_peer_gid = (__gid32_t) -1; | ||||||
|  |  | ||||||
|  |       if (!res) | ||||||
|  | 	res = sec_event_connect (&sin); | ||||||
|  |  | ||||||
|       if (!res) |       if (!res) | ||||||
|         { |         { | ||||||
| 	  /* eid credential transaction.  If connect is in progress, | 	  /* eid credential transaction.  If connect is in progress, | ||||||
| @@ -803,7 +844,6 @@ int | |||||||
| fhandler_socket::accept (struct sockaddr *peer, int *len) | fhandler_socket::accept (struct sockaddr *peer, int *len) | ||||||
| { | { | ||||||
|   int res = -1; |   int res = -1; | ||||||
|   bool secret_check_failed = false; |  | ||||||
|  |  | ||||||
|   /* Allows NULL peer and len parameters. */ |   /* Allows NULL peer and len parameters. */ | ||||||
|   struct sockaddr_in peer_dummy; |   struct sockaddr_in peer_dummy; | ||||||
| @@ -827,27 +867,7 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) | |||||||
|  |  | ||||||
|   if ((SOCKET) res != INVALID_SOCKET && get_addr_family () == AF_LOCAL |   if ((SOCKET) res != INVALID_SOCKET && get_addr_family () == AF_LOCAL | ||||||
|       && get_socket_type () == SOCK_STREAM) |       && get_socket_type () == SOCK_STREAM) | ||||||
|     { |     res = sec_event_accept (res, (struct sockaddr_in *) peer); | ||||||
| 	if (!create_secret_event ()) |  | ||||||
| 	  secret_check_failed = true; |  | ||||||
|  |  | ||||||
|       if (!secret_check_failed) |  | ||||||
| 	{ |  | ||||||
| 	  if (!check_peer_secret_event ((struct sockaddr_in*) peer)) |  | ||||||
| 	    { |  | ||||||
| 	      debug_printf ("connect from unauthorized client"); |  | ||||||
| 	      secret_check_failed = true; |  | ||||||
| 	    } |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|       if (secret_check_failed) |  | ||||||
| 	{ |  | ||||||
| 	  close_secret_event (); |  | ||||||
| 	  closesocket (res); |  | ||||||
| 	  set_errno (ECONNABORTED); |  | ||||||
| 	  return -1; |  | ||||||
| 	} |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   if ((SOCKET) res == INVALID_SOCKET) |   if ((SOCKET) res == INVALID_SOCKET) | ||||||
|     set_winsock_errno (); |     set_winsock_errno (); | ||||||
| @@ -1256,7 +1276,7 @@ int | |||||||
| fhandler_socket::sendto (const void *ptr, size_t len, int flags, | fhandler_socket::sendto (const void *ptr, size_t len, int flags, | ||||||
| 			 const struct sockaddr *to, int tolen) | 			 const struct sockaddr *to, int tolen) | ||||||
| { | { | ||||||
|   sockaddr_in sin; |   struct sockaddr_in sin; | ||||||
|  |  | ||||||
|   if (to && !get_inet_addr (to, tolen, &sin, &tolen)) |   if (to && !get_inet_addr (to, tolen, &sin, &tolen)) | ||||||
|     return SOCKET_ERROR; |     return SOCKET_ERROR; | ||||||
|   | |||||||
| @@ -338,11 +338,10 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds, | |||||||
|       UNIX_FD_SET (me->fd, writefds); |       UNIX_FD_SET (me->fd, writefds); | ||||||
|       if (me->except_on_write && (sock = me->fh->is_socket ())) |       if (me->except_on_write && (sock = me->fh->is_socket ())) | ||||||
| 	{ | 	{ | ||||||
| 	  /* eid credential transaction on successful non-blocking connect. | 	  /* Special AF_LOCAL handling. */ | ||||||
| 	     Since the read bit indicates an error, don't start transaction | 	  if (!me->read_ready && sock->connect_state () == connect_pending | ||||||
| 	     if it's set. */ | 	      && sock->af_local_connect () && me->read_selected) | ||||||
| 	  if (!me->read_ready && sock->connect_state () == connect_pending) | 	    UNIX_FD_SET (me->fd, readfds); | ||||||
| 	    sock->eid_connect (); |  | ||||||
| 	  sock->connect_state (connected); | 	  sock->connect_state (connected); | ||||||
| 	} | 	} | ||||||
|       ready++; |       ready++; | ||||||
| @@ -354,8 +353,10 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds, | |||||||
| 	  UNIX_FD_SET (me->fd, writefds); | 	  UNIX_FD_SET (me->fd, writefds); | ||||||
| 	  if ((sock = me->fh->is_socket ())) | 	  if ((sock = me->fh->is_socket ())) | ||||||
| 	    { | 	    { | ||||||
| 	      if (!me->read_ready && sock->connect_state () == connect_pending) | 	      /* Special AF_LOCAL handling. */ | ||||||
| 	        sock->eid_connect (); | 	      if (!me->read_ready && sock->connect_state () == connect_pending | ||||||
|  | 		  && sock->af_local_connect () && me->read_selected) | ||||||
|  | 		UNIX_FD_SET (me->fd, readfds); | ||||||
| 	      sock->connect_state (connected); | 	      sock->connect_state (connected); | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user