Exemplo n.º 1
0
/*
 * Checks for completed auth requests, returns amount of requests handled.
 * The function is called only from the main thread.
 */
int pam_poll(void)
{
	struct pam_auth_request *request;
	int count = 0;

	while (pam_first_taken_slot != pam_first_free_slot) {
		request = &pam_auth_queue[pam_first_taken_slot];

		if (request->status == PAM_STATUS_IN_PROGRESS) {
			/* When still-in-progress slot is found there is no need to continue
			 * the loop since all further requests will be in progress too.
			 */
			break;
		}

		if (is_valid_socket(request)) {
			pam_auth_finish(request);
		}

		count++;
		pam_first_taken_slot = (pam_first_taken_slot + 1) % PAM_REQUEST_QUEUE_SIZE;
	}

	return count;
}
Exemplo n.º 2
0
int
assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2])
{
  int rc;

  rc = _assuan_new_context (r_ctx);
  if (!rc)
    {
      assuan_context_t ctx = *r_ctx;
      const char *s;
      unsigned long ul;

      ctx->is_server = 1;
#ifdef HAVE_W32_SYSTEM
      /* MS Windows has so many different types of handle that one
         needs to tranlsate them at many place forth and back.  Also
         make sure that the file descriptors are in binary mode.  */
      setmode (filedes[0], O_BINARY);
      setmode (filedes[1], O_BINARY);
      ctx->inbound.fd  = (void*)_get_osfhandle (filedes[0]);
      ctx->outbound.fd = (void*)_get_osfhandle (filedes[1]);
#else
      s = getenv ("_assuan_connection_fd");
      if (s && *s && is_valid_socket (s) )
        {
          /* Well, we are called with an bi-directional file
             descriptor.  Prepare for using sendmsg/recvmsg.  In this
             case we ignore the passed file descriptors. */
          ctx->inbound.fd  = ctx->outbound.fd = atoi (s);
          _assuan_init_uds_io (ctx);
          ctx->deinit_handler = _assuan_uds_deinit;
        }
      else if (filedes && filedes[0] != ASSUAN_INVALID_FD 
               && filedes[1] != ASSUAN_INVALID_FD )
        {
          /* Standard pipe server. */
          ctx->inbound.fd  = filedes[0];
          ctx->outbound.fd = filedes[1];
        }
      else
        {
          _assuan_release_context (*r_ctx);
          *r_ctx = NULL;
          return ASSUAN_Problem_Starting_Server;
        }
#endif
      ctx->pipe_mode = 1;

      s = getenv ("_assuan_pipe_connect_pid");
      if (s && (ul=strtoul (s, NULL, 10)) && ul)
        ctx->pid = (pid_t)ul;
      else
        ctx->pid = (pid_t)-1;

    }
  return rc;
}
Exemplo n.º 3
0
int
server_switch(void)
{
  int ret_val, i, cmd = 0;
  fd_set rd, wr, ex, fds_mask;
  FD_ZERO(&rd);
  FD_ZERO(&wr);
  FD_ZERO(&ex);
  fds_mask = server_mask;
  cmd = 0;
  if (purpose_table[SessionManager] != NULL) {
    FD_SET(0, &fds_mask);
    FD_SET(purpose_table[SessionManager]->socket, &fds_mask);
  }
  while (1) {
    do {
      if (purpose_table[MenuServer] != NULL) {
        FD_SET(purpose_table[MenuServer]->socket, &fds_mask);
      }
      rd = fds_mask;
      ret_val = select(FD_SETSIZE, (void *) &rd, (void *) 0, (void *) 0, (void *) 0);
      if (ret_val == -1) {
        /* perror ("Select in switch"); */
        return -1;
      }
      for(i=0; i<2; i++) {
        if (is_valid_socket(&server[i])
            && (FD_ISSET(server[i].socket, &rd)))
          fricas_accept_connection(server+i);
      }
    } while (purpose_table[SessionManager] == NULL);
    FD_SET(purpose_table[SessionManager]->socket, &fds_mask);
    if (FD_ISSET(purpose_table[SessionManager]->socket, &rd)) {
      cmd = get_int(purpose_table[SessionManager]);
      return cmd;
    }
    if (FD_ISSET(0, &rd)) {
      return CallInterp;
    }
    if (purpose_table[MenuServer] != NULL &&
        (FD_ISSET(purpose_table[MenuServer]->socket, &rd))) {
      cmd = get_int(purpose_table[MenuServer]);
      return cmd;
    }
  }
}
Exemplo n.º 4
0
/*
 * The authentication thread function.
 * Performs scanning the queue for new requests and calling PAM for them.
 */
static void* pam_auth_worker(void *arg)
{
	int current_slot = pam_first_taken_slot;
	struct pam_auth_request *request;

	while (true) {

		/* Wait for new data in the queue */
		pthread_mutex_lock(&pam_queue_tail_mutex);

		while (current_slot == pam_first_free_slot) {
			pthread_cond_wait(&pam_data_available, &pam_queue_tail_mutex);
		}

		pthread_mutex_unlock(&pam_queue_tail_mutex);

		log_debug("pam_auth_worker(): processing slot %d", current_slot);

		/* We have at least one request in the queue */
		request = &pam_auth_queue[current_slot];
		current_slot = (current_slot + 1) % PAM_REQUEST_QUEUE_SIZE;

		/* If the socket is already in the wrong state or reused then ignore it.
		 * This check is not safe and should not be trusted (the socket state
		 * might change exactly after it), but it helps to quickly filter out invalid
		 * sockets and thus save some time.
		 */
		if (!is_valid_socket(request)) {
			log_debug("pam_auth_worker(): invalid socket in slot %d", current_slot);
			request->status = PAM_STATUS_FAILED;
			continue;
		}

		if (pam_check_passwd(request)) {
			request->status = PAM_STATUS_SUCCESS;
		} else {
			request->status = PAM_STATUS_FAILED;
		}

		log_debug("pam_auth_worker(): authorization completed, status=%d", request->status);
	}

	return NULL;
}
Exemplo n.º 5
0
int
sock_accept_connection(int purpose)
{
  fd_set rd;
  int ret_val, i, p;
  if (getenv("SPADNUM") == NULL) return -1;
  while (1) {
    rd = server_mask;
    ret_val = sselect(FD_SETSIZE, (fd_set *)&rd, (fd_set *)0, (fd_set *)0, NULL);
    if (ret_val == -1) {
      /* perror ("Select"); */
      return -1;
    }
    for(i=0; i<2; i++) {
      if (is_valid_socket(&server[i])
          && FD_ISSET(server[i].socket, &rd)) {
        p = fricas_accept_connection(server+i);
        if (p == purpose) return 1;
      }
    }
  }
}
Exemplo n.º 6
0
/* This actually is a int file descriptor (and not assuan_fd_t) as
   _get_osfhandle is called on W32 systems.  */
gpg_error_t
assuan_init_pipe_server (assuan_context_t ctx, assuan_fd_t filedes[2])
{
  const char *s;
  unsigned long ul;
  gpg_error_t rc;
  assuan_fd_t infd = ASSUAN_INVALID_FD;
  assuan_fd_t outfd = ASSUAN_INVALID_FD;
  int is_usd = 0;
  TRACE_BEG (ctx, ASSUAN_LOG_CTX, "assuan_init_pipe_server", ctx);
  if (filedes)
    {
      TRACE_LOG2 ("fd[0]=0x%x, fd[1]=0x%x", filedes[0], filedes[1]);
    }
  
  rc = _assuan_register_std_commands (ctx);
  if (rc)
    return TRACE_ERR (rc);

#ifdef HAVE_W32_SYSTEM
  infd  = filedes[0];
  outfd = filedes[1];
#else
  s = getenv ("_assuan_connection_fd");
  if (s && *s && is_valid_socket (s))
    {
      /* Well, we are called with an bi-directional file descriptor.
	 Prepare for using sendmsg/recvmsg.  In this case we ignore
	 the passed file descriptors. */
      infd = atoi (s);
      outfd = atoi (s);
      is_usd = 1;

    }
  else if (filedes && filedes[0] != ASSUAN_INVALID_FD 
	   && filedes[1] != ASSUAN_INVALID_FD )
    {
      /* Standard pipe server. */
      infd = filedes[0];
      outfd = filedes[1];
    }
  else
    {
      rc = _assuan_error (ctx, GPG_ERR_ASS_SERVER_START);
      return TRACE_ERR (rc);
    }
#endif

  ctx->is_server = 1;
  ctx->engine.release = _assuan_server_release;
  ctx->engine.readfnc = _assuan_simple_read;
  ctx->engine.writefnc = _assuan_simple_write;
  ctx->engine.sendfd = NULL;
  ctx->engine.receivefd = NULL;
  ctx->max_accepts = 1;

  s = getenv ("_assuan_pipe_connect_pid");
  if (s && (ul=strtoul (s, NULL, 10)) && ul)
    ctx->pid = (pid_t)ul;
  else
    ctx->pid = (pid_t)-1;
  ctx->accept_handler = NULL;
  ctx->finish_handler = _assuan_server_finish;
  ctx->inbound.fd = infd;
  ctx->outbound.fd = outfd;

  if (is_usd)
    _assuan_init_uds_io (ctx);

  return TRACE_SUC();
}