예제 #1
0
/*
 *  Revoke the authentication key in the given AUTH handle by setting
 *  it to NULL.  If newkey is true, then generate a new key instead of
 *  nulling out the old one.  This is necessary for AUTH_DES because
 *  the new key will be used next time the user does a keylogin.  If
 *  the zero'd key is used as actual key, then it cannot be revoked
 *  again!
 */
void
revoke_key(AUTH *auth, int newkey)
{
	if (auth == NULL)
		return;

	if (newkey) {
		if (key_gendes(&auth->ah_key) != RPC_SUCCESS) {
			/* failed to get new key, munge the old one */
			auth->ah_key.key.high ^= auth->ah_key.key.low;
			auth->ah_key.key.low  += auth->ah_key.key.high;
		}
	} else {
		/* null out old key */
		auth->ah_key.key.high = 0;
		auth->ah_key.key.low  = 0;
	}
}
예제 #2
0
int
yp_update(char *domain, char *map, unsigned int ypop, char *key, int keylen,
	  char *data, int datalen)
{
	char *master;
	int rval;
	unsigned int res;
	struct ypupdate_args upargs;
	struct ypdelete_args delargs;
	CLIENT *clnt;
	char netname[MAXNETNAMELEN+1];
	des_block des_key;
	struct timeval timeout;

	/* Get the master server name for 'domain.' */
	if ((rval = yp_master(domain, map, &master)))
		return(rval);

	/* Check that ypupdated is running there. */
	if (getrpcport(master, YPU_PROG, YPU_VERS, ypop))
		return(YPERR_DOMAIN);

	/* Get a handle. */
	if ((clnt = clnt_create(master, YPU_PROG, YPU_VERS, "tcp")) == NULL)
		return(YPERR_RPC);

	/*
	 * Assemble netname of server.
	 * NOTE: It's difficult to discern from the documentation, but
	 * when you make a Secure RPC call, the netname you pass should
	 * be the netname of the guy on the other side, not your own
	 * netname. This is how the client side knows what public key
	 * to use for the initial exchange. Passing your own netname
	 * only works if the server on the other side is running under
	 * your UID.
	 */
	if (!host2netname(netname, master, domain)) {
		clnt_destroy(clnt);
		return(YPERR_BADARGS);
	}

	/* Make up a DES session key. */
	key_gendes(&des_key);

	/* Set up DES authentication. */
	if ((clnt->cl_auth = (AUTH *)authdes_create(netname, WINDOW, NULL,
			&des_key)) == NULL) {
		clnt_destroy(clnt);
		return(YPERR_RESRC);
	}

	/* Set a timeout for clnt_call(). */
	timeout.tv_usec = 0;
	timeout.tv_sec = TIMEOUT;

	/*
	 * Make the call. Note that we use clnt_call() here rather than
	 * the rpcgen-erated client stubs. We could use those stubs, but
	 * then we'd have to do some gymnastics to get at the error
	 * information to figure out what error code to send back to the
	 * caller. With clnt_call(), we get the error status returned to
	 * us right away, and we only have to exert a small amount of
	 * extra effort.
	 */
	switch (ypop) {
	case YPOP_CHANGE:
		upargs.mapname = map;
		upargs.key.yp_buf_len = keylen;
		upargs.key.yp_buf_val = key;
		upargs.datum.yp_buf_len = datalen;
		upargs.datum.yp_buf_val = data;

		if ((rval = clnt_call(clnt, YPU_CHANGE,
			(xdrproc_t)xdr_ypupdate_args, &upargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	case YPOP_INSERT:
		upargs.mapname = map;
		upargs.key.yp_buf_len = keylen;
		upargs.key.yp_buf_val = key;
		upargs.datum.yp_buf_len = datalen;
		upargs.datum.yp_buf_val = data;

		if ((rval = clnt_call(clnt, YPU_INSERT,
			(xdrproc_t)xdr_ypupdate_args, &upargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	case YPOP_DELETE:
		delargs.mapname = map;
		delargs.key.yp_buf_len = keylen;
		delargs.key.yp_buf_val = key;

		if ((rval = clnt_call(clnt, YPU_DELETE,
			(xdrproc_t)xdr_ypdelete_args, &delargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	case YPOP_STORE:
		upargs.mapname = map;
		upargs.key.yp_buf_len = keylen;
		upargs.key.yp_buf_val = key;
		upargs.datum.yp_buf_len = datalen;
		upargs.datum.yp_buf_val = data;

		if ((rval = clnt_call(clnt, YPU_STORE,
			(xdrproc_t)xdr_ypupdate_args, &upargs,
			(xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) {
			if (rval == RPC_AUTHERROR)
				res = YPERR_ACCESS;
			else
				res = YPERR_RPC;
		}

		break;
	default:
		res = YPERR_BADARGS;
		break;
	}

	/* All done: tear down the connection. */
	auth_destroy(clnt->cl_auth);
	clnt_destroy(clnt);
	free(master);

	return(res);
}
예제 #3
0
/*
 * Slightly modified version of authdessec_create which takes the public key
 * of the server principal as an argument. This spares us a call to
 * getpublickey() which in the nameserver context can cause a deadlock.
 */
AUTH *
authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window,
	const char *timehost, const des_block *ckey, nis_server *srvr)
{
	AUTH *auth;
	struct ad_private *ad;
	char namebuf[MAXNETNAMELEN+1];

	/*
	 * Allocate everything now
	 */
	auth = ALLOC(AUTH);
	if (auth == NULL) {
		syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
		return (NULL);
	}
	ad = ALLOC(struct ad_private);
	if (ad == NULL) {
		syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
		goto failed;
	}
	ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
	ad->ad_timehost = NULL;
	ad->ad_netid = NULL;
	ad->ad_uaddr = NULL;
	ad->ad_nis_srvr = NULL;
	ad->ad_timediff.tv_sec = 0;
	ad->ad_timediff.tv_usec = 0;
	memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len);
	if (!getnetname(namebuf))
		goto failed;
	ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf));
	ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
	ad->ad_servernamelen = strlen(servername);
	ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);

	if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
		syslog(LOG_ERR, "authdes_seccreate: out of memory");
		goto failed;
	}
	if (timehost != NULL) {
		ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
		if (ad->ad_timehost == NULL) {
			syslog(LOG_ERR, "authdes_seccreate: out of memory");
			goto failed;
		}
		memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
		ad->ad_dosync = TRUE;
	} else if (srvr != NULL) {
		ad->ad_nis_srvr = srvr;	/* transient */
		ad->ad_dosync = TRUE;
	} else {
		ad->ad_dosync = FALSE;
	}
	memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
	memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1);
	ad->ad_window = window;
	if (ckey == NULL) {
		if (key_gendes(&auth->ah_key) < 0) {
			syslog(LOG_ERR,
	    "authdes_seccreate: keyserv(1m) is unable to generate session key");
			goto failed;
		}
	} else {
		auth->ah_key = *ckey;
	}

	/*
	 * Set up auth handle
	 */
	auth->ah_cred.oa_flavor = AUTH_DES;
	auth->ah_verf.oa_flavor = AUTH_DES;
	auth->ah_ops = authdes_ops();
	auth->ah_private = (caddr_t)ad;

	if (!authdes_refresh(auth, NULL)) {
		goto failed;
	}
	ad->ad_nis_srvr = NULL; /* not needed any longer */
	return (auth);

failed:
	if (auth)
		FREE(auth, sizeof (AUTH));
	if (ad) {
		if (ad->ad_fullname)
			FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
		if (ad->ad_servername)
			FREE(ad->ad_servername, ad->ad_servernamelen + 1);
		if (ad->ad_timehost)
			FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
		if (ad->ad_netid)
			FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
		if (ad->ad_uaddr)
			FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
		FREE(ad, sizeof (struct ad_private));
	}
	return (NULL);
}
예제 #4
0
파일: auth_des.c 프로젝트: bminor/glibc
AUTH *
authdes_pk_create (const char *servername, netobj *pkey, u_int window,
		   struct sockaddr *syncaddr, des_block *ckey)
{
  AUTH *auth;
  struct ad_private *ad;
  char namebuf[MAXNETNAMELEN + 1];

  /*
   * Allocate everything now
   */
  auth = ALLOC (AUTH);
  ad = ALLOC (struct ad_private);

  if (auth == NULL || ad == NULL)
    {
      debug ("authdes_create: out of memory");
      goto failed;
    }

  memset (ad, 0, sizeof (struct ad_private));
  memcpy (ad->ad_pkey, pkey->n_bytes, pkey->n_len);
  if (!getnetname (namebuf))
    goto failed;
  ad->ad_fullnamelen = RNDUP (strlen (namebuf));
  ad->ad_fullname = mem_alloc (ad->ad_fullnamelen + 1);

  ad->ad_servernamelen = strlen (servername);
  ad->ad_servername = mem_alloc (ad->ad_servernamelen + 1);

  if (ad->ad_fullname == NULL || ad->ad_servername == NULL)
    {
      debug ("authdes_create: out of memory");
      goto failed;
    }

  /*
   * Set up private data
   */
  memcpy (ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
  memcpy (ad->ad_servername, servername, ad->ad_servernamelen + 1);
  ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
  if (syncaddr != NULL)
    {
      ad->ad_syncaddr = *syncaddr;
      ad->ad_dosync = TRUE;
    }
  else
    ad->ad_dosync = FALSE;

  ad->ad_window = window;
  if (ckey == NULL)
    {
      if (key_gendes (&auth->ah_key) < 0)
	{
	  debug ("authdes_create: unable to gen conversation key");
	  goto failed;
	}
    }
  else
    auth->ah_key = *ckey;

  /*
   * Set up auth handle
   */
  auth->ah_cred.oa_flavor = AUTH_DES;
  auth->ah_verf.oa_flavor = AUTH_DES;
  auth->ah_ops = (struct auth_ops *) &authdes_ops;
  auth->ah_private = (caddr_t) ad;

  if (!authdes_refresh (auth))
    goto failed;

  return auth;

failed:
  if (auth != NULL)
    FREE (auth, sizeof (AUTH));
  if (ad != NULL)
    {
      if (ad->ad_fullname != NULL)
	FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
      if (ad->ad_servername != NULL)
	FREE (ad->ad_servername, ad->ad_servernamelen + 1);
      FREE (ad, sizeof (struct ad_private));
    }
  return NULL;
}