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

📄 auth-pam.c

📁 the open vpn source code in linux
💻 C
📖 第 1 页 / 共 2 页
字号:
      context->background_pid = pid;      /* close our copy of child's socket */      close (fd[1]);      /* don't let future subprocesses inherit child socket */      if (fcntl (fd[0], F_SETFD, FD_CLOEXEC) < 0)	fprintf (stderr, "AUTH-PAM: Set FD_CLOEXEC flag on socket file descriptor failed\n");      /* wait for background child process to initialize */      status = recv_control (fd[0]);      if (status == RESPONSE_INIT_SUCCEEDED)	{	  context->foreground_fd = fd[0];	  return (openvpn_plugin_handle_t) context;	}    }  else    {      /*       * Background Process       */      /* close all parent fds except our socket back to parent */      close_fds_except (fd[1]);      /* Ignore most signals (the parent will receive them) */      set_signals ();      /* Daemonize if --daemon option is set. */      daemonize (envp);      /* execute the event loop */      pam_server (fd[1], argv[1], context->verb, &name_value_list);      close (fd[1]);      exit (0);      return 0; /* NOTREACHED */    } error:  if (context)    free (context);  return NULL;}OPENVPN_EXPORT intopenvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]){  struct auth_pam_context *context = (struct auth_pam_context *) handle;  if (type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY && context->foreground_fd >= 0)    {      /* get username/password from envp string array */      const char *username = get_env ("username", envp);      const char *password = get_env ("password", envp);      if (username && strlen (username) > 0 && password)	{	  if (send_control (context->foreground_fd, COMMAND_VERIFY) == -1	      || send_string (context->foreground_fd, username) == -1	      || send_string (context->foreground_fd, password) == -1)	    {	      fprintf (stderr, "AUTH-PAM: Error sending auth info to background process\n");	    }	  else	    {	      const int status = recv_control (context->foreground_fd);	      if (status == RESPONSE_VERIFY_SUCCEEDED)		return OPENVPN_PLUGIN_FUNC_SUCCESS;	      if (status == -1)		fprintf (stderr, "AUTH-PAM: Error receiving auth confirmation from background process\n");	    }	}    }  return OPENVPN_PLUGIN_FUNC_ERROR;}OPENVPN_EXPORT voidopenvpn_plugin_close_v1 (openvpn_plugin_handle_t handle){  struct auth_pam_context *context = (struct auth_pam_context *) handle;  if (DEBUG (context->verb))    fprintf (stderr, "AUTH-PAM: close\n");  if (context->foreground_fd >= 0)    {      /* tell background process to exit */      if (send_control (context->foreground_fd, COMMAND_EXIT) == -1)	fprintf (stderr, "AUTH-PAM: Error signaling background process to exit\n");      /* wait for background process to exit */      if (context->background_pid > 0)	waitpid (context->background_pid, NULL, 0);      close (context->foreground_fd);      context->foreground_fd = -1;    }  free (context);}OPENVPN_EXPORT voidopenvpn_plugin_abort_v1 (openvpn_plugin_handle_t handle){  struct auth_pam_context *context = (struct auth_pam_context *) handle;  /* tell background process to exit */  if (context->foreground_fd >= 0)    {      send_control (context->foreground_fd, COMMAND_EXIT);      close (context->foreground_fd);      context->foreground_fd = -1;    }}/* * PAM conversation function */static intmy_conv (int n, const struct pam_message **msg_array,	 struct pam_response **response_array, void *appdata_ptr){  const struct user_pass *up = ( const struct user_pass *) appdata_ptr;  struct pam_response *aresp;  int i;  int ret = PAM_SUCCESS;  *response_array = NULL;  if (n <= 0 || n > PAM_MAX_NUM_MSG)    return (PAM_CONV_ERR);  if ((aresp = calloc (n, sizeof *aresp)) == NULL)    return (PAM_BUF_ERR);  /* loop through each PAM-module query */  for (i = 0; i < n; ++i)    {      const struct pam_message *msg = msg_array[i];      aresp[i].resp_retcode = 0;      aresp[i].resp = NULL;      if (DEBUG (up->verb))	{	  fprintf (stderr, "AUTH-PAM: BACKGROUND: my_conv[%d] query='%s' style=%d\n",		   i,		   msg->msg ? msg->msg : "NULL",		   msg->msg_style);	}      if (up->name_value_list && up->name_value_list->len > 0)	{	  /* use name/value list match method */	  const struct name_value_list *list = up->name_value_list;	  int j;	  /* loop through name/value pairs */	  for (j = 0; j < list->len; ++j)	    {	      const char *match_name = list->data[j].name;	      const char *match_value = list->data[j].value;	      if (name_value_match (msg->msg, match_name))		{		  /* found name/value match */		  const char *return_value = NULL;		  if (DEBUG (up->verb))		    fprintf (stderr, "AUTH-PAM: BACKGROUND: name match found, query/match-string ['%s', '%s'] = '%s'\n",			     msg->msg,			     match_name,			     match_value);		  if (!strcmp (match_value, "USERNAME"))		    return_value = up->username;		  else if (!strcmp (match_value, "PASSWORD"))		    return_value = up->password;		  else		    return_value = match_value;		  aresp[i].resp = strdup (return_value);		  if (aresp[i].resp == NULL)		    ret = PAM_CONV_ERR;		  break;		}	    }	  if (j == list->len)	    ret = PAM_CONV_ERR;	}      else	{	  /* use PAM_PROMPT_ECHO_x hints */	  switch (msg->msg_style)	    {	    case PAM_PROMPT_ECHO_OFF:	      aresp[i].resp = strdup (up->password);	      if (aresp[i].resp == NULL)		ret = PAM_CONV_ERR;	      break;	    case PAM_PROMPT_ECHO_ON:	      aresp[i].resp = strdup (up->username);	      if (aresp[i].resp == NULL)		ret = PAM_CONV_ERR;	      break;	    case PAM_ERROR_MSG:	    case PAM_TEXT_INFO:	      break;	    default:	      ret = PAM_CONV_ERR;	      break;	    }	}    }  if (ret == PAM_SUCCESS)    *response_array = aresp;  return ret;}/* * Return 1 if authenticated and 0 if failed. * Called once for every username/password * to be authenticated. */static intpam_auth (const char *service, const struct user_pass *up){  struct pam_conv conv;  pam_handle_t *pamh = NULL;  int status = PAM_SUCCESS;  int ret = 0;  const int name_value_list_provided = (up->name_value_list && up->name_value_list->len > 0);  /* Initialize PAM */  conv.conv = my_conv;  conv.appdata_ptr = (void *)up;  status = pam_start (service, name_value_list_provided ? NULL : up->username, &conv, &pamh);  if (status == PAM_SUCCESS)    {      /* Call PAM to verify username/password */      status = pam_authenticate(pamh, 0);      if (status == PAM_SUCCESS)	status = pam_acct_mgmt (pamh, 0);      if (status == PAM_SUCCESS)	ret = 1;      /* Output error message if failed */      if (!ret)	{	  fprintf (stderr, "AUTH-PAM: BACKGROUND: user '%s' failed to authenticate: %s\n",		   up->username,		   pam_strerror (pamh, status));	}      /* Close PAM */      pam_end (pamh, status);          }  return ret;}/* * Background process -- runs with privilege. */static voidpam_server (int fd, const char *service, int verb, const struct name_value_list *name_value_list){  struct user_pass up;  int command;#if DLOPEN_PAM  static const char pam_so[] = "libpam.so";#endif  /*   * Do initialization   */  if (DEBUG (verb))    fprintf (stderr, "AUTH-PAM: BACKGROUND: INIT service='%s'\n", service);#if DLOPEN_PAM  /*   * Load PAM shared object   */  if (!dlopen_pam (pam_so))    {      fprintf (stderr, "AUTH-PAM: BACKGROUND: could not load PAM lib %s: %s\n", pam_so, dlerror());      send_control (fd, RESPONSE_INIT_FAILED);      goto done;    }#endif  /*   * Tell foreground that we initialized successfully   */  if (send_control (fd, RESPONSE_INIT_SUCCEEDED) == -1)    {      fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [1]\n");      goto done;    }  /*   * Event loop   */  while (1)    {      memset (&up, 0, sizeof (up));      up.verb = verb;      up.name_value_list = name_value_list;      /* get a command from foreground process */      command = recv_control (fd);      if (DEBUG (verb))	fprintf (stderr, "AUTH-PAM: BACKGROUND: received command code: %d\n", command);      switch (command)	{	case COMMAND_VERIFY:	  if (recv_string (fd, up.username, sizeof (up.username)) == -1	      || recv_string (fd, up.password, sizeof (up.password)) == -1)	    {	      fprintf (stderr, "AUTH-PAM: BACKGROUND: read error on command channel: code=%d, exiting\n",		       command);	      goto done;	    }	  if (DEBUG (verb))	    fprintf (stderr, "AUTH-PAM: BACKGROUND: USER/PASS: %s/%s\n",		     up.username, up.password);	  if (pam_auth (service, &up)) /* Succeeded */	    {	      if (send_control (fd, RESPONSE_VERIFY_SUCCEEDED) == -1)		{		  fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [2]\n");		  goto done;		}	    }	  else /* Failed */	    {	      if (send_control (fd, RESPONSE_VERIFY_FAILED) == -1)		{		  fprintf (stderr, "AUTH-PAM: BACKGROUND: write error on response socket [3]\n");		  goto done;		}	    }	  break;	case COMMAND_EXIT:	  goto done;	case -1:	  fprintf (stderr, "AUTH-PAM: BACKGROUND: read error on command channel\n");	  goto done;	default:	  fprintf (stderr, "AUTH-PAM: BACKGROUND: unknown command code: code=%d, exiting\n",		   command);	  goto done;	}    } done:#if DLOPEN_PAM  dlclose_pam ();#endif  if (DEBUG (verb))    fprintf (stderr, "AUTH-PAM: BACKGROUND: EXIT\n");  return;}

⌨️ 快捷键说明

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