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

📄 rpasswd-client.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2002, 2003, 2004, 2005 Thorsten Kukuk   Author: Thorsten Kukuk <kukuk@suse.de>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License version 2 as   published by the Free Software Foundation.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software Foundation,   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#include <ctype.h>#include <netdb.h>#include <sys/socket.h>#include <sys/types.h>#ifdef HAVE_DIRENT_H#include <dirent.h>#endif#ifdef USE_SLP#include <slp.h>#endif#ifdef USE_GNUTLSstatic intstart_request (HANDLE gnutls_session ssl, char *username, int admin_mode){  request_header req;  char *locale = getenv ("LANG");  int ret;  if (admin_mode)    req.request = START_ADMIN;  else    req.request = START;  req.version = RPASSWD_VERSION;  req.data_len = strlen (username) + 1;  if (locale)    req.locale_len = strlen (locale) + 1;  else    req.locale_len = 0;  if ((ret = gnutls_record_send (ssl, &req, sizeof (request_header))) <= 0)    {      if (ret == 0)	PRINTF (ERR_HANDLE, _("error while sending start request: %s\n"),		_("Peer has closed the TLS connection"));      else	PRINTF (ERR_HANDLE, _("error while sending start request: %s\n"),		gnutls_strerror (ret));      return -1;    }  if (locale)    {      if ((ret = gnutls_record_send (ssl, locale, req.locale_len)) <= 0)	{	  if (ret == 0)	    PRINTF (ERR_HANDLE, _("error while sending locale data: %s\n"),		    _("Peer has closed the TLS connection"));	  else	    PRINTF (ERR_HANDLE, _("error while sending locale data: %s\n"),		    gnutls_strerror (ret));	  return -1;	}    }  if ((ret = gnutls_record_send (ssl, username, req.data_len)) <= 0)    {      if (ret == 0)	PRINTF (ERR_HANDLE, _("error while sending username: %s\n"),		_("Peer has closed the TLS connection"));      else	PRINTF (ERR_HANDLE, _("error while sending username: %s\n"),		gnutls_strerror (ret));      return -1;    }  return 0;}static intsend_string (HANDLE gnutls_session ssl, u_int32_t retval, const char *str){  int ret;  conv_header resp;  resp.retval = retval;  if (str == NULL)    resp.data_len = 0;  else    resp.data_len = strlen (str) + 1;  if ((ret = gnutls_record_send (ssl, &resp, sizeof (resp))) <= 0)    {      if (ret == 0)	PRINTF (ERR_HANDLE, _("error while sending string: %s\n"),		_("Peer has closed the TLS connection"));      else	PRINTF (ERR_HANDLE, _("error while sending string: %s\n"),		gnutls_strerror (ret));      return E_FAILURE;    }  if (str)    {      if ((ret = gnutls_record_send (ssl, str, resp.data_len)) <= 0)	{	  if (ret == 0)	    PRINTF (ERR_HANDLE, _("error while sending string: %s\n"),		    _("Peer has closed the TLS connection"));	  else	    PRINTF (ERR_HANDLE, _("error while sending string: %s\n"),		    gnutls_strerror (ret));	  return E_FAILURE;	}    }  return E_SUCCESS;}#elsestatic intstart_request (SSL *ssl, char *username, int admin_mode){  request_header req;  char *locale = getenv ("LANG");  if (admin_mode)    req.request = START_ADMIN;  else    req.request = START;  req.version = RPASSWD_VERSION;  req.data_len = strlen (username) + 1;  if (locale)    req.locale_len = strlen (locale) + 1;  else    req.locale_len = 0;  if (SSL_write (ssl, &req, sizeof (request_header)) !=      sizeof (request_header))    return -1;  if (locale)    if (SSL_write (ssl, locale, req.locale_len) != req.locale_len)      return -1;  if (SSL_write (ssl, username, req.data_len) != req.data_len)    return -1;  return 0;}static intsend_string (SSL *ssl, u_int32_t ret, const char *str){  conv_header resp;  resp.retval = ret;  if (str == NULL)    resp.data_len = 0;  else    resp.data_len = strlen (str) + 1;  if (TEMP_FAILURE_RETRY (SSL_write (ssl, &resp, sizeof (resp)))      != sizeof (resp))    return E_FAILURE;  if (str)    if (TEMP_FAILURE_RETRY (SSL_write (ssl, str, resp.data_len))	!= resp.data_len)      return E_FAILURE;  return E_SUCCESS;}#endif#ifdef USE_SLP/* Ask SLP server for rpasswd service.  */struct slpcb{  char *srvurl;  SLPError err;  struct slpcb *next;  char *hostp;  char *portp;  char *descr;};static voidfree_slpcb (struct slpcb *cb){  struct slpcb *tcb;  free (cb->srvurl);  cb = cb->next;  while (cb)    {      tcb = cb;      cb = cb->next;      free (tcb->srvurl);      if (tcb->descr)	free (tcb->descr);      free (tcb);    }}static voidparse_slpcb (struct slpcb *cb){#define NEEDLE "://"  size_t needle_length = strlen (NEEDLE);  cb->hostp = strstr (cb->srvurl, NEEDLE);  if (cb->hostp == NULL || strlen (cb->hostp) < needle_length + 1)    return;  cb->hostp += needle_length;  cb->portp = strchr (cb->hostp, ':');  if (cb->portp)    {      char *cp;      cb->portp[0] = '\0';      cb->portp += 1;      cp = cb->portp;      while (isdigit (*cp))	cp++;      if (*cp != '\0')	*cp = '\0';    }}static SLPBooleanMySLPSrvURLCallback (SLPHandle hslp __attribute__ ((unused)),		     const char *srvurl,		     unsigned short lifetime __attribute__ ((unused)),		     SLPError errcode, void *cookie){  struct slpcb *cb = (struct slpcb *) cookie;  if (errcode == SLP_OK)    {      if (cb->srvurl != NULL)	{	  struct slpcb *cbt = malloc (sizeof (struct slpcb));	  if (cbt == NULL)	    return SLP_FALSE;	  cbt->srvurl = cb->srvurl;	  cbt->hostp = cb->hostp;	  cbt->portp = cb->portp;	  cbt->err = cb->err;	  cbt->next = cb->next;	  cb->next = cbt;	  cb->descr = NULL;	}      cb->srvurl = strdup (srvurl);      parse_slpcb (cb);      cb->err = SLP_OK;      return SLP_TRUE;    }  else if (errcode != SLP_LAST_CALL)    cb->err = errcode;  return SLP_FALSE;		/* We don't wan't to be called again.  */}static SLPBooleanMySLPAttrCallback (SLPHandle hslp __attribute__ ((unused)),		   const char *attrlist, SLPError errcode, void *cookie){  char **descr = (char **) cookie;  if (errcode == SLP_OK)    {      char *cp = strstr (attrlist, "(description=");      if (cp == NULL)	return SLP_FALSE;      *descr = strdup (cp + 13);      cp = strchr (*descr, ')');      if (cp != NULL)	*cp = '\0';    }  return SLP_FALSE;}static intquery_slp (HANDLE char **hostp, char **portp, char **descrp){  struct slpcb *cb, callbackres = { NULL, 0, NULL, NULL, NULL, NULL };  SLPError err;  SLPHandle hslp;  *hostp = NULL;  *portp = NULL;  *descrp = NULL;  PRINTF (STD_HANDLE, _("Searching a server...\n"));  err = SLPOpen ("en", SLP_FALSE, &hslp);  if (err != SLP_OK)    {      PRINTF (ERR_HANDLE, _("Error opening SLP handle: %i.\n"), err);      return err;    }  err = SLPFindSrvs (hslp, "rpasswdd", 0, 0,		     MySLPSrvURLCallback, &callbackres);  /* err may contain an error code that occurred as the slp library     _prepared_ to make the call.  */  if (err != SLP_OK || callbackres.err != SLP_OK)    {      PRINTF (STD_HANDLE, _("No service found with SLP.\n"));      return -1;    }  cb = &callbackres;  while (cb != NULL)    {      char *buf;      asprintf (&buf, "service:rpasswdd://%s:%s/", cb->hostp,		cb->portp ? : "774");      err = SLPFindAttrs (hslp, buf, "", "",	/* use configured scopes */			  MySLPAttrCallback, &(cb->descr));      free (buf);      if (err != SLP_OK)	{	  PRINTF (STD_HANDLE,		  _("Error while searching for SLP description.\n"));	  return -1;	}      cb = cb->next;    }  /* Now that we're done using slp, close the slp handle */  SLPClose (hslp);  cb = &callbackres;#if defined(SELECT_SRVURL)  if (cb->next != NULL)		/* Only if we have more than one entry.  */    {      /* Ask the user which one to use.  */      struct slpcb *tcb = &callbackres;      int choice = 0;		/* index of the user's choice.  */      char response[20];	/* string to hold the user's response.  */      int i = 0;      printf (_("\nPlease select a server:\n"));      while (tcb != NULL)	{	  ++i;	  printf ("[%2d] %s", i, tcb->hostp);	  if (tcb->portp)	    printf (_(" (port %s)"), tcb->portp);	  if (tcb->descr)	    printf (" - %s", tcb->descr);	  fputs ("\n", stdout);	  tcb = tcb->next;	}      while ((choice < 1) || (choice > i))	{	  char *cp;	  printf (_("Enter number of choice [1-%d]: "), i);	  fflush (stdin);	  cp = fgets (response, sizeof (response), stdin);	  fflush (stdin);	  if (cp == NULL)	    choice = 0;	  else	    choice = strtol (response, NULL, 10);	}      printf ("\n");      for (i = 0; i < (choice - 1); i++)	cb = cb->next;    }#endif  if (cb->hostp != NULL)    {      *hostp = strdup (cb->hostp);      if (cb->portp)	*portp = strdup (cb->portp);      if (cb->descr)	*descrp = strdup (cb->descr);      free_slpcb (&callbackres);      return 0;    }  free_slpcb (&callbackres);  return -1;}#endifstatic intparse_reqcert (const char *str){  if (strcmp (str, "never") == 0)    return 0;  else if (strcmp (str, "allow") == 0)    return 1;  else if (strcmp (str, "try") == 0)    return 2;  else if (strcmp (str, "demand") == 0 || strcmp (str, "hard") == 0)    return 3;  /* If we cannot parse it, use saftest mode.  */  return 3;}/* Load the config file (/etc/rpasswd.conf)  */static intload_config (const char *configfile, char **hostp, char **portp, int *reqcertp#ifdef DO_VERBOSE_OUTPUT	     , int verbose, int check_syntax#endif  ){  FILE *fp;  char *buf = NULL;  size_t buflen = 0;  int have_entries = 0;		/* # of entries we found in config file */#ifdef DO_VERBOSE_OUTPUT  int bad_entries = 0;#endif  fp = fopen (configfile, "r");  if (NULL == fp)    return 1;#ifdef DO_VERBOSE_OUTPUT  if (verbose > 1)    PRINTF (STD_HANDLE, _("parsing config file"));#endif  while (!feof (fp))    {      char *tmp, *cp;#if defined(HAVE_GETLINE)      ssize_t n = getline (&buf, &buflen, fp);#elif defined (HAVE_GETDELIM)      ssize_t n = getdelim (&buf, &buflen, '\n', fp);#else      ssize_t n;      if (buf == NULL)	{	  buflen = 8096;	  buf = malloc (buflen);	}      buf[0] = '\0';      fgets (buf, buflen - 1, fp);      if (buf != NULL)	n = strlen (buf);      else	n = 0;#endif /* HAVE_GETLINE / HAVE_GETDELIM */      cp = buf;      if (n < 1)	break;      tmp = strchr (cp, '#');	/* remove comments */      if (tmp)	*tmp = '\0';      while (isspace ((int) *cp))	/* remove spaces and tabs */	++cp;      if (*cp == '\0')		/* ignore empty lines */	continue;      if (cp[strlen (cp) - 1] == '\n')	cp[strlen (cp) - 1] = '\0';#ifdef DO_VERBOSE_OUTPUT      if (verbose > 1)	PRINTF (STD_HANDLE, "%s %s", _("Trying entry:"), cp);      if (check_syntax)	PRINTF (STD_HANDLE, "%s %s\n", _("Trying entry:"), cp);#endif      if (strncmp (cp, "server", 6) == 0 && isspace ((int) cp[6]))	{	  if (hostp != NULL)	    {	      char tmpserver[MAXHOSTNAMELEN + 1];	      if (sscanf (cp, "server %s", tmpserver) == 1)		*hostp = strdup (tmpserver);	    }	  continue;	}      else if (strncmp (cp, "port", 4) == 0 && isspace ((int) cp[4]))	{	  if (portp != NULL)	    {	      char tmpport[30];	      if (sscanf (cp, "port %s", tmpport) == 1)		*portp = strdup (tmpport);	    }

⌨️ 快捷键说明

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