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

📄 rpasswdd.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		dbg_log ("SSL connection using %s", SSL_get_cipher (ssl));#if 0	      /* Get client's certificate (note: beware of dynamic		 allocation) - opt */	      client_cert = SSL_get_peer_certificate (ssl);	      if (client_cert != NULL)		{		  printf ("Client certificate:\n");		  str = X509_NAME_oneline (X509_get_subject_name (client_cert),					   0, 0);		  CHK_NULL(str);		  printf ("\t subject: %s\n", str);		  free (str);		  str = X509_NAME_oneline (X509_get_issuer_name (client_cert),					   0, 0);		  CHK_NULL(str);		  printf ("\t issuer: %s\n", str);		  free (str);		  /* We could do all sorts of certificate verification		     stuff here before deallocating the certificate. */		  X509_free (client_cert);		}	      else		printf ("Client does not have certificate.\n");#endif	      /* Now read the request.  */	      errno = 0;	      if (TEMP_FAILURE_RETRY (SSL_read (ssl, &req, sizeof (req)))		  != sizeof (req))		{		  if (debug_level > 0)		    {		      if (errno == 0)			dbg_log (_("error while reading request: %s"),				 _("wrong data received"));		      else			dbg_log (_("error while reading request: %s"),				 strerror_r (errno, buf, sizeof (buf)));		    }		  close (fd);		  continue;		}#endif	      /* It should not be possible to crash the rpasswdd with		 a silly request (i.e., a terribly large key). We limit		 the size to 1kb for locale and username.  */	      if (req.locale_len < 0 || req.locale_len > 1024)		{		  if (debug_level > 0)		    dbg_log (_("locale length in request too long: %d"),			     req.locale_len);		  continue;		}	      else if (req.locale_len != 0)		{		  /* Get the locale.  */		  char localebuf[req.locale_len + 1];		  if (safe_read (ssl, localebuf, req.locale_len, 1)		      != req.locale_len)		    {		      if (debug_level > 0)			{			  char err_buf[256];			  if (errno == 0)			    dbg_log (_("error while reading request locale: %s"),				     _("wrong data received"));			  else			    dbg_log (_("error while reading request locale: %s"),				     strerror_r (errno, err_buf,						 sizeof (err_buf)));			}		      continue;		    }		  /* Don't assume the string is NUL-terminated */		  localebuf[req.locale_len] = '\0';		  if ((locale = strdup (localebuf)) == NULL)		    {		      dbg_log ("running out of memory!");		      continue;		    }		}	      else		locale = NULL;	      if (req.data_len < 0 || req.data_len > 1024)		{		  if (debug_level > 0)		    dbg_log (_("data length in request too long: %d"),			     req.data_len);		  if (locale)		    free (locale);		  continue;		}	      else if (req.data_len != 0)		{		  /* Get the data.  */		  char databuf[req.data_len + 1];		  if (safe_read (ssl, databuf, req.data_len, 1)		      != req.data_len)		    {		      if (debug_level > 0)			{			  char err_buf[256];			  if (errno == 0)			    dbg_log (_("error while reading request username: %s"),				     _("wrong data received"));			  else			    dbg_log (_("error while reading request username: %s"),				     strerror_r (errno, err_buf,						 sizeof (err_buf)));			}		      if (locale)			free (locale);		      continue;		    }		  /* Don't assume the string is NUL-terminated */		  databuf[req.data_len] = '\0';		  if ((username = strdup (databuf)) == NULL)		    {		      dbg_log ("running out of memory!");		      if (locale)			free (locale);		      continue;		    }		}	      else		{		  dbg_log (_("No username supplied"));		  if (locale)		    free (locale);		  continue;		}	      /* To avoid a DoS attack, fork at first and let the child		 handle the request.  */	      switch (fork ())		{		case 0:		  /* Child: get all the data and process it.  */		  {		    int ret = handle_request (ssl, &req, locale, username,					      program);		    close (fd);		    exit (ret);		    }		  break;		case -1:		  {		    char *cp;		    if (asprintf (&cp, "fork: %s", strerror (errno)) > 0)		      {			dbg_log (cp);			send_string (ssl, ERROR_MSG, cp);			free (cp);#ifdef USE_GNUTLS			/* do not wait for the peer to close the connection.  */			gnutls_bye (ssl, GNUTLS_SHUT_WR);			close (fd);			gnutls_deinit (ssl);#else			close (fd);			SSL_free (ssl);#endif			if (locale)			  free (locale);			free (username);		      }		  }		  break;		default:		  /* Parent: we are done.  */#ifdef USE_GNUTLS		  /* do not wait for the peer to close the connection.  */		  gnutls_bye (ssl, GNUTLS_SHUT_WR);		  close (fd);		  gnutls_deinit (ssl);#else		  close (fd);		  SSL_free (ssl);#endif		  if (locale)		    free (locale);		  free (username);		}	    }	}    }}/* Cleanup.  */static voidtermination_handler (int sig __attribute__ ((unused))){  close_sockets ();#ifdef USE_SLP  /* Remove from local SLP server.  */  if (use_slp)    deregister_slp ();#endif  /* Clean up pid file.  */  unlink (_PATH_RPASSWDDPID);  exit (EXIT_SUCCESS);}/* Make sure there are no zombies left.  */static voidsig_child (int sig __attribute__ ((unused))){  int st;  /* Clear all childs */  while (waitpid(-1, &st, WNOHANG) > 0)    ;}static voidinit_limits (void){  struct rlimit rlim;  /* Don't create a core file.  */  rlim.rlim_cur = rlim.rlim_max = 0;  setrlimit (RLIMIT_CORE, &rlim);  /* Set all limits to unlimited to avoid to run in any     problems later.  */  rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;  setrlimit (RLIMIT_AS, &rlim);  setrlimit (RLIMIT_CPU, &rlim);  setrlimit (RLIMIT_DATA, &rlim);  setrlimit (RLIMIT_FSIZE, &rlim);  setrlimit (RLIMIT_NOFILE, &rlim);  setrlimit (RLIMIT_RSS, &rlim);  setrlimit (RLIMIT_STACK, &rlim);}intmain (int argc, char **argv){  /* ipv4 and/or ipv6 binding.  */  int ipv4 = 0;  int ipv6 = 0;  int go_background = 1;  const char *program = "rpasswdd";  char *certificate = "/etc/rpasswdd.pem";  char *privatekey = "/etc/rpasswdd.pem";  int port = -1;#ifdef USE_SLP  int slp_timeout = 3600;  char *slp_descr = NULL;#endif#ifndef USE_GNUTLS  SSL_METHOD *meth;#endif  /* Set locale via LC_ALL.  */  setlocale (LC_ALL, "C");  /* Set the text message domain.  */  textdomain (PACKAGE);  /* Parse program arguments */  while (1)    {      int c;      int option_index = 0;      static struct option long_options[] =        {	  {"port",     required_argument, NULL, 'p'},	  {"debug",    no_argument,       NULL, 'd'},	  {"ipv4",     no_argument,       NULL, '4'},	  {"ipv6",     no_argument,       NULL, '6'},	  {"certificate", required_argument, NULL, 'c'},	  {"privatekey",  required_argument, NULL, 'k'},	  {"slp-descr",   required_argument, NULL, '\250'},	  {"slp-timeout", required_argument, NULL, '\251'},	  {"slp",      no_argument,       NULL, '\252'},          {"version",  no_argument,       NULL, '\255'},          {"usage",    no_argument,       NULL, '\254'},          {"help",     no_argument,       NULL, '\253'},          {NULL,       0,                 NULL, '\0'}        };      c = getopt_long (argc, argv, "46c:dk:p:", long_options,                       &option_index);      if (c == EOF)        break;      switch (c)        {	case '4':	  ipv4 = 1;	  break;	case '6':	  ipv6 = 1;	  break;	case 'c':	  certificate = optarg;	  break;	case 'k':	  privatekey = optarg;	  break;	case 'd':	  ++debug_level;	  go_background = 0;	  break;	case 'p':	  port = htons (atol (optarg));	  break;#ifdef USE_SLP	case '\250':	  slp_descr = optarg;	  break;	case '\251':	  slp_timeout = atol (optarg);	  break;	case '\252':	  use_slp = 1;	  break;#endif        case '\253':          print_help (program);          return 0;        case '\255':          print_version (program);          return 0;        case '\254':          print_usage (stdout, program);          return E_USAGE;        default:          print_error (program);          return E_BAD_ARG;        }    }  argc -= optind;  argv += optind;  if (argc != 0)    {      fprintf (stderr, _("%s: Too many arguments.\n"), program);      print_error (program);      return E_USAGE;    }  if (ipv4 == 0 && ipv6 == 0)    ipv4 = ipv6 = 1;  /* Check if we are already running. */  if (check_pid (_PATH_RPASSWDDPID))    error (EXIT_FAILURE, 0, _("already running"));#ifdef USE_GNUTLS  /* this must be called once in the program.  */  gnutls_global_init ();#else  /* Initialize SSL data. We need to do this before we go in     background, else we cannot read the PEM phass phrase.  */  SSL_load_error_strings ();  SSLeay_add_ssl_algorithms ();  meth = SSLv23_server_method ();  ctx = SSL_CTX_new (meth);  if (!ctx)    {      dbg_log (ERR_error_string (ERR_get_error (), NULL));      return E_SSL_FAILURE;    }  if (SSL_CTX_use_certificate_file (ctx, certificate, SSL_FILETYPE_PEM) <= 0)    {      dbg_log ("Loading certificate (%s): %s", certificate,	       ERR_error_string (ERR_get_error (), NULL));      return E_SSL_FAILURE;    }  if (SSL_CTX_use_PrivateKey_file (ctx, privatekey, SSL_FILETYPE_PEM) <= 0)    {      dbg_log ("Loading privatekey (%s): %s", privatekey,	       ERR_error_string (ERR_get_error (), NULL));      return E_SSL_FAILURE;    }  if (!SSL_CTX_check_private_key (ctx))    {      dbg_log (ERR_error_string (ERR_get_error (), NULL));      return E_SSL_FAILURE;    }#endif  /* Behave like a daemon.  */  if (go_background)    {      int i;      if (fork ())        exit (0);      for (i = 0; i < getdtablesize (); i++)        close (i);      if (fork ())        exit (0);      setsid ();      if (chdir ("/") < 0)	dbg_log ("chdir(\"/\") failed: %s", strerror (errno));      openlog (program, LOG_CONS | LOG_ODELAY, LOG_DAEMON);      if (write_pid (_PATH_RPASSWDDPID) < 0)        dbg_log ("%s: %s", _PATH_RPASSWDDPID, strerror (errno));      /* Ignore job control signals.  */      signal (SIGTTOU, SIG_IGN);      signal (SIGTTIN, SIG_IGN);      signal (SIGTSTP, SIG_IGN);    }  /* Install sig child handler to get ride of zombies.  */  signal (SIGCHLD, sig_child);  /* Ignore "File size limit exceeded" signals.  */  signal (SIGXFSZ, SIG_IGN);  /* We don't support SIGHUP yet.  */  signal (SIGHUP, SIG_IGN);  signal (SIGINT,  termination_handler);  signal (SIGPIPE, SIG_IGN);  signal (SIGQUIT, termination_handler);  signal (SIGTERM, termination_handler);  /* Set the limits to a usefull value.  */  init_limits ();  /* If port was not specified on commandline, try at first a lookup     in the service database, if this fails, use the compiled in     default port.  */  if (port == -1)    {      struct servent *serv = getservbyname ("rpasswd", "tcp");      if (serv)	port = serv->s_port;      else	port = htons (RPASSWDD_PORT);    }  /* Init databases.  */  server_init (port, ipv4, ipv6);#ifdef USE_SLP  /* Register at local SLP server.  */  if (use_slp)    register_slp (ntohs(port), slp_timeout, slp_descr);#endif  /* Handle incoming requests.  */#ifdef USE_GNUTLS  server_run (certificate, privatekey, program);#else  server_run (program);#endif  return E_SUCCESS;}

⌨️ 快捷键说明

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