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

📄 rpasswd-client.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	  continue;	}      else if (strncmp (cp, "reqcert", 7) == 0 && isspace ((int) cp[7]))	{	  char *p = &cp[7];	  while (isspace (*p))	    ++p;	  *reqcertp = parse_reqcert (p);	  continue;	}#ifdef DO_VERBOSE_OUTPUT      if (check_syntax)	{	  PRINTF (STD_HANDLE, _("Entry \"%s\" is not valid!\n"), cp);	  ++bad_entries;	}      else	PRINTF (ERR_HANDLE, _("Entry \"%s\" is not valid, ignored!\n"), cp);#endif    }  fclose (fp);  if (buf)    free (buf);#ifdef DO_VERBOSE_OUTPUT  if (check_syntax)    {      if (bad_entries)	{	  PRINTF (STD_HANDLE, _("Bad entries found.\n"));	  return 1;	}      if (!have_entries)	{	  PRINTF (STD_HANDLE, _("No entry found.\n"));	  return 1;	}    }#endif  if (!have_entries)    {#ifdef DO_VERBOSE_OUTPUT      if (verbose > 1)	PRINTF (STD_HANDLE, _("No entry found."));#endif      return 1;    }  return 0;}static intconnect_to_server (HANDLE const char *hostp, const char *portp, int family){#ifdef NI_WITHSCOPEID  const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;#else  const int niflags = NI_NUMERICHOST;#endif  struct addrinfo hints, *res, *res0;  int error;  int sock = -1;  memset (&hints, 0, sizeof (hints));  hints.ai_family = family;  hints.ai_socktype = SOCK_STREAM;  hints.ai_flags = AI_CANONNAME;  error = getaddrinfo (hostp, portp, &hints, &res0);  if (error)    {      if (error == EAI_NONAME)	{	  PRINTF (ERR_HANDLE,		  _		  ("Hostname or service not known for specified protocol\n"));	  return -1;	}      else if (error == EAI_SERVICE)	{	  /* if port cannot be resolved, try compiled in	     port number. If this works, don't abort here.  */	  char *cp;	  asprintf (&cp, "%d", RPASSWDD_PORT);	  error = getaddrinfo (hostp, cp, &hints, &res0);	  free (cp);	  if (error)	    {	      PRINTF (ERR_HANDLE, _("bad port: %s\n"), portp);	      return -1;	    }	}      else	{	  PRINTF (ERR_HANDLE, "%s: %s\n", hostp, gai_strerror (error));	  return -1;	}    }  for (res = res0; res; res = res->ai_next)    {      char hbuf[NI_MAXHOST];      if (getnameinfo (res->ai_addr, res->ai_addrlen,		       hbuf, sizeof (hbuf), NULL, 0, niflags) != 0)	strcpy (hbuf, "(invalid)");      switch (res->ai_family)	{	case AF_INET:	  {	    struct sockaddr_in s_in;	    memcpy (&s_in, res->ai_addr, sizeof (struct sockaddr_in));	    PRINTF (STD_HANDLE, _("Trying %s port %d...\r\n"),		    hbuf, ntohs (s_in.sin_port));	    break;	  }	case AF_INET6:	  {	    struct sockaddr_in6 s_in6;	    memcpy (&s_in6, res->ai_addr, sizeof (struct sockaddr_in));	    PRINTF (STD_HANDLE, _("Trying %s port %d...\r\n"),		    hbuf, ntohs (s_in6.sin6_port));	    break;	  }	default:	  PRINTF (STD_HANDLE, _("Trying %s...\r\n"), hbuf);	  break;	}      /* Create the socket.  */      sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol);      if (sock < 0)	continue;      if (connect (sock, res->ai_addr, res->ai_addrlen) < 0)	{	  if (getnameinfo (res->ai_addr, res->ai_addrlen,			   hbuf, sizeof (hbuf), NULL, 0, niflags) != 0)	    strcpy (hbuf, "(invalid)");	  PRINTF (ERR_HANDLE, _("connect to address %s: %s\n"), hbuf,		  strerror (errno));	  close (sock);	  sock = -1;	  continue;	}      PRINTF (STD_HANDLE, "\n");      break;    }  freeaddrinfo (res0);  return sock;}#ifdef USE_GNUTLS#include <gnutls/x509.h>#ifndef HAVE_GNUTLS_PK_ALGORITHM_GET_NAMEstatic const char *gnutls_pk_algorithm_get_name (gnutls_pk_algorithm algorithm){  if (algorithm == GNUTLS_PK_RSA)    return "RSA";  else if (algorithm == GNUTLS_PK_DSA)    return "DSA";  else    return "UNKNOWN";}#endif/* This function will print information about this session's peer * certificate. */static voidprint_x509_certificate_info (HANDLE gnutls_session session){  char dn[128];  size_t size;  unsigned int algo, bits;  time_t expiration_time, activation_time;  const gnutls_datum *cert_list;  unsigned int cert_list_size = 0;  gnutls_x509_crt cert;  /* This function only works for X.509 certificates.   */  if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)    return;  cert_list = gnutls_certificate_get_peers (session, &cert_list_size);  if (cert_list_size <= 0)    return;  PRINTF (STD_HANDLE, _("Server certificate info:\n"));  /* we only print information about the first certificate. */  gnutls_x509_crt_init (&cert);  gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER);  expiration_time = gnutls_x509_crt_get_expiration_time (cert);  activation_time = gnutls_x509_crt_get_activation_time (cert);  PRINTF (STD_HANDLE, _("  Certificate is valid since: %s"),			ctime (&activation_time));  PRINTF (STD_HANDLE, _("  Certificate expires: %s"),	  ctime (&expiration_time));  /* Extract some of the public key algorithm's parameters   */  algo = gnutls_x509_crt_get_pk_algorithm (cert, &bits);  PRINTF (STD_HANDLE, _("  Certificate public key: %s"),	  gnutls_pk_algorithm_get_name (algo));  /* Print the version of the X.509   * certificate.   */  PRINTF (STD_HANDLE, _("  Certificate version: #%d\n"),	  gnutls_x509_crt_get_version (cert));  size = sizeof (dn);  gnutls_x509_crt_get_dn (cert, dn, &size);  PRINTF (STD_HANDLE, _("  DN: %s\n"), dn);  size = sizeof (dn);  gnutls_x509_crt_get_issuer_dn (cert, dn, &size);  PRINTF (STD_HANDLE, _("  Issuer's DN: %s\n"), dn);  PRINTF (STD_HANDLE, "\n");  gnutls_x509_crt_deinit (cert);}static intstart_ssl (HANDLE long sock, int reqcert, int verbose, gnutls_session session,	   gnutls_certificate_credentials *cred){  gnutls_certificate_credentials xcred;  DIR *dir = opendir ("/etc/ssl/certs");  struct dirent *entry;  int ret;  /* Allow connections to servers that have OpenPGP keys as well. */  const int cert_type_priority[3] =    { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };  /* X509 stuff */  gnutls_certificate_allocate_credentials (&xcred);  /* sets the trusted cas files from /etc/ssl/certs and try to     add /etc/rpasswdd.pem (default from server). */  if (dir != NULL)    {      while ((entry = readdir (dir)) != NULL)	{	  /* Skip "." and ".." directory entries.  */	  if (strcmp (entry->d_name, ".") == 0 ||	      strcmp (entry->d_name, "..") == 0)	    continue;	  else	    {	      char srcfile[strlen ("/etc/ssl/certs") +			   strlen (entry->d_name) + 2];	      struct stat st;	      char *cp;	      /* create source and destination filename with full path.  */	      cp = stpcpy (srcfile, "/etc/ssl/certs");	      *cp++ = '/';	      strcpy (cp, entry->d_name);	      if (lstat (srcfile, &st) != 0)		continue;	      if (!S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode) &&		  !S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode))		{		  /* XXX error handling! */		  gnutls_certificate_set_x509_trust_file (xcred, srcfile,							  GNUTLS_X509_FMT_PEM);		}	    }	}      closedir (dir);    }  gnutls_certificate_set_x509_trust_file (xcred, "/etc/rpasswdd.pem",					  GNUTLS_X509_FMT_PEM);  *cred = xcred;  /* Use default priorities */  gnutls_set_default_priority (session);  gnutls_certificate_type_set_priority (session, cert_type_priority);  /* put the x509 credentials to the current session.  */  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);  gnutls_transport_set_ptr (session, (gnutls_transport_ptr) sock);  /* Perform the TLS handshake.  */  ret = gnutls_handshake (session);  if (ret < 0)    {      PRINTF (ERR_HANDLE, _("Handshake failed: %s\n"),	      gnutls_strerror (ret));      return E_SSL_FAILURE;    }  if (reqcert > 0 || verbose)    {      gnutls_kx_algorithm kx;      unsigned int verify_result = 0;      time_t now;      /* print the key exchange's algorithm name.  */      kx = gnutls_kx_get (session);#ifdef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS2      ret = gnutls_certificate_verify_peers2 (session, &verify_result);#else      ret = gnutls_certificate_verify_peers (session);      if (ret > 0)	verify_result = ret;#endif      if (ret < 0)	{	  PRINTF (ERR_HANDLE, _("TLS certificate error: %s\n"),		  gnutls_strerror (verify_result));	  return E_SSL_FAILURE;	}      /* Following two steps are optional and not required for         data exchange to be successful except the client couldn't verfiy         the server certificate.  */      if (verify_result || verbose)	{	  /* Get the cipher.  */	  PRINTF (STD_HANDLE, _("%s connection using %s-%s (%s)\n\n"),		  gnutls_protocol_get_name (gnutls_protocol_get_version					    (session)),		  gnutls_cipher_get_name (gnutls_cipher_get (session)),		  gnutls_mac_get_name (gnutls_mac_get (session)),		  gnutls_certificate_type_get_name		  (gnutls_certificate_type_get (session)));#if defined(IAM_PAM_MODULE)	  print_x509_certificate_info (pamh, session);#else	  print_x509_certificate_info (session);#endif	  if (verify_result & GNUTLS_CERT_SIGNER_NOT_FOUND)	    {	      PRINTF (ERR_HANDLE,		      _		      ("TLS authentication error: server certificate issuer is unknown.\n"));	      if (reqcert >= 2)		return E_SSL_FAILURE;	    }	  else if (verify_result & GNUTLS_CERT_INVALID)	    {	      PRINTF (ERR_HANDLE,		      _		      ("TLS authentication error: server certificate is NOT trusted.\n"));	      if (reqcert >= 2)		return E_SSL_FAILURE;	    }	}      now = time (NULL);      if (gnutls_certificate_activation_time_peers (session) > now)	{	  PRINTF (ERR_HANDLE,		  _("TLS authentication error: server certificate not yet activated.\n"));	  if (reqcert >= 2)	    return E_SSL_FAILURE;	}      if (gnutls_certificate_expiration_time_peers (session) < now)	{	  PRINTF (ERR_HANDLE,		  _("TLS authentication error: server certificate expired.\n"));	  if (reqcert >= 2)	    return E_SSL_FAILURE;	}    }  return 0;}#elsestatic intstart_ssl (HANDLE int sock, int reqcert, int verbose,	   SSL_CTX ** ctx, SSL ** ssl){  X509 *server_cert;  char *str;  SSL_METHOD *meth;  long verify_result;  int err;  SSLeay_add_ssl_algorithms ();  meth = SSLv23_client_method ();  SSL_load_error_strings ();  *ctx = SSL_CTX_new (meth);  if (*ctx == NULL)    {      PRINTF (ERR_HANDLE, ERR_error_string (ERR_get_error (), NULL));      return E_SSL_FAILURE;    }#if 0  /* This is only necessary if we configure a unusual path.     XXX Make this a program option.  */  if (!SSL_CTX_load_verify_locations (*ctx, NULL, "/etc/ssl/certs"))    {      PRINTF (ERR_HANDLE, _("error loading default verify locations: %s\n"),	      ERR_error_string (ERR_get_error (), NULL));      if (reqcert > 1)	return E_SSL_FAILURE;    }#endif  if (!SSL_CTX_set_default_verify_paths (*ctx))    {      PRINTF (ERR_HANDLE, _("error setting default verify path: %s\n"),	      ERR_error_string (ERR_get_error (), NULL));      if (reqcert > 1)	return E_SSL_FAILURE;    }  /* Now we have TCP conncetion. Start SSL negotiation. */  *ssl = SSL_new (*ctx);  if (*ssl == NULL)    {      PRINTF (ERR_HANDLE, ERR_error_string (ERR_get_error (), NULL));      return E_SSL_FAILURE;    }  SSL_set_fd (*ssl, sock);  err = SSL_connect (*ssl);  if (err < 1)    {      PRINTF (ERR_HANDLE, "SSL_connect: %s", ERR_error_string (err, NULL));      close (sock);      return E_SSL_FAILURE;    }  if (reqcert > 0 || verbose)    {      /* Get server's certificate (note: beware of dynamic allocation).  */      server_cert = SSL_get_peer_certificate (*ssl);      /* Verify severs certificate.  */      verify_result = SSL_get_verify_result (*ssl);      /* Following two steps are optional and not required for         data exchange to be successful except the client couldn't verfiy         the server certificate.  */      if (verify_result || verbose)	{	  /* Get the cipher.  */	  PRINTF (STD_HANDLE, _("SSL connection using %s\n\n"),		  SSL_get_cipher (*ssl));	  if (server_cert == NULL)	    {	      PRINTF (ERR_HANDLE, _("Server does not have a certificate?\n"));	      if (reqcert >= 3)		return E_SSL_FAILURE;	    }	  else	    {	      PRINTF (STD_HANDLE, _("Server certificate info:\n"));	      str = X509_NAME_oneline (X509_get_subject_name (server_cert),				       0, 0);	      if (str)		{		  PRINTF (STD_HANDLE, _("  DN: %s\n"), str);		  free (str);		}	      str = X509_NAME_oneline (X509_get_issuer_name (server_cert),				       0, 0);	      if (str)		{		  PRINTF (STD_HANDLE, _("  Issuer's DN: %s\n"), str);		  free (str);		}	      /* We could do all sorts of certificate verification stuff	         here before deallocating the certificate.  */	      PRINTF (STD_HANDLE, "\n");	    }	}      if ((verify_result = SSL_get_verify_result (*ssl)) != X509_V_OK)	{	  PRINTF (ERR_HANDLE, "Server certificate is not ok: %s!\n",		  X509_verify_cert_error_string (verify_result));	  if (reqcert >= 2)	    return E_SSL_FAILURE;	}      X509_free (server_cert);    }  return 0;}#endif

⌨️ 快捷键说明

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