Ejemplo n.º 1
0
/*ARGSUSED*/
int
sec_clnt_revoke(int rpcflavor, uid_t uid, cred_t *cr, void *mechanism,
						model_t model)
{
	struct desauthent *da;
	int error = 0;
	zoneid_t zoneid = getzoneid();

	if (uid != crgetuid(cr) && secpolicy_nfs(cr) != 0)
		return (EPERM);

	switch (rpcflavor) {
	case AUTH_DES:
		mutex_enter(&desauthtab_lock);
		if (desauthtab != NULL) {
			for (da = desauthtab;
			    da < &desauthtab[clnt_authdes_cachesz]; da++) {
				if (uid == da->da_uid &&
				    zoneid == da->da_zoneid)
					revoke_key(da->da_auth, 1);
			}
		}
		mutex_exit(&desauthtab_lock);
		return (0);

	case RPCSEC_GSS: {
		rpc_gss_OID	mech;
		caddr_t		elements;

		if (!mechanism)
			return (EINVAL);

		/* copyin the gss mechanism type */
		mech = kmem_alloc(sizeof (rpc_gss_OID_desc), KM_SLEEP);
#ifdef _SYSCALL32_IMPL
		if (model != DATAMODEL_NATIVE) {
			gss_OID_desc32 mech32;

			if (copyin(mechanism, &mech32,
			    sizeof (gss_OID_desc32))) {
				kmem_free(mech, sizeof (rpc_gss_OID_desc));
				return (EFAULT);
			}
			mech->length = mech32.length;
			mech->elements = (caddr_t)(uintptr_t)mech32.elements;
		} else
#endif /* _SYSCALL32_IMPL */
		if (copyin(mechanism, mech, sizeof (rpc_gss_OID_desc))) {
			kmem_free(mech, sizeof (rpc_gss_OID_desc));
			return (EFAULT);
		}

		if (mech->length < MINAUTHLEN ||
		    mech->length > MAXAUTHLEN) {
			kmem_free(mech, sizeof (rpc_gss_OID_desc));
			return (EINVAL);
		}

		elements = kmem_alloc(mech->length, KM_SLEEP);
		if (copyin(mech->elements, elements, mech->length)) {
			kmem_free(elements, mech->length);
			kmem_free(mech, sizeof (rpc_gss_OID_desc));
			return (EFAULT);
		}
		mech->elements = elements;

		error = rpc_gss_revauth(uid, mech);

		kmem_free(elements, mech->length);
		kmem_free(mech, sizeof (rpc_gss_OID_desc));

		return (error);
	}

	default:
		/* not an auth type with cached creds */
		return (EINVAL);
	}
}
Ejemplo n.º 2
0
void *
handle_client(void * arg)
{
  struct thread_data_t * datum = (struct thread_data_t *)(arg);
  /* Fetch the ID from the argument */
  #ifndef NDEBUG
  fprintf(stderr, "[thread %lu] INFO: worker started\n", datum->id);
  #endif

  /* Worker thread signal handling is unique */
  sigaction(SIGUSR1, datum->signal_action, NULL);
  sigaction(SIGUSR2, datum->signal_action, NULL);

  /* As long as possible, grab up whatever connection is available */
  while (!session_data.caught_signal && !datum->caught_signal) {
    /* Ensure only one worker accepts the next client */
    gcry_pthread_mutex_lock((void **)(&session_data.accept_mutex));
    datum->sock = accept(session_data.sock,
                         (struct sockaddr *)(&datum->remote_addr),
                         &datum->remote_addr_len);
    gcry_pthread_mutex_unlock((void **)(&session_data.accept_mutex));
    if (datum->sock >= 0) {
      #ifndef NDEBUG
      fprintf(stderr,
              "[thread %lu] INFO: worker connected to client\n",
              datum->id);
      #endif
      /* Receive a "hello" message from the client */
      recv_message(&datum->buffet, datum->sock);
      /* Decrypt it with the default key */
      decrypt_message(&datum->buffet, keystore.key);
      /* Verify it is an authentication request */
      if (strncmp(datum->buffet.tbuffer,
                  AUTH_CHECK_MSG, sizeof(AUTH_CHECK_MSG))) {
        /* Respond with nonce (misdirection) */
        gcry_create_nonce(datum->buffet.pbuffer, MAX_COMMAND_LENGTH);
        encrypt_message(&datum->buffet, keystore.key);
        send_message(&datum->buffet, datum->sock);
      } else {
        /* Request a session key */
        gcry_pthread_mutex_lock((void **)(&session_data.keystore_mutex));
        #ifndef NDEBUG
        print_keystore(stderr, "before request");
        #endif
        request_key(&datum->credentials.key);
        #ifndef NDEBUG
        print_keystore(stderr, "after request");
        #endif
        gcry_pthread_mutex_unlock((void **)(&session_data.keystore_mutex));
        /* Encrypted it using the default key */
        salt_and_pepper((char *)(datum->credentials.key), NULL,
                        &datum->buffet);
        encrypt_message(&datum->buffet, keystore.key);
        send_message(&datum->buffet, datum->sock);
        clear_buffet(&datum->buffet);
        /* Repeatedly poll for message streams */
        while (handle_stream(datum) == BANKING_SUCCESS);
        /* Revoke the session key */
        gcry_pthread_mutex_lock((void **)(&session_data.keystore_mutex));
        #ifndef NDEBUG
        print_keystore(stderr, "before revoke");
        #endif
        revoke_key(&datum->credentials.key);
        #ifndef NDEBUG
        print_keystore(stderr, "after revoke");
        #endif
        gcry_pthread_mutex_unlock((void **)(&session_data.keystore_mutex));
      }
      /* Cleanup (disconnect) */
      #ifndef NDEBUG
      fprintf(stderr,
              "[thread %lu] INFO: worker disconnected from client\n",
              datum->id);
      #endif
      clear_buffet(&datum->buffet);
      destroy_socket(datum->sock);
      datum->sock = BANKING_FAILURE;
    } else {
      fprintf(stderr,
              "[thread %lu] ERROR: worker unable to connect\n",
              datum->id);
    }
  }

  /* Teardown */
  handle_interruption(0);
  return NULL;
}