⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cygserver.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* cygserver.cc   Copyright 2001, 2002 Red Hat Inc.   Written by Egor Duda <deo@logos-m.ru>This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. */#include "woutsup.h"#include <sys/types.h>#include <assert.h>#include <ctype.h>#include <errno.h>#include <getopt.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "cygerrno.h"#include "cygwin_version.h"#include "cygwin/cygserver.h"#include "cygwin/cygserver_process.h"#include "cygwin/cygserver_transport.h"// Version string.static const char version[] = "$Revision: 1.5 $";/* * Support function for the XXX_printf () macros in "woutsup.h". * Copied verbatim from "strace.cc". */static intgetfunc (char *in_dst, const char *func){  const char *p;  const char *pe;  char *dst = in_dst;  for (p = func; (pe = strchr (p, '(')); p = pe + 1)    if (isalnum ((int)pe[-1]) || pe[-1] == '_')      break;    else if (isspace ((int)pe[-1]))      {	pe--;	break;      }  if (!pe)    pe = strchr (func, '\0');  for (p = pe; p > func; p--)    if (p != pe && *p == ' ')      {	p++;	break;      }  if (*p == '*')    p++;  while (p < pe)    *dst++ = *p++;  *dst++ = ':';  *dst++ = ' ';  *dst = '\0';  return dst - in_dst;}/* * Support function for the XXX_printf () macros in "woutsup.h". */extern "C" void__cygserver__printf (const char *const function, const char *const fmt, ...){  const DWORD lasterror = GetLastError ();  const int lasterrno = errno;  va_list ap;  char *const buf = (char *) alloca (BUFSIZ);  assert (buf);  int len = 0;  if (function)    len += getfunc (buf, function);  va_start (ap, fmt);  len += vsnprintf (buf + len, BUFSIZ - len, fmt, ap);  va_end (ap);  len += snprintf (buf + len, BUFSIZ - len, "\n");  const int actual = (len > BUFSIZ ? BUFSIZ : len);  write (2, buf, actual);  errno = lasterrno;  SetLastError (lasterror);  return;}#ifdef DEBUGGINGint __stdcall__set_errno (const char *func, int ln, int val){  debug_printf ("%s:%d val %d", func, ln, val);  return _impure_ptr->_errno = val;}#endif /* DEBUGGING */GENERIC_MAPPING access_mapping;static BOOLsetup_privileges (){  BOOL rc, ret_val;  HANDLE hToken = NULL;  TOKEN_PRIVILEGES sPrivileges;  rc = OpenProcessToken (GetCurrentProcess () , TOKEN_ALL_ACCESS , &hToken) ;  if (!rc)    {      system_printf ("error opening process token (%lu)", GetLastError ());      ret_val = FALSE;      goto out;    }  rc = LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &sPrivileges.Privileges[0].Luid);  if (!rc)    {      system_printf ("error getting privilege luid (%lu)", GetLastError ());      ret_val = FALSE;      goto out;    }  sPrivileges.PrivilegeCount = 1 ;  sPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED ;  rc = AdjustTokenPrivileges (hToken, FALSE, &sPrivileges, 0, NULL, NULL) ;  if (!rc)    {      system_printf ("error adjusting privilege level. (%lu)",		     GetLastError ());      ret_val = FALSE;      goto out;    }  access_mapping.GenericRead = FILE_READ_DATA;  access_mapping.GenericWrite = FILE_WRITE_DATA;  access_mapping.GenericExecute = 0;  access_mapping.GenericAll = FILE_READ_DATA | FILE_WRITE_DATA;  ret_val = TRUE;out:  CloseHandle (hToken);  return ret_val;}intcheck_and_dup_handle (HANDLE from_process, HANDLE to_process,		      HANDLE from_process_token,		      DWORD access,		      HANDLE from_handle,		      HANDLE *to_handle_ptr, BOOL bInheritHandle = FALSE){  HANDLE local_handle = NULL;  int ret_val = EACCES;  if (from_process != GetCurrentProcess ())    {      if (!DuplicateHandle (from_process, from_handle,			    GetCurrentProcess (), &local_handle,			    0, bInheritHandle,			    DUPLICATE_SAME_ACCESS))	{	  system_printf ("error getting handle(%u) to server (%lu)",			 (unsigned int)from_handle, GetLastError ());	  goto out;	}    } else      local_handle = from_handle;  if (!wincap.has_security ())    assert (!from_process_token);  else    {      char sd_buf [1024];      PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR) &sd_buf;      DWORD bytes_needed;      PRIVILEGE_SET ps;      DWORD ps_len = sizeof (ps);      BOOL status;      if (!GetKernelObjectSecurity (local_handle,				    (OWNER_SECURITY_INFORMATION				     | GROUP_SECURITY_INFORMATION				     | DACL_SECURITY_INFORMATION),				    sd, sizeof (sd_buf), &bytes_needed))	{	  system_printf ("error getting handle SD (%lu)", GetLastError ());	  goto out;	}      MapGenericMask (&access, &access_mapping);      if (!AccessCheck (sd, from_process_token, access, &access_mapping,			&ps, &ps_len, &access, &status))	{	  system_printf ("error checking access rights (%lu)",			 GetLastError ());	  goto out;	}      if (!status)	{	  system_printf ("access to object denied");	  goto out;	}    }  if (!DuplicateHandle (from_process, from_handle,			to_process, to_handle_ptr,			access, bInheritHandle, 0))    {      system_printf ("error getting handle to client (%lu)", GetLastError ());      goto out;    }  // verbose: debug_printf ("Duplicated %p to %p", from_handle, *to_handle_ptr);  ret_val = 0; out:  if (local_handle && from_process != GetCurrentProcess ())    CloseHandle (local_handle);  return (ret_val);}/* * client_request_attach_tty::serve () */voidclient_request_attach_tty::serve (transport_layer_base *const conn,				  process_cache *){  assert (conn);  assert (!error_code ());  if (!wincap.has_security ())    {      syscall_printf ("operation only supported on systems with security");      error_code (EINVAL);      msglen (0);      return;    }  if (msglen () != sizeof (req))    {      syscall_printf ("bad request body length: expecting %lu bytes, got %lu",		      sizeof (req), msglen ());      error_code (EINVAL);      msglen (0);      return;    }  msglen (0);			// Until we fill in some fields.  // verbose: debug_printf ("pid %ld:(%p,%p) -> pid %ld",  //			    req.master_pid, req.from_master, req.to_master,  //			    req.pid);  // verbose: debug_printf ("opening process %ld", req.master_pid);  const HANDLE from_process_handle =    OpenProcess (PROCESS_DUP_HANDLE, FALSE, req.master_pid);  if (!from_process_handle)    {      system_printf ("error opening `from' process, error = %lu",		     GetLastError ());      error_code (EACCES);      return;    }  // verbose: debug_printf ("opening process %ld", req.pid);  const HANDLE to_process_handle =    OpenProcess (PROCESS_DUP_HANDLE, FALSE, req.pid);  if (!to_process_handle)    {      system_printf ("error opening `to' process, error = %lu",		     GetLastError ());      CloseHandle (from_process_handle);      error_code (EACCES);      return;    }  // verbose: debug_printf ("Impersonating client");  conn->impersonate_client ();  HANDLE token_handle = NULL;  // verbose: debug_printf ("about to open thread token");  const DWORD rc = OpenThreadToken (GetCurrentThread (),				    TOKEN_QUERY,				    TRUE,				    &token_handle);  // verbose: debug_printf ("opened thread token, rc=%lu", rc);  conn->revert_to_self ();  if (!rc)    {      system_printf ("error opening thread token, error = %lu",		     GetLastError ());      CloseHandle (from_process_handle);      CloseHandle (to_process_handle);      error_code (EACCES);      return;    }  // From this point on, a reply body is returned to the client.  const HANDLE from_master = req.from_master;  const HANDLE to_master = req.to_master;  req.from_master = NULL;  req.to_master = NULL;  msglen (sizeof (req));  if (from_master)    if (check_and_dup_handle (from_process_handle, to_process_handle,			      token_handle,			      GENERIC_READ,			      from_master,			      &req.from_master, TRUE) != 0)      {	system_printf ("error duplicating from_master handle, error = %lu",		       GetLastError ());	error_code (EACCES);      }  if (to_master)    if (check_and_dup_handle (from_process_handle, to_process_handle,			      token_handle,			      GENERIC_WRITE,			      to_master,			      &req.to_master, TRUE) != 0)      {	system_printf ("error duplicating to_master handle, error = %lu",		       GetLastError ());	error_code (EACCES);      }  CloseHandle (from_process_handle);  CloseHandle (to_process_handle);  CloseHandle (token_handle);  debug_printf ("%lu(%lu, %lu) -> %lu(%lu,%lu)",		req.master_pid, from_master, to_master,		req.pid, req.from_master, req.to_master);  return;}voidclient_request_get_version::serve (transport_layer_base *, process_cache *){  assert (!error_code ());  if (msglen ())    syscall_printf ("unexpected request body ignored: %lu bytes", msglen ());  msglen (sizeof (version));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -