Beispiel #1
0
static int
get_pkcs11_key_value(libzfs_handle_t *hdl, zfs_cmd_t *zc,
    zfs_crypto_zckey_t cmd, pkcs11_uri_t *p11uri,
    char **keydata, size_t *keydatalen)
{
	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
	KMF_KEY_CLASS keyclass = KMF_SYMMETRIC;
	KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
	KMF_ATTRIBUTE attr[10];
	KMF_KEY_HANDLE keys;
	KMF_CREDENTIAL cred;
	KMF_RAW_SYM_KEY rkey;
	KMF_HANDLE_T kmfh;
	KMF_RETURN err;
	boolean_t true_val = B_TRUE;
	CK_SLOT_ID slot;
	CK_TOKEN_INFO info;
	size_t n = 0;
	uint32_t numkeys = 0; /* Ask for all of the named keys */
	char *token = NULL;

	if (kmf_initialize(&kmfh, NULL, NULL) != KMF_OK) {
		errno = EINVAL;
		return (-1);
	}

	kmf_set_attr_at_index(attr, n++, KMF_KEYSTORE_TYPE_ATTR, &kstype,
	    sizeof (kstype));
	if (p11uri->token) {
		token = strdup((const char *)p11uri->token);
	} else {
		/* If the token wasn't set we assume the metaslot */
		token = strdup(METASLOT_TOKEN_LABEL);
	}
	kmf_set_attr_at_index(attr, n++, KMF_TOKEN_LABEL_ATTR,
	    token, strlen(token));
	kmf_set_attr_at_index(attr, n++, KMF_READONLY_ATTR,
	    &true_val, sizeof (true_val));
	kmf_set_attr_at_index(attr, n++, KMF_TOKEN_BOOL_ATTR,
	    &true_val, sizeof (true_val));

	err = kmf_configure_keystore(kmfh, n, attr);
	if (err != KMF_OK)
		goto out;

	if ((err = kmf_pk11_token_lookup(kmfh, token, &slot)) != KMF_OK ||
	    (err = C_GetTokenInfo(slot, &info)) != CKR_OK)
		goto out;
	/* Always prompt for PIN since the key is likey CKA_SENSITIVE */
	if (prompt_pkcs11_pin(hdl, zc, cmd, p11uri, &cred.cred,
	    &cred.credlen) != 0)
		goto out;
	kmf_set_attr_at_index(attr, n++, KMF_CREDENTIAL_ATTR,
	    &cred, sizeof (KMF_CREDENTIAL));

	kmf_set_attr_at_index(attr, n++, KMF_KEYLABEL_ATTR,
	    p11uri->object, strlen((const char *)p11uri->object));
	kmf_set_attr_at_index(attr, n++, KMF_KEYCLASS_ATTR, &keyclass,
	    sizeof (keyclass));
	kmf_set_attr_at_index(attr, n++, KMF_ENCODE_FORMAT_ATTR, &format,
	    sizeof (format));
	kmf_set_attr_at_index(attr, n++, KMF_COUNT_ATTR,
	    &numkeys, sizeof (numkeys));

	err = kmf_find_key(kmfh, n, attr);
	if (err != KMF_OK || numkeys != 1)
		goto out;

	kmf_set_attr_at_index(attr, n++, KMF_KEY_HANDLE_ATTR, &keys,
	    sizeof (KMF_KEY_HANDLE));
	err = kmf_find_key(kmfh, n, attr);
	err = kmf_get_sym_key_value(kmfh, &keys, &rkey);
	if (err != KMF_OK)
		goto out;
	if (rkey.keydata.len == *keydatalen) {
		*keydata = zfs_alloc(hdl, rkey.keydata.len);
		bcopy(rkey.keydata.val, *keydata, rkey.keydata.len);
	}
	*keydatalen = rkey.keydata.len;
	kmf_free_bigint(&rkey.keydata);

out:
	if (token != NULL)
		free(token);
	(void) kmf_finalize(kmfh);

	if (numkeys == 1 && err == KMF_OK) {
		return (0);
	} else if (err == KMF_ERR_AUTH_FAILED) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "PKCS#11 token login failed."));
	} else if (numkeys == 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "PKCS#11 token object not found."));
	} else if (numkeys > 1) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "keysource points to multiple PKCS#11"
		    " objects"));
	}

	ASSERT(errno != 0);
	return (-1);
}
Beispiel #2
0
/*
 * Attempts to fetch key material, no matter where it might live. The key
 * material is allocated and returned in km_out. *can_retry_out will be set
 * to B_TRUE if the user is providing the key material interactively, allowing
 * for re-entry attempts.
 */
static int
get_key_material(libzfs_handle_t *hdl, boolean_t do_verify, boolean_t newkey,
    zfs_keyformat_t keyformat, char *keylocation, const char *fsname,
    uint8_t **km_out, size_t *kmlen_out, boolean_t *can_retry_out)
{
	int ret, i;
	zfs_keylocation_t keyloc = ZFS_KEYLOCATION_NONE;
	FILE *fd = NULL;
	uint8_t *km = NULL, *km2 = NULL;
	size_t kmlen, kmlen2;
	boolean_t can_retry = B_FALSE;

	/* verify and parse the keylocation */
	keyloc = zfs_prop_parse_keylocation(keylocation);

	/* open the appropriate file descriptor */
	switch (keyloc) {
	case ZFS_KEYLOCATION_PROMPT:
		fd = stdin;
		if (isatty(fileno(fd))) {
			can_retry = B_TRUE;

			/* raw keys cannot be entered on the terminal */
			if (keyformat == ZFS_KEYFORMAT_RAW) {
				ret = EINVAL;
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "Cannot enter raw keys on the terminal"));
				goto error;
			}
		}
		break;
	case ZFS_KEYLOCATION_URI:
		fd = fopen(&keylocation[7], "r");
		if (!fd) {
			ret = errno;
			errno = 0;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Failed to open key material file"));
			goto error;
		}
		break;
	default:
		ret = EINVAL;
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "Invalid keylocation."));
		goto error;
	}

	/* fetch the key material into the buffer */
	ret = get_key_material_raw(fd, fsname, keyformat, B_FALSE, newkey,
	    &km, &kmlen);
	if (ret != 0)
		goto error;

	/* do basic validation of the key material */
	switch (keyformat) {
	case ZFS_KEYFORMAT_RAW:
		/* verify the key length is correct */
		if (kmlen < WRAPPING_KEY_LEN) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Raw key too short (expected %u)."),
			    WRAPPING_KEY_LEN);
			goto error;
		}

		if (kmlen > WRAPPING_KEY_LEN) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Raw key too long (expected %u)."),
			    WRAPPING_KEY_LEN);
			goto error;
		}
		break;
	case ZFS_KEYFORMAT_HEX:
		/* verify the key length is correct */
		if (kmlen < WRAPPING_KEY_LEN * 2) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Hex key too short (expected %u)."),
			    WRAPPING_KEY_LEN * 2);
			goto error;
		}

		if (kmlen > WRAPPING_KEY_LEN * 2) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Hex key too long (expected %u)."),
			    WRAPPING_KEY_LEN * 2);
			goto error;
		}

		/* check for invalid hex digits */
		for (i = 0; i < WRAPPING_KEY_LEN * 2; i++) {
			if (!isxdigit((char)km[i])) {
				ret = EINVAL;
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "Invalid hex character detected."));
				goto error;
			}
		}
		break;
	case ZFS_KEYFORMAT_PASSPHRASE:
		/* verify the length is within bounds */
		if (kmlen > MAX_PASSPHRASE_LEN) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Passphrase too long (max %u)."),
			    MAX_PASSPHRASE_LEN);
			goto error;
		}

		if (kmlen < MIN_PASSPHRASE_LEN) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Passphrase too short (min %u)."),
			    MIN_PASSPHRASE_LEN);
			goto error;
		}
		break;
	default:
		/* can't happen, checked above */
		break;
	}

	if (do_verify && isatty(fileno(fd))) {
		ret = get_key_material_raw(fd, fsname, keyformat, B_TRUE,
		    newkey, &km2, &kmlen2);
		if (ret != 0)
			goto error;

		if (kmlen2 != kmlen ||
		    (memcmp((char *)km, (char *)km2, kmlen) != 0)) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Provided keys do not match."));
			goto error;
		}
	}

	if (fd != stdin)
		fclose(fd);

	if (km2 != NULL)
		free(km2);

	*km_out = km;
	*kmlen_out = kmlen;
	if (can_retry_out != NULL)
		*can_retry_out = can_retry;

	return (0);

error:
	if (km != NULL)
		free(km);

	if (km2 != NULL)
		free(km2);

	if (fd != NULL && fd != stdin)
		fclose(fd);

	*km_out = NULL;
	*kmlen_out = 0;
	if (can_retry_out != NULL)
		*can_retry_out = can_retry;

	return (ret);
}
Beispiel #3
0
int
zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props,
    nvlist_t *pool_props, uint8_t **wkeydata_out, uint_t *wkeylen_out)
{
	int ret;
	char errbuf[1024];
	uint64_t crypt = ZIO_CRYPT_INHERIT, pcrypt = ZIO_CRYPT_INHERIT;
	uint64_t keyformat = ZFS_KEYFORMAT_NONE;
	char *keylocation = NULL;
	zfs_handle_t *pzhp = NULL;
	uint8_t *wkeydata = NULL;
	uint_t wkeylen = 0;
	boolean_t local_crypt = B_TRUE;

	(void) snprintf(errbuf, sizeof (errbuf),
	    dgettext(TEXT_DOMAIN, "Encryption create error"));

	/* lookup crypt from props */
	ret = nvlist_lookup_uint64(props,
	    zfs_prop_to_name(ZFS_PROP_ENCRYPTION), &crypt);
	if (ret != 0)
		local_crypt = B_FALSE;

	/* lookup key location and format from props */
	(void) nvlist_lookup_uint64(props,
	    zfs_prop_to_name(ZFS_PROP_KEYFORMAT), &keyformat);
	(void) nvlist_lookup_string(props,
	    zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);

	if (parent_name != NULL) {
		/* get a reference to parent dataset */
		pzhp = make_dataset_handle(hdl, parent_name);
		if (pzhp == NULL) {
			ret = ENOENT;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Failed to lookup parent."));
			goto out;
		}

		/* Lookup parent's crypt */
		pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION);

		/* Params require the encryption feature */
		if (!encryption_feature_is_enabled(pzhp->zpool_hdl)) {
			if (proplist_has_encryption_props(props)) {
				ret = EINVAL;
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "Encryption feature not enabled."));
				goto out;
			}

			ret = 0;
			goto out;
		}
	} else {
		/*
		 * special case for root dataset where encryption feature
		 * feature won't be on disk yet
		 */
		if (!nvlist_exists(pool_props, "feature@encryption")) {
			if (proplist_has_encryption_props(props)) {
				ret = EINVAL;
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "Encryption feature not enabled."));
				goto out;
			}

			ret = 0;
			goto out;
		}

		pcrypt = ZIO_CRYPT_OFF;
	}

	/* Check for encryption being explicitly truned off */
	if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) {
		ret = EINVAL;
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "Invalid encryption value. Dataset must be encrypted."));
		goto out;
	}

	/* Get the inherited encryption property if we don't have it locally */
	if (!local_crypt)
		crypt = pcrypt;

	/*
	 * At this point crypt should be the actual encryption value. If
	 * encryption is off just verify that no encryption properties have
	 * been specified and return.
	 */
	if (crypt == ZIO_CRYPT_OFF) {
		if (proplist_has_encryption_props(props)) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Encryption must be turned on to set encryption "
			    "properties."));
			goto out;
		}

		ret = 0;
		goto out;
	}

	/*
	 * If we have a parent crypt it is valid to specify encryption alone.
	 * This will result in a child that is encrypted with the chosen
	 * encryption suite that will also inherit the parent's key. If
	 * the parent is not encrypted we need an encryption suite provided.
	 */
	if (pcrypt == ZIO_CRYPT_OFF && keylocation == NULL &&
	    keyformat == ZFS_KEYFORMAT_NONE) {
		ret = EINVAL;
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "Keyformat required for new encryption root."));
		goto out;
	}

	/*
	 * Specifying a keylocation implies this will be a new encryption root.
	 * Check that a keyformat is also specified.
	 */
	if (keylocation != NULL && keyformat == ZFS_KEYFORMAT_NONE) {
		ret = EINVAL;
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "Keyformat required for new encryption root."));
		goto out;
	}

	/* default to prompt if no keylocation is specified */
	if (keyformat != ZFS_KEYFORMAT_NONE && keylocation == NULL) {
		keylocation = "prompt";
		ret = nvlist_add_string(props,
		    zfs_prop_to_name(ZFS_PROP_KEYLOCATION), keylocation);
		if (ret != 0)
			goto out;
	}

	/*
	 * If a local key is provided, this dataset will be a new
	 * encryption root. Populate the encryption params.
	 */
	if (keylocation != NULL) {
		ret = populate_create_encryption_params_nvlists(hdl, NULL,
		    B_FALSE, keyformat, keylocation, props, &wkeydata,
		    &wkeylen);
		if (ret != 0)
			goto out;
	}

	if (pzhp != NULL)
		zfs_close(pzhp);

	*wkeydata_out = wkeydata;
	*wkeylen_out = wkeylen;
	return (0);

out:
	if (pzhp != NULL)
		zfs_close(pzhp);
	if (wkeydata != NULL)
		free(wkeydata);

	*wkeydata_out = NULL;
	*wkeylen_out = 0;
	return (ret);
}
static void
hn_others_menu_get_items (GtkMenu *menu,
			  HNOthersButton *button,
			  GtkTreeModel *model,
			  GtkTreeIter *iter)
{
  GtkMenu *submenu = NULL;

  GtkWidget *menu_item = NULL;

  gchar *item_name = NULL;
  gchar *item_comment = NULL;
  GdkPixbuf *item_icon  = NULL;
  GdkPixbuf *item_thumb_icon = NULL;
  gchar *item_exec = NULL;
  gchar *item_service = NULL;
  gchar *item_desktop_id = NULL;
  gchar *item_text_domain = NULL;
  GtkTreeIter child_iter;
  gint children;
  gboolean my_iterator = FALSE;
  
  g_return_if_fail (menu);

  if (!model)
  {
    GtkTreeIter iter0;
    
    model = get_menu_contents();
    iter = g_malloc0 (sizeof (GtkTreeIter));
    my_iterator = TRUE;
    
    /* Get the top level iterator. */
    if (!gtk_tree_model_get_iter_first(model, &iter0) ||
        !gtk_tree_model_iter_children(model, iter, &iter0))
    {
      g_object_unref (G_OBJECT (model));
      return;
    }
  }
  else
  {
    g_object_ref (G_OBJECT (model));
  }
    
  /* Loop! */
  do  {
    item_name = NULL;
    item_icon = NULL;
    item_thumb_icon = NULL;
    item_exec = NULL;
    item_service = NULL;
    item_desktop_id = NULL;
    item_text_domain = NULL;

    gtk_tree_model_get (model, iter,
		        TREE_MODEL_NAME, &item_name,
		        TREE_MODEL_ICON, &item_icon,
		        TREE_MODEL_THUMB_ICON, &item_thumb_icon,
		        TREE_MODEL_EXEC, &item_exec,
		        TREE_MODEL_SERVICE, &item_service,
		        TREE_MODEL_DESKTOP_ID, &item_desktop_id,
		        TREE_MODEL_COMMENT, &item_comment,
		        TREE_MODEL_TEXT_DOMAIN, &item_text_domain,
		        -1);

    children = 0;

    /* If the item has children. */
    if (gtk_tree_model_iter_children (model, &child_iter, iter))
    {
      gchar *child_string = NULL;
      	    
      /* It's a submenu */
      submenu = GTK_MENU (gtk_menu_new ());
      
      gtk_widget_set_name (GTK_WIDGET (submenu),
                           NAVIGATOR_MENU_NAME);
      
      /* Create a menu item and add it to the menu. */
      children = gtk_tree_model_iter_n_children (model, iter);
      child_string = g_strdup_printf(MENU_ITEM_N_ITEMS (children), children);
 
      menu_item = hildon_thumb_menu_item_new_with_labels (
                                (item_text_domain && *item_text_domain) ?
                                dgettext(item_text_domain, item_name):
                                _(item_name),
                                NULL,
                                child_string);
      
      g_free(child_string);
      
      gtk_menu_shell_append (GTK_MENU_SHELL (menu),
      		             GTK_WIDGET (menu_item));
      
      /* Add the submenu icon */
      if (item_icon && item_thumb_icon)
      {
        hildon_thumb_menu_item_set_images (
            		  HILDON_THUMB_MENU_ITEM (menu_item),
            		  gtk_image_new_from_pixbuf (item_icon),
            		  gtk_image_new_from_pixbuf (item_thumb_icon));
      }
      	    
      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
      			         GTK_WIDGET (submenu));
      
      /* Recurse! */
      hn_others_menu_get_items(submenu, button, model, &child_iter);
    }
    else if ( !item_desktop_id || strlen( item_desktop_id ) == 0 )
    {
      /* Empty submenu. Skip "Extras" */
      if (strcmp (item_name, "tana_fi_extras") != 0)
      {
        gchar *child_string;
        submenu = GTK_MENU(gtk_menu_new());
    
        gtk_widget_set_name (GTK_WIDGET(submenu),
      		             NAVIGATOR_MENU_NAME);

        /* Create a menu item and add it to the menu.
         */
        child_string = g_strdup_printf(MENU_ITEM_N_ITEMS(children), children);
        menu_item = hildon_thumb_menu_item_new_with_labels (
      	        (item_text_domain && *item_text_domain)?
      	        dgettext(item_text_domain, item_name):
      	        dgettext("maemo-af-desktop", item_name),
      	        NULL,
      	        child_string);

	g_free(child_string);

        gtk_menu_shell_append (GTK_MENU_SHELL (menu),
      		               GTK_WIDGET (menu_item));

        /* Add the submenu icon */
        if (item_icon)
        {
          hildon_thumb_menu_item_set_images(
      	          HILDON_THUMB_MENU_ITEM(menu_item),
      	          gtk_image_new_from_pixbuf(item_icon),
      	          gtk_image_new_from_pixbuf(item_thumb_icon));
        }

        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
      		                   GTK_WIDGET (submenu));

        /* Create a menu item and add it to the menu. */
        GtkWidget *submenu_item =
                gtk_image_menu_item_new_with_label (MENU_ITEM_EMPTY_SUBMENU_STRING);

        gtk_widget_set_sensitive (submenu_item, FALSE);

        gtk_menu_shell_append (GTK_MENU_SHELL (submenu),
                               GTK_WIDGET (submenu_item));

      }
    }
    else if (strcmp(item_desktop_id, SEPARATOR_STRING) == 0)
    {
      /* Separator */
      menu_item = gtk_separator_menu_item_new();

      gtk_menu_shell_append (GTK_MENU_SHELL (menu),
      		             GTK_WIDGET (menu_item));
      	    
    }
    else
    {
      /* Application */
      menu_item = hildon_thumb_menu_item_new_with_labels (
      		(item_text_domain && *item_text_domain)?
      		dgettext(item_text_domain, item_name):
      		dgettext("maemo-af-desktop", item_name),
      		NULL,
      		/* work around strange behaviour of gettext for
      		 * empty  strings
      		 */
      		(item_comment && *item_comment)?_(item_comment):"");

      if (!item_icon)
      {
        item_icon = get_icon (MENU_ITEM_DEFAULT_APP_ICON,
      		              MENU_ITEM_ICON_SIZE);
      }

      if (!item_thumb_icon)
      {
        item_thumb_icon = get_icon (MENU_ITEM_DEFAULT_APP_ICON,
      		                    MENU_ITEM_THUMB_ICON_SIZE);
      }

      if (item_icon && item_thumb_icon)
      {
        hildon_thumb_menu_item_set_images (
      		   HILDON_THUMB_MENU_ITEM (menu_item),
      		   gtk_image_new_from_pixbuf (item_icon),
      		   gtk_image_new_from_pixbuf (item_thumb_icon));
      }

      gtk_menu_shell_append (GTK_MENU_SHELL (menu),
      		             GTK_WIDGET (menu_item));

      g_object_set_data_full (G_OBJECT (menu_item),
      		              DESKTOP_ENTRY_EXEC_FIELD,
      		              g_strdup (item_exec), 
			      g_free);

      g_object_set_data_full (G_OBJECT(menu_item),
      		              DESKTOP_ENTRY_SERVICE_FIELD,
      		              g_strdup (item_service), 
			      g_free);

      /* Connect the signal and callback */
      g_signal_connect (G_OBJECT (menu_item), 
		        "activate",
      		        G_CALLBACK (hn_others_menu_activate_item),
      		        button);
    }
 
    g_free (item_name);
    
    if (item_icon)
      g_object_unref (G_OBJECT (item_icon));
    
    if (item_thumb_icon)
      g_object_unref (G_OBJECT (item_thumb_icon));
    
    g_free (item_exec);
    g_free (item_service);
    g_free (item_desktop_id);
    g_free (item_comment);
    g_free (item_text_domain);
	    
  } while (gtk_tree_model_iter_next(model, iter));


  if (my_iterator)
  {
    gtk_tree_iter_free (iter);
    
    g_debug ("ref count remaining on model %d (should be 1)",
             G_OBJECT (model)->ref_count);
  }
  
  g_object_unref (G_OBJECT (model));
}
Beispiel #5
0
int
zfs_crypto_unload_key(zfs_handle_t *zhp)
{
	int ret;
	char errbuf[1024];
	char prop_encroot[MAXNAMELEN];
	uint64_t keystatus, keyformat;
	boolean_t is_encroot;

	(void) snprintf(errbuf, sizeof (errbuf),
	    dgettext(TEXT_DOMAIN, "Key unload error"));

	/* check that encryption is enabled for the pool */
	if (!encryption_feature_is_enabled(zhp->zpool_hdl)) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Encryption feature not enabled."));
		ret = EINVAL;
		goto error;
	}

	/* Fetch the keyformat. Check that the dataset is encrypted. */
	keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT);
	if (keyformat == ZFS_KEYFORMAT_NONE) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "'%s' is not encrypted."), zfs_get_name(zhp));
		ret = EINVAL;
		goto error;
	}

	/*
	 * Fetch the key location. Check that we are working with an
	 * encryption root.
	 */
	ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, prop_encroot);
	if (ret != 0) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Failed to get encryption root for '%s'."),
		    zfs_get_name(zhp));
		goto error;
	} else if (!is_encroot) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Keys must be unloaded for encryption root of '%s' (%s)."),
		    zfs_get_name(zhp), prop_encroot);
		ret = EINVAL;
		goto error;
	}

	/* check that the key is loaded */
	keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
	if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Key already unloaded for '%s'."), zfs_get_name(zhp));
		ret = ENOENT;
		goto error;
	}

	/* call the ioctl */
	ret = lzc_unload_key(zhp->zfs_name);

	if (ret != 0) {
		switch (ret) {
		case EPERM:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Permission denied."));
			break;
		case ENOENT:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Key already unloaded for '%s'."),
			    zfs_get_name(zhp));
			break;
		case EBUSY:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "'%s' is busy."), zfs_get_name(zhp));
			break;
		}
		zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
	}

	return (ret);

error:
	zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
	return (ret);
}
Beispiel #6
0
char *_p_CDGetText (char *domainname, char *msgid)
{
  return dgettext (domainname, msgid);
}
Beispiel #7
0
recognizer 
recognizer_load(char* directory, char* name, char** subset)
{
    recognizer	rec;				/*the recognizer*/
    rec_info*	rinf;				/*rec_info for recognizer information*/
    static bool	intl_init = false;	/*true if recog. manager initted.*/

    if( intl_init == false ) {
      intl_init = true;
      intl_initialize();
    }

    /*The name takes precedence.*/
    rinf = make_rec_info(directory, name, subset);
    if (rinf == nil) {
	the_last_error = 
	  dgettext(INTL_DOMAIN,
		   "Ran out of memory during prelinking initialization.");
	return((recognizer)nil);
    } 
/* fprint(2, "Got past make_rec_info.\n"); */

    /*Let recognition code create recognizer and initialize*/
    rec = __recognizer_internal_initialize(rinf);
    if (rec == nil) {
	return((recognizer)nil);
    }
/* fprint(2, "Did rii.\n"); */
    /*Check whether it's been correctly initialized*/

    if( rec->recognizer_load_state == nil ||
        rec->recognizer_save_state == nil ||
        rec->recognizer_load_dictionary == nil ||
        rec->recognizer_save_dictionary == nil ||
        rec->recognizer_free_dictionary == nil ||
        rec->recognizer_add_to_dictionary == nil ||
        rec->recognizer_delete_from_dictionary == nil ||
        rec->recognizer_error == nil ||
        rec->recognizer_set_context == nil ||
        rec->recognizer_get_context == nil ||
        rec->recognizer_clear == nil ||
        rec->recognizer_get_buffer == nil ||
        rec->recognizer_set_buffer == nil ||
        rec->recognizer_translate == nil ||
        rec->recognizer_get_extension_functions == nil ||
        rec->recognizer_get_gesture_names == nil ||
        rec->recognizer_set_gesture_action == nil
       ) {

	recognizer_unload(rec);
/* fprint(2, "Unloading b/c null function pointer.\n"); */
	the_last_error = 
	  dgettext(INTL_DOMAIN,
		   "One or more recognizer function pointers is nil.");
	return((recognizer)nil);
    }


    /*Set the rec_info structure.*/

    rec->recognizer_info = rinf;

    /*Check whether home directory is there for recognizer info.*/

/*
 *  ari -- don't bother.  We're not going to load from each user's
 *  home directory at this point.  Instead, we'll use a stupid
 *  little a-b-c file because it loads FAST.
 *
 *    if( check_for_user_home() < 0 ) {
 *	recognizer_unload(rec);
 *	return((recognizer)nil);
 *   }
 */
    /*We got it!*/
/* fprint(2, "Done.\n"); */

    return(rec);
}
Beispiel #8
0
const char *
uu_strerror(uint32_t code)
{
	const char *str;

	switch (code) {
	case UU_ERROR_NONE:
		str = dgettext(TEXT_DOMAIN, "No error");
		break;

	case UU_ERROR_INVALID_ARGUMENT:
		str = dgettext(TEXT_DOMAIN, "Invalid argument");
		break;

	case UU_ERROR_UNKNOWN_FLAG:
		str = dgettext(TEXT_DOMAIN, "Unknown flag passed");
		break;

	case UU_ERROR_NO_MEMORY:
		str = dgettext(TEXT_DOMAIN, "Out of memory");
		break;

	case UU_ERROR_CALLBACK_FAILED:
		str = dgettext(TEXT_DOMAIN, "Callback-initiated failure");
		break;

	case UU_ERROR_NOT_SUPPORTED:
		str = dgettext(TEXT_DOMAIN, "Operation not supported");
		break;

	case UU_ERROR_EMPTY:
		str = dgettext(TEXT_DOMAIN, "No value provided");
		break;

	case UU_ERROR_UNDERFLOW:
		str = dgettext(TEXT_DOMAIN, "Value too small");
		break;

	case UU_ERROR_OVERFLOW:
		str = dgettext(TEXT_DOMAIN, "Value too large");
		break;

	case UU_ERROR_INVALID_CHAR:
		str = dgettext(TEXT_DOMAIN,
		    "Value contains unexpected character");
		break;

	case UU_ERROR_INVALID_DIGIT:
		str = dgettext(TEXT_DOMAIN,
		    "Value contains digit not in base");
		break;

	case UU_ERROR_SYSTEM:
		str = dgettext(TEXT_DOMAIN, "Underlying system error");
		break;

	case UU_ERROR_UNKNOWN:
		str = dgettext(TEXT_DOMAIN, "Error status not known");
		break;

	default:
		errno = ESRCH;
		str = NULL;
		break;
	}
	return (str);
}
Beispiel #9
0
static int
rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
    struct share_info **entries_listp)
{
	char ctx_string[2+16+1];	/* enough for 64-bit pointer, in hex */
	unsigned_char_p_t binding;
	unsigned32 binding_status;
	rpc_binding_handle_t binding_h;
	int error, i, entries;
	char *addrstr, *srvnamestr;
	unsigned short *usrvnamestr;
	unsigned32 level;
	SHARE_ENUM_STRUCT share_info;
	SHARE_INFO_1_CONTAINER share_info_1_container;
	SHARE_INFO_1 *shares, *share;
	unsigned32 total_entries;
	unsigned32 status, free_status;
	struct share_info *entry_list, *elp;
	static EXCEPTION rpc_x_connect_rejected;
	static int exceptions_initialized;

	sprintf(ctx_string, "%p", ctx);
	rpc_string_binding_compose(NULL, "ncacn_np", ctx_string,
	    "srvsvc", NULL, &binding, &binding_status);
	if (binding_status != rpc_s_ok) {
		smb_error(dgettext(TEXT_DOMAIN,
		    "rpc_string_binding_compose failed with %d"),
		    0, binding_status);
		return (EINVAL);
	}
	rpc_binding_from_string_binding(binding, &binding_h, &status);
	rpc_string_free(&binding, (unsigned32 *)&free_status);
	if (binding_status != rpc_s_ok) {
		smb_error(dgettext(TEXT_DOMAIN,
		    "rpc_binding_from_string_binding failed with %d"), 0,
		    binding_status);
		return (EINVAL);
	}
	level = 1;
	share_info.share_union.level = 1;
	share_info.share_union.tagged_union.share1 = &share_info_1_container;
	share_info_1_container.share_count = 0;
	share_info_1_container.shares = NULL;
	/*
	 * Convert the server IP address to a string, and send that as
	 * the "server name" - that's what Windows appears to do, and
	 * that avoids problems with NetBIOS names containing
	 * non-ASCII characters.
	 */
	addrstr = inet_ntoa(ctx->ct_srvinaddr.sin_addr);
	srvnamestr = malloc(strlen(addrstr) + 3);
	if (srvnamestr == NULL) {
		status = errno;
		smb_error(dgettext(TEXT_DOMAIN,
		    "can't allocate string for server address"), status);
		rpc_binding_free(&binding_h, &free_status);
		return (status);
	}
	strcpy(srvnamestr, "\\\\");
	strcat(srvnamestr, addrstr);
	usrvnamestr = convert_utf8_to_leunicode(srvnamestr);
	if (usrvnamestr == NULL) {
		smb_error(dgettext(TEXT_DOMAIN,
		    "can't convert string for server address to Unicode"), 0);
		rpc_binding_free(&binding_h, &free_status);
		free(srvnamestr);
		return (EINVAL);
	}
	if (!exceptions_initialized) {
		EXCEPTION_INIT(rpc_x_connect_rejected);
		exc_set_status(&rpc_x_connect_rejected, rpc_s_connect_rejected);
		exceptions_initialized = 1;
	}
	/* printf("Calling NetrShareEnum.."); XXX */
	TRY
		status = NetrShareEnum(binding_h, usrvnamestr, &level,
		    &share_info, 4294967295U, &total_entries, NULL);
		if (status != 0)
			smb_error(dgettext(TEXT_DOMAIN,
			    "error from NetrShareEnum call: status = 0x%08x"),
			    0, status);
	/*CSTYLED*/
	CATCH (rpc_x_connect_rejected)
		/*
		 * This is what we get if we can't open the pipe.
		 * That's a normal occurrence when we're talking
		 * to a system that (presumably) doesn't support
		 * DCE RPC on the server side, such as Windows 95/98/Me,
		 * so we don't log an error.
		 */
		/*CSTYLED*/
		status = ENOTSUP;
	CATCH_ALL
		/*
		 * XXX - should we handle some exceptions differently,
		 * returning different errors, and try RAP only for
		 * ENOTSUP?
		 */
		smb_error(dgettext(TEXT_DOMAIN,
		    "error from NetrShareEnum call: exception = %u"),
		    0, THIS_CATCH->match.value);
		status = ENOTSUP;
	ENDTRY
	rpc_binding_free(&binding_h, &free_status);
	free(srvnamestr);
	free(usrvnamestr);
	if (status != 0)
		return (ENOTSUP);

	/*
	 * XXX - if the IDL is correct, it's not clear whether the
	 * unmarshalling code will properly handle the case where
	 * a packet where "share_count" and the max count for the
	 * array of shares don't match; a valid DCE RPC implementation
	 * won't marshal something like that, but there's no guarantee
	 * that the server we're talking to has a valid implementation
	 * (which could be a *malicious* implementation!).
	 */
	entries = share_info.share_union.tagged_union.share1->share_count;
	shares = share_info.share_union.tagged_union.share1->shares;
	entry_list = calloc(entries, sizeof (struct share_info));
	if (entry_list == NULL) {
		error = errno;
		goto cleanup_and_return;
	}
	for (share = shares, elp = entry_list, i = 0; i < entries;
	    i++, share++) {
		elp->type = share->shi1_type;
		elp->netname = convert_unicode_to_utf8(share->shi1_share);
		if (elp->netname == NULL)
			goto fail;
		elp->remark = convert_unicode_to_utf8(share->shi1_remark);
		if (elp->remark == NULL)
			goto fail;
		elp++;
	}
	*entriesp = entries;
	*totalp = total_entries;
	*entries_listp = entry_list;
	error = 0;
	goto cleanup_and_return;

fail:
	error = errno;
	for (elp = entry_list, i = 0; i < entries; i++, elp++) {
		/*
		 * elp->netname is set before elp->remark, so if
		 * elp->netname is null, elp->remark is also null.
		 * If either of them is null, we haven't done anything
		 * to any entries after this one.
		 */
		if (elp->netname == NULL)
			break;
		free(elp->netname);
		if (elp->remark == NULL)
			break;
		free(elp->remark);
	}
	free(entry_list);

cleanup_and_return:
	for (share = shares, i = 0; i < entries; i++, share++) {
		free(share->shi1_share);
		free(share->shi1_remark);
	}
	free(shares);
	/*
	 * XXX - "share1" should be a unique pointer, but we haven't
	 * changed the marshalling code to support non-full pointers
	 * in unions, so we leave it as a full pointer.
	 *
	 * That means that this might, or might not, be changed from
	 * pointing to "share_info_1_container" to pointing to a
	 * mallocated structure, according to the DCE RPC 1.1 IDL spec;
	 * we free it only if it's changed.
	 */
	if (share_info.share_union.tagged_union.share1 !=
	    &share_info_1_container)
		free(share_info.share_union.tagged_union.share1);
	return (error);
}
Beispiel #10
0
/**
 * gimp_enum_get_value:
 * @enum_type:  the #GType of a registered enum
 * @value:      an integer value
 * @value_name: return location for the value's name (or %NULL)
 * @value_nick: return location for the value's nick (or %NULL)
 * @value_desc: return location for the value's translated description (or %NULL)
 * @value_help: return location for the value's translated help (or %NULL)
 *
 * Checks if @value is valid for the enum registered as @enum_type.
 * If the value exists in that enum, its name, nick and its translated
 * description and help are returned (if @value_name, @value_nick,
 * @value_desc and @value_help are not %NULL).
 *
 * Return value: %TRUE if @value is valid for the @enum_type,
 *               %FALSE otherwise
 *
 * Since: GIMP 2.2
 **/
gboolean
gimp_enum_get_value (GType         enum_type,
                     gint          value,
                     const gchar **value_name,
                     const gchar **value_nick,
                     const gchar **value_desc,
                     const gchar **value_help)
{
  GEnumClass *enum_class;
  GEnumValue *enum_value;
  gboolean    success = FALSE;

  g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), FALSE);

  enum_class = g_type_class_ref (enum_type);
  enum_value = g_enum_get_value (enum_class, value);

  if (enum_value)
    {
      if (value_name)
        *value_name = enum_value->value_name;

      if (value_nick)
        *value_nick = enum_value->value_nick;

      if (value_desc || value_help)
        {
          GimpEnumDesc *enum_desc;

          enum_desc = gimp_enum_get_desc (enum_class, value);

          if (value_desc)
            {
              if (enum_desc && enum_desc->value_desc)
                {
                  const gchar *context;

                  context = gimp_type_get_translation_context (enum_type);

                  if (context)  /*  the new way, using NC_()    */
                    *value_desc = g_dpgettext2 (gimp_type_get_translation_domain (enum_type),
                                                context,
                                                enum_desc->value_desc);
                  else          /*  for backward compatibility  */
                    *value_desc = g_strip_context (enum_desc->value_desc,
                                                   dgettext (gimp_type_get_translation_domain (enum_type),
                                                             enum_desc->value_desc));
                }
              else
                {
                  *value_desc = NULL;
                }
            }

          if (value_help)
            {
              *value_help = ((enum_desc && enum_desc->value_help) ?
                             dgettext (gimp_type_get_translation_domain (enum_type),
                                       enum_desc->value_help) :
                             NULL);
            }
        }

      success = TRUE;
    }

  g_type_class_unref (enum_class);

  return success;
}
Beispiel #11
0
void trecruit::refresh_tooltip(twindow& window)
{
    int idx_in_resistances;
    std::stringstream text;

    tstacked_widget* stacked = find_widget<tstacked_widget>(&window, "middle_top_part", false, true);
    stacked->set_dirty(true);
    stacked = find_widget<tstacked_widget>(&window, "right_part", false, true);
    stacked->set_dirty(true);

    if (checked_heros_.empty()) {
        // It is necessary set all relative tips to empty.
        tcontrol* control = find_widget<tcontrol>(&window, "master_png", false, true);
        control->set_label("");
        tlabel* label = find_widget<tlabel>(&window, "master_name", false, true);
        label->set_label("");

        // leadership
        label = find_widget<tlabel>(&window, "tip_leadership", false, true);
        label->set_label("");

        // force
        label = find_widget<tlabel>(&window, "tip_force", false, true);
        label->set_label("");

        // intellect
        label = find_widget<tlabel>(&window, "tip_intellect", false, true);
        label->set_label("");

        // politics
        label = find_widget<tlabel>(&window, "tip_politics", false, true);
        label->set_label("");

        // charm
        label = find_widget<tlabel>(&window, "tip_charm", false, true);
        label->set_label("");

        // hp
        label = find_widget<tlabel>(&window, "tip_hp", false, true);
        label->set_label("");

        // xp
        label = find_widget<tlabel>(&window, "tip_xp", false, true);
        label->set_label("");

        // movement
        label = find_widget<tlabel>(&window, "tip_movement", false, true);
        label->set_label("");

        // arm
        label = find_widget<tlabel>(&window, "tip_arm", false, true);
        label->set_label("");

        // adaptability
        label = find_widget<tlabel>(&window, "tip_adaptability", false, true);
        label->set_label("");

        // abilities
        label = find_widget<tlabel>(&window, "tip_abilities", false, true);
        label->set_label("");

        // feature
        label = find_widget<tlabel>(&window, "tip_feature", false, true);
        label->set_label("");

        // attack
        label = find_widget<tlabel>(&window, "tip_attack", false, true);
        label->set_label("");

        // resistance
        for (idx_in_resistances = 0; idx_in_resistances < 7; idx_in_resistances ++) {
            text.str("");
            text << "tip_resistance" << idx_in_resistances;
            label = find_widget<tlabel>(&window, text.str(), false, true);
            label->set_label("");
        }
        return;
    }

    const unit_type* t = unit_types_[type_index_];
    std::vector<const hero*> v;
    int index = 0;
    for (std::set<int>::const_iterator itor = checked_heros_.begin(); itor != checked_heros_.end(); ++ itor, index ++) {
        if (index == 0) {
            v.push_back(fresh_heros_[*itor]);
        } else if (index == 1) {
            v.push_back(fresh_heros_[*itor]);
        } else if (index == 2) {
            v.push_back(fresh_heros_[*itor]);
        }
    }
    type_heros_pair pair(t, v);
    unit temp(units_, heros_, pair, city_.cityno(), false);

    std::stringstream str;
    // refresh to gui
    tcontrol* control = find_widget<tcontrol>(&window, "master_png", false, true);
    control->set_label(temp.master().image());
    tlabel* label = find_widget<tlabel>(&window, "master_name", false, true);
    label->set_label(temp.master().name());

    control = find_widget<tcontrol>(&window, "second_png", false, true);
    label = find_widget<tlabel>(&window, "second_name", false, true);
    if (temp.second().valid()) {
        control->set_label(temp.second().image());
        label->set_label(temp.second().name());
    } else {
        control->set_label("");
        label->set_label("");
    }

    control = find_widget<tcontrol>(&window, "third_png", false, true);
    label = find_widget<tlabel>(&window, "third_name", false, true);
    if (temp.third().valid()) {
        control->set_label(temp.third().image());
        label->set_label(temp.third().name());
    } else {
        control->set_label("");
        label->set_label("");
    }

    // leadership
    label = find_widget<tlabel>(&window, "tip_leadership", false, true);
    label->set_label(lexical_cast<std::string>(temp.leadership_));

    // force
    label = find_widget<tlabel>(&window, "tip_force", false, true);
    label->set_label(lexical_cast<std::string>(temp.force_));

    // intellect
    label = find_widget<tlabel>(&window, "tip_intellect", false, true);
    label->set_label(lexical_cast<std::string>(temp.intellect_));

    // politics
    label = find_widget<tlabel>(&window, "tip_politics", false, true);
    label->set_label(lexical_cast<std::string>(temp.politics_));

    // charm
    label = find_widget<tlabel>(&window, "tip_charm", false, true);
    label->set_label(lexical_cast<std::string>(temp.charm_));

    // hp
    label = find_widget<tlabel>(&window, "tip_hp", false, true);
    label->set_label(lexical_cast<std::string>(temp.max_hitpoints()));

    // xp
    label = find_widget<tlabel>(&window, "tip_xp", false, true);
    label->set_label(lexical_cast<std::string>(temp.max_experience()));

    // movement
    label = find_widget<tlabel>(&window, "tip_movement", false, true);
    label->set_label(lexical_cast<std::string>(temp.total_movement()));

    // arm
    label = find_widget<tlabel>(&window, "tip_arm", false, true);
    str << temp.type_name() << "(Lv" << temp.level() << ")";
    label->set_label(str.str());

    // adaptability
    str.str("");
    label = find_widget<tlabel>(&window, "tip_adaptability", false, true);
    str << hero::arms_str(temp.arms()) << "(" << hero::adaptability_str2(ftofxp12(temp.adaptability_[temp.arms()])) << ")";
    label->set_label(str.str());

    // abilities
    str.str("");
    std::vector<std::string> abilities_tt;
    abilities_tt = temp.ability_tooltips(true);
    if (!abilities_tt.empty()) {
        std::vector<t_string> abilities;
        for (std::vector<std::string>::const_iterator a = abilities_tt.begin(); a != abilities_tt.end(); a += 2) {
            abilities.push_back(*a);
        }

        for (std::vector<t_string>::const_iterator a = abilities.begin(); a != abilities.end(); a++) {
            if (a != abilities.begin()) {
                if (a - abilities.begin() != 2) {
                    str << ", ";
                } else {
                    str << "\n";
                }
            }
            str << (*a);
        }
    }
    label = find_widget<tlabel>(&window, "tip_abilities", false, true);
    label->set_label(str.str());

    // feature
    str.str("");
    index = 0;
    for (int i = 0; i < HEROS_MAX_FEATURE; i ++) {
        if (unit_feature_val2(temp, i) == hero_feature_single_result) {
            if (index > 0) {
                if (index != 2) {
                    str << ", ";
                } else {
                    str << "\n";
                }
            }
            index ++;
            str << temp.master().feature_str(i);
        }
    }
    label = find_widget<tlabel>(&window, "tip_feature", false, true);
    label->set_label(str.str());

    // attack
    str.str("");
    std::vector<attack_type>* attacks_ptr = const_cast<std::vector<attack_type>*>(&temp.attacks());
    for (std::vector<attack_type>::const_iterator at_it = attacks_ptr->begin(); at_it != attacks_ptr->end(); ++at_it) {
        // see generate_report() in generate_report.cpp
        str << at_it->name() << " (" << dgettext("wesnoth", at_it->type().c_str()) << ")\n";

        std::string accuracy = at_it->accuracy_parry_description();
        if(accuracy.empty() == false) {
            accuracy += " ";
        }

        str << "  " << at_it->damage() << "-" << at_it->num_attacks()
            << " " << accuracy << "- " << dgettext("wesnoth", at_it->range().c_str());

        std::string special = at_it->weapon_specials(true);
        if (!special.empty()) {
            str << "(" << special << ")";
        }
        str << "\n";
    }
    label = find_widget<tlabel>(&window, "tip_attack", false, true);
    label->set_label(str.str());

    // resistance
    std::set<std::string> resistances_table;
    utils::string_map resistances = temp.get_base_resistances();
    bool att_def_diff = false;
    const map_location& loc = temp.get_location();
    idx_in_resistances = 0;
    for (utils::string_map::iterator resist = resistances.begin(); resist != resistances.end(); ++resist, idx_in_resistances ++) {
        // str << gettext(resist->first.c_str()) << ": ";
        str.str("");

        if (loc.valid()) {
            // Some units have different resistances when
            // attacking or defending.
            int res_att = 100 - temp.resistance_against(resist->first, true, loc);
            int res_def = 100 - temp.resistance_against(resist->first, false, loc);
            if (res_att == res_def) {
                str << res_def;
            } else {
                str << res_att << "% / " << res_def; // (Att / Def)
                att_def_diff = true;
            }
        } else {
            str << 100 - lexical_cast_default<int>(resist->second.c_str());
        }
        str << "%";
        text.str("");
        text << "tip_resistance" << idx_in_resistances;
        label = find_widget<tlabel>(&window, text.str(), false, true);
        label->set_label(str.str());
    }


    // gui_.show_unit_tooltip(temp, window.get_x() + window.get_width(), window.get_y());
}
Beispiel #12
0
const char * KRB5_CALLCONV
error_message(long code)
{
    unsigned long offset;
    unsigned long l_offset;
    struct et_list *e;
    unsigned long table_num;
    int started = 0;
    unsigned int divisor = 100;
    char *cp, *cp1;
    const struct error_table *table;

    if (CALL_INIT_FUNCTION(com_err_initialize))
        return 0;

    l_offset = (unsigned long)code & ((1<<ERRCODE_RANGE)-1);
    offset = l_offset;
    table_num = ((unsigned long)code - l_offset) & ERRCODE_MAX;
    if (table_num == 0
#ifdef __sgi
        /* Irix 6.5 uses a much bigger table than other UNIX
           systems I've looked at, but the table is sparse.  The
           sparse entries start around 500, but sys_nerr is only
           152.  */
        || (code > 0 && code <= 1600)
#endif
    ) {
        if (code == 0)
            goto oops;

        /* This could trip if int is 16 bits.  */
        if ((unsigned long)(int)code != (unsigned long)code)
            abort ();
        cp = get_thread_buffer();
        if (cp && strerror_r(code, cp, ET_EBUFSIZ) == 0)
            return cp;
        return strerror(code);
    }

    k5_mutex_lock(&et_list_lock);
    dprintf(("scanning list for %x\n", table_num));
    for (e = et_list; e != NULL; e = e->next) {
        dprintf(("\t%x = %s\n", e->table->base & ERRCODE_MAX,
                 e->table->msgs[0]));
        if ((e->table->base & ERRCODE_MAX) == table_num) {
            table = e->table;
            goto found;
        }
    }
    goto no_table_found;

found:
    k5_mutex_unlock(&et_list_lock);
    dprintf (("found it!\n"));
    /* This is the right table */

    /* This could trip if int is 16 bits.  */
    if ((unsigned long)(unsigned int)offset != offset)
        goto no_table_found;

    if (table->n_msgs <= (unsigned int) offset)
        goto no_table_found;

    /* If there's a string at the end of the table, it's a text domain. */
    if (table->msgs[table->n_msgs] != NULL)
        return dgettext(table->msgs[table->n_msgs], table->msgs[offset]);
    else
        return table->msgs[offset];

no_table_found:
    k5_mutex_unlock(&et_list_lock);
#if defined(_WIN32)
    /*
     * WinSock errors exist in the 10000 and 11000 ranges
     * but might not appear if WinSock is not initialized
     */
    if (code >= WSABASEERR && code < WSABASEERR + 1100) {
        table_num = 0;
        offset = code;
        divisor = WSABASEERR;
    }
#endif
#ifdef _WIN32
    {
        LPVOID msgbuf;

        if (! FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                             NULL /* lpSource */,
                             (DWORD) code,
                             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                             (LPTSTR) &msgbuf,
                             (DWORD) 0 /*sizeof(buffer)*/,
                             NULL /* va_list */ )) {
            /*
             * WinSock errors exist in the 10000 and 11000 ranges
             * but might not appear if WinSock is not initialized
             */
            if (code >= WSABASEERR && code < WSABASEERR + 1100) {
                table_num = 0;
                offset = code;
                divisor = 10000;
            }

            goto oops;
        } else {
            char *buffer;
            cp = get_thread_buffer();
            if (cp == NULL)
                return "Unknown error code";
            buffer = cp;
            strncpy(buffer, msgbuf, ET_EBUFSIZ);
            buffer[ET_EBUFSIZ-1] = '\0';
            cp = buffer + strlen(buffer) - 1;
            if (*cp == '\n') *cp-- = '\0';
            if (*cp == '\r') *cp-- = '\0';
            if (*cp == '.') *cp-- = '\0';

            LocalFree(msgbuf);
            return buffer;
        }
    }
#endif

oops:

    cp = get_thread_buffer();
    if (cp == NULL)
        return "Unknown error code";
    cp1 = cp;
    strlcpy(cp, "Unknown code ", ET_EBUFSIZ);
    cp += sizeof("Unknown code ") - 1;
    if (table_num != 0L) {
        (void) error_table_name_r(table_num, cp);
        while (*cp != '\0')
            cp++;
        *cp++ = ' ';
    }
    while (divisor > 1) {
        if (started != 0 || offset >= divisor) {
            *cp++ = '0' + offset / divisor;
            offset %= divisor;
            started++;
        }
        divisor /= 10;
    }
    *cp++ = '0' + offset;
    *cp = '\0';
    return(cp1);
}
Beispiel #13
0
int
zfs_key_load(zfs_handle_t *zhp, boolean_t mount, boolean_t share,
    boolean_t recursive)
{
	zfs_handle_t *pzhp = NULL;
	zprop_source_t propsrctype;
	char source[ZFS_MAXNAMELEN];
	char keysource[MAXNAMELEN];
	uint64_t ret, crypt, keystatus;
	zfs_cmd_t zc = { {0 }};
	char errbuf[1024];

    fprintf(stderr, "zfs_key_load\r\n");


	(void) strlcpy(zc.zc_name, zfs_get_name(zhp), sizeof (zc.zc_name));
	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
	    "cannot load key for '%s'"), zc.zc_name);

	zfs_refresh_properties(zhp);

	crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
	if (crypt == ZIO_CRYPT_OFF) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "encryption not enabled on dataset %s."), zc.zc_name);
		return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
	}

	keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);

	if (keystatus == ZFS_CRYPT_KEY_AVAILABLE && !recursive) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "already loaded."));
		return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
	}

	if (zfs_prop_get(zhp, ZFS_PROP_KEYSOURCE, keysource, ZFS_MAXNAMELEN,
	    &propsrctype, source, sizeof (source), FALSE) != 0) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "no keysource property available."));
		return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
	}

	if (propsrctype == ZPROP_SRC_INHERITED) {
#if 0 // FIXME
		if (strcmp(source, ZONE_INVISIBLE_SOURCE) == 0) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "key must be loaded from global zone."));
			return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
		}
#endif
		pzhp = make_dataset_handle(zhp->zfs_hdl, source);
		if (pzhp == NULL) {
			errno = EINVAL;
			return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
		}
		keystatus = zfs_prop_get_int(pzhp, ZFS_PROP_KEYSTATUS);
		zfs_close(pzhp);
	}

	if (propsrctype == ZPROP_SRC_DEFAULT) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "invalid keysource property."));
		return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
	}

	if (!zfs_can_prompt_if_needed(keysource)) {
		errno = ENOTTY;
		return (-1);
	}
	/*
	 * NONE we are the top ds asking for crypto so we
	 * need to get and load the key.
	 *
	 * UNAVAILABLE we need to load the key of a higher level
	 * dataset.
	 *
	 * AVAILABLE we are done other than filling in who we
	 * are inheriting the wrapping key from.
	 */
	if (propsrctype == ZPROP_SRC_INHERITED &&
	    keystatus == ZFS_CRYPT_KEY_AVAILABLE) {
		(void) strlcpy(zc.zc_crypto.zic_inherit_dsname, source,
		    sizeof (zc.zc_crypto.zic_inherit_dsname));
		ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CRYPTO_KEY_INHERIT, &zc);
		goto out;
	}

	zc.zc_crypto.zic_crypt = crypt;

	ret = key_hdl_to_zc(zhp->zfs_hdl, zhp, keysource, crypt, &zc,
	    ZFS_CRYPTO_KEY_LOAD);
	if (ret != 0) {
		if (errno == ENOTTY)
			ret = 0;
		goto out;
	}

	ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CRYPTO_KEY_LOAD, &zc);
out:
	if (ret != 0) {
		if (errno == EACCES) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "incorrect key."));
			return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
		} else if (!recursive) {
			if (errno == EEXIST) {
				zfs_error_aux(zhp->zfs_hdl,
				    dgettext(TEXT_DOMAIN, "already loaded."));
			} else if (zhp->zfs_hdl->libzfs_desc_active == 0) {
				zfs_error_aux(zhp->zfs_hdl, strerror(errno));
			}
			return (zfs_error(zhp->zfs_hdl, EZFS_KEYERR, errbuf));
		}
	}

	zfs_refresh_properties(zhp);
	if (mount) {
		if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
			if (recursive) {
				ret = zfs_mountall(zhp, 0);
			} else {
				ret = zfs_mount(zhp, NULL, 0);
			}
			if (ret == 0 && share) {
				ret = zfs_share(zhp);
			}
		}
	}

	return (ret);
}
Beispiel #14
0
static int
key_hdl_to_zc(libzfs_handle_t *hdl, zfs_handle_t *zhp, char *keysource,
    int crypt, zfs_cmd_t *zc, zfs_crypto_zckey_t cmd)
{
    //	CK_SESSION_HANDLE session;
	int ret = 0;
	key_format_t format;
	key_locator_t locator;
	char *uri;
	//pkcs11_uri_t p11uri;
	size_t keylen = zio_crypt_table[crypt].ci_keylen;
	char *keydata = NULL;
	size_t keydatalen = 0;
	char *tmpkeydata = NULL;
	size_t tmpkeydatalen = 0;
	uint64_t salt;
	//struct cb_arg_curl cb_curl = { 0 };

    fprintf(stderr, "in key_hdl_to_zc\r\n");

	zc->zc_crypto.zic_clone_newkey = hdl->libzfs_crypt.zc_clone_newkey;

	if (!keysource_prop_parser(keysource, &format, &locator, &uri)) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "invalid keysource property."));
		return (-1);
	}

	/*
	 * First check if there was anything in the handle already
	 * if so we use that and we are done with locating the data.
	 * Note that we may be looking at other fields
	 * and zic_clone_newkey even if zc_key_data_len is empty.
	 *
	 * We allow this regardless of the locator so that things
	 * like a PAM module can provide the passphrase but the user
	 * can still have "passphrase,prompt" to use zfs(1M) interactively.
	 */
	if (hdl->libzfs_crypt.zc_key_data_len != 0) {
		keydata = zfs_alloc(hdl, hdl->libzfs_crypt.zc_key_data_len);
		bcopy(hdl->libzfs_crypt.zc_key_data, keydata,
		    hdl->libzfs_crypt.zc_key_data_len);
		keydatalen = hdl->libzfs_crypt.zc_key_data_len;
		goto format_key;
	}

	/*
	 * Get the key from the URI or prompt for it.
	 * If the format is raw then prompting is a simple read(2)
	 * otherwise we put up a prompt saying what we are asking for.
	 * We can't do this with the 'zfs mount -a' that is in
	 * sys:/system/filesystem/local:default but we shouldn't
	 * cause errors or warnings there either.
	 */
	switch (locator) {
	case KEY_LOCATOR_PROMPT:
		if (format == KEY_FORMAT_RAW) {
			keydata = zfs_alloc(hdl, keylen);
			errno = 0;
			keydatalen = read(STDIN_FILENO, keydata, keylen);
			if (keydatalen != keylen) {
				free(keydata);
				return (-1);
			}

		} else {
			int tries = 0;
			do {
				/* get_passphrase allocates keydata */
				ret = get_passphrase(hdl, &keydata,
				    &keydatalen, format, zc, cmd);
			} while (ret != 0 && ++tries < 3);
			if (ret)
				return (-1);
		}
		break;
	case KEY_LOCATOR_FILE_URI:
		/*
		 * Need to tell pkcs11_read_data() how big of a key
		 * we want in case the locator URI is a device (eg, /dev/random)
		 * to be read from and not a file.
		 *
		 * Note that pkcs11_read_data allocates memory with malloc
		 * that we need to free.
		 */
#if 0 // FIXME
		keydatalen = keylen;
		ret = pkcs11_read_data(&(uri[7]),
		    (void **)&keydata, &keydatalen);
		if (ret != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "failed to read key file: %s"), strerror(ret));
			errno = ret;
			return (-1);
		}
#endif
		break;

	case KEY_LOCATOR_PKCS11_URI:
#if 0 // FIXME
		keydatalen = keylen;
		/*
		 * Parse out the PKCS#11 URI and
		 * get the value of the wrapping key.
		 */
		if (pkcs11_parse_uri(uri, &p11uri) != PK11_URI_OK) {
			errno = EINVAL;
			return (-1);
		}
		ret = get_pkcs11_key_value(hdl, zc, cmd, &p11uri,
		    &keydata, &keydatalen);
		pkcs11_free_uri(&p11uri);
		if (ret != 0) {
			return (-1);
		}
#endif
		break;
	case KEY_LOCATOR_HTTPS_URI: {
#if 0
		CURL *curl_hdl = curl_easy_init();
		CURLcode cerr;

		cerr = curl_easy_setopt(curl_hdl, CURLOPT_URL, uri);
		if (cerr != CURLE_OK)
			goto curl_fail;
		cerr = curl_easy_setopt(curl_hdl, CURLOPT_FAILONERROR, 1L);
		if (cerr != CURLE_OK)
			goto curl_fail;
		cerr = curl_easy_setopt(curl_hdl, CURLOPT_WRITEFUNCTION,
		    get_keydata_curl);
		if (cerr != CURLE_OK)
			goto curl_fail;
		cb_curl.cb_hdl = hdl;
		cerr = curl_easy_setopt(curl_hdl, CURLOPT_WRITEDATA,
		    &cb_curl);
		if (cerr != CURLE_OK)
			goto curl_fail;
		cerr = curl_easy_perform(curl_hdl);
curl_fail:
		/*
		 * Just deal with libcurl errors here, reading the wrong key
		 * size is dealt with generically in the format_key section.
		 */
		if (cerr != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "failed to retreive key from '%s': '%s'"),
			    uri, curl_easy_strerror(cerr));
			return (-1);
		}

		keydata = cb_curl.cb_keydata;
		keydatalen = cb_curl.cb_keydatalen;

		curl_easy_cleanup(curl_hdl);
#endif
		break;

        case KEY_LOCATOR_NONE: // Avoid Warning
            break;
		}
	}

format_key:
	if (keydata == NULL || keydatalen == 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "key can not be of zero size"));
		errno = ret;
		return (-1);
	}

	/*
	 * Now that we have the key do any transform that is necessary
	 * such as turning the hex format into raw or in the case of
	 * a passphrase running it through PKCS#5 to get the raw key.
	 *
	 * Note that zic_keydata is not malloc'd memory so that we
	 * don't have to worry about our caller freeing it.
	 */
	switch (format) {
	case KEY_FORMAT_RAW:
		bcopy(keydata, zc->zc_crypto.zic_keydata, keydatalen);
		zc->zc_crypto.zic_keydatalen = keydatalen;
		zc->zc_crypto.zic_salt = 0;
		break;
	case KEY_FORMAT_HEX:
		/*
		 * If the keylen is not on the byte boundary, in terms of hex
		 * format, and that extra char is a linefeed, we can trim it
		 */
		if (keydatalen == (keylen * 2) + 1 &&
		    keydata[keydatalen] == '\n') {
			keydatalen--;
		}

		/*
		 * hexstr_to_bytes allocates memory with malloc
		 * but we want the data in zic_keydata which isn't malloc'd
		 * so to avoid a memory leak we use a tmpkeydata buffer
		 * and bcopy it.
		 */
#if 0        // FIXME
		ret = hexstr_to_bytes(keydata, keydatalen,
		    (uchar_t **)&tmpkeydata, &tmpkeydatalen);
#endif

		if (ret) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "invalid hex format key."));
			errno = EACCES;
			ret = -1;
			goto out;
		}

		bcopy(tmpkeydata, zc->zc_crypto.zic_keydata, tmpkeydatalen);
		bzero(tmpkeydata, tmpkeydatalen);
		free(tmpkeydata);
		zc->zc_crypto.zic_keydatalen = tmpkeydatalen;
		zc->zc_crypto.zic_salt = 0;
		break;
	case KEY_FORMAT_PASSPHRASE:
		/* Remove any extra linefeed that may be on the end */
		if (keydata[keydatalen - 1] == '\n')
			keydatalen--;

		if (cmd == ZFS_CRYPTO_KEY_LOAD) {
			salt = zfs_prop_get_int(zhp, ZFS_PROP_SALT);
		} else {
#if 0 // FIXME
			ret = pkcs11_get_random(&salt, sizeof (uint64_t));
			if (ret) {
				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				    "failed to obtain salt: %s."),
				    pkcs11_strerror(ret));
				errno = EINVAL;
				ret = -1;
				goto out;
			}
#endif
		}

        fprintf(stderr, "Key is '%s' and is len %u\r\n",
                keydata, keydatalen);

        // FIXME
        tmpkeydata = strdup(keydata);
        tmpkeydatalen = keydatalen;
        salt = 0x1234;

#if 0 // FIXME
		ret = SUNW_C_GetMechSession(CKM_PKCS5_PBKD2, &session);
		if (ret) {
			zfs_error_aux(hdl,
			    dgettext(TEXT_DOMAIN,
			    "failed to access CKM_PKCS5_PBKD2: %s."),
			    pkcs11_strerror(ret));
			errno = EINVAL;
			ret = -1;
			goto out;
		}

		/*
		 * pkcs11_PasswdToKey allocates memory with malloc
		 * but we want the data in zic_keydata which isn't malloc'd
		 * so to avoid a memory leak we use a tmpkeydata buffer
		 * and bcopy it.
		 */
		ret = pkcs11_PasswdToKey(session, keydata, keydatalen,
		    (void *)&salt, sizeof (uint64_t), CKK_AES,
		    keylen, (void **)&tmpkeydata, &tmpkeydatalen);

		(void) C_CloseSession(session);

		if (ret) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "failed to generate key: %s."),
			    pkcs11_strerror(ret));
			errno = EINVAL;
			ret = -1;
			goto out;
		}
#endif

		bcopy(tmpkeydata, zc->zc_crypto.zic_keydata, tmpkeydatalen);
		bzero(tmpkeydata, tmpkeydatalen);
		free(tmpkeydata);
		zc->zc_crypto.zic_keydatalen = tmpkeydatalen;
		zc->zc_crypto.zic_salt = salt;
		break;

	default:
		ASSERT(format);
	}

	if (zc->zc_crypto.zic_keydatalen != keylen) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "key length invalid. expected %lu bytes have %lu"),
		    keylen, zc->zc_crypto.zic_keydatalen);
		errno = EIO;
		ret = -1;
	}

    if (tmpkeydatalen) // Only decrease if NOT zero.
        tmpkeydatalen--;
	while (zc->zc_crypto.zic_keydata[tmpkeydatalen] == 0 &&
	    tmpkeydatalen > 0)
		tmpkeydatalen--;

	if (tmpkeydatalen == 0) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
                                    "invalid all zeros key %lu"), tmpkeydatalen);
		errno = EIO;
		ret = -1;
	}
out:
	if (keydata) {
		bzero(keydata, keydatalen);
		free(keydata);
	}

	return (ret);
}
Beispiel #15
0
int fontforge_main( int argc, char **argv ) {
    extern const char *source_modtime_str;
    extern const char *source_version_str;
    const char *load_prefs = getenv("FONTFORGE_LOADPREFS");
    int i;
    int recover=2;
    int any;
    int next_recent=0;
    GRect pos;
    GWindowAttrs wattrs;
    char *display = NULL;
    FontRequest rq;
    int ds, ld;
    int openflags=0;
    int doopen=0, quit_request=0;
    bool use_cairo = true;

#if !(GLIB_CHECK_VERSION(2, 35, 0))
    g_type_init();
#endif

    /* Must be done before we cache the current directory */
    /* Change to HOME dir if specified on the commandline */
    for ( i=1; i<argc; ++i ) {
	char *pt = argv[i];
	if ( pt[0]=='-' && pt[1]=='-' ) ++pt;
	if (strcmp(pt,"-home")==0 || strncmp(pt,"-psn_",5)==0) {
	    /* OK, I don't know what _-psn_ means, but to GW it means */
	    /* we've been started on the mac from the FontForge.app   */
	    /* structure, and the current directory is (shudder) "/"  */
	    if (getenv("HOME")!=NULL) chdir(getenv("HOME"));
	    break;	/* Done - Unnecessary to check more arguments */
	}
	if (strcmp(pt,"-quiet")==0)
	    quiet = 1;
    }

    if (!quiet) {
        fprintf( stderr, "Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.\n" );
        fprintf( stderr, " License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n" );
        fprintf( stderr, " with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.\n" );
        fprintf( stderr, " Based on sources from %s"
	        "-ML"
#ifdef FREETYPE_HAS_DEBUGGER
	        "-TtfDb"
#endif
#ifdef _NO_PYTHON
	        "-NoPython"
#endif
#ifdef FONTFORGE_CONFIG_USE_DOUBLE
	        "-D"
#endif
	        ".\n",
	        FONTFORGE_MODTIME_STR );
        fprintf( stderr, " Based on source from git with hash: %s\n", FONTFORGE_GIT_VERSION );
    }

#if defined(__Mac)
    /* Start X if they haven't already done so. Well... try anyway */
    /* Must be before we change DYLD_LIBRARY_PATH or X won't start */
    /* (osascript depends on a libjpeg which isn't found if we look in /sw/lib first */
    int local_x = uses_local_x(argc,argv);
    if ( local_x==1 && getenv("DISPLAY")==NULL ) {
	/* Don't start X if we're just going to quit. */
	/* if X exists, it isn't needed. If X doesn't exist it's wrong */
	if ( !hasquit(argc,argv)) {
	    /* This sequence is supposed to bring up an app without a window */
	    /*  but X still opens an xterm */
	    system( "osascript -e 'tell application \"X11\" to launch'" );
	    system( "osascript -e 'tell application \"X11\" to activate'" );
	}
	setenv("DISPLAY",":0.0",0);
    } else if ( local_x==1 && *getenv("DISPLAY")!='/' && strcmp(getenv("DISPLAY"),":0.0")!=0 && strcmp(getenv("DISPLAY"),":0")!=0 )
	/* 10.5.7 uses a named socket or something "/tmp/launch-01ftWX:0" */
	local_x = 0;
#endif

#if defined(__MINGW32__)
    if( getenv("DISPLAY")==NULL ) {
	putenv("DISPLAY=127.0.0.1:0.0");
    }
    if( getenv("LC_ALL")==NULL ){
	char lang[8];
	char env[32];
	if( GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, 8) > 0 ){
	    strcpy(env, "LC_ALL=");
	    strcat(env, lang);
	    putenv(env);
	}
    }
#endif

    FF_SetUiInterface(&gdraw_ui_interface);
    FF_SetPrefsInterface(&gdraw_prefs_interface);
    FF_SetSCInterface(&gdraw_sc_interface);
    FF_SetCVInterface(&gdraw_cv_interface);
    FF_SetBCInterface(&gdraw_bc_interface);
    FF_SetFVInterface(&gdraw_fv_interface);
    FF_SetFIInterface(&gdraw_fi_interface);
    FF_SetMVInterface(&gdraw_mv_interface);
    FF_SetClipInterface(&gdraw_clip_interface);
#ifndef _NO_PYTHON
    PythonUI_Init();
#endif

    FindProgDir(argv[0]);
    InitSimpleStuff();

#if defined(__MINGW32__)
    {
        char path[MAX_PATH];
        unsigned int len = GetModuleFileNameA(NULL, path, MAX_PATH);
        path[len] = '\0';
        
        //The '.exe' must be removed as resources presumes it's not there.
        GResourceSetProg(GFileRemoveExtension(GFileNormalizePath(path)));
    }
#else
    GResourceSetProg(argv[0]);
#endif

#if defined(__Mac)
    /* The mac seems to default to the "C" locale, LANG and LC_MESSAGES are not*/
    /*  defined. This means that gettext will not bother to look up any message*/
    /*  files -- even if we have a "C" or "POSIX" entry in the locale diretory */
    /* Now if X11 gives us the command key, I want to force a rebinding to use */
    /*  Cmd rather than Control key -- more mac-like. But I can't do that if   */
    /*  there is no locale. So I force a locale if there is none specified */
    /* I force the US English locale, because that's the what the messages are */
    /*  by default so I'm changing as little as I can. I think. */
    /* Now the locale command will treat a LANG which is "" as undefined, but */
    /*  gettext will not. So I don't bother to check for null strings or "C"  */
    /*  or "POSIX". If they've mucked with the locale perhaps they know what  */
    /*  they are doing */
    {
	int did_keybindings = 0;
	int useCommandKey = get_mac_x11_prop("enable_key_equivalents") <= 0;

	if ( local_x && useCommandKey ) {
	    hotkeySystemSetCanUseMacCommand( 1 );

	    /* Ok, we get the command key */
	    if ( getenv("LANG")==NULL && getenv("LC_MESSAGES")==NULL ) {
		setenv("LC_MESSAGES","en_US.UTF-8",0);
	    }
	    /* Can we find a set of keybindings designed for the mac with cmd key? */
	    bind_textdomain_codeset("Mac-FontForge-MenuShortCuts","UTF-8");
	    bindtextdomain("Mac-FontForge-MenuShortCuts", getLocaleDir());
	    if ( *dgettext("Mac-FontForge-MenuShortCuts","Flag0x10+")!='F' ) {
		GMenuSetShortcutDomain("Mac-FontForge-MenuShortCuts");
		did_keybindings = 1;
	    }
	}
	if ( !did_keybindings ) {
	    /* Nope. we can't. Fall back to the normal stuff */
#endif
	    GMenuSetShortcutDomain("FontForge-MenuShortCuts");
	    bind_textdomain_codeset("FontForge-MenuShortCuts","UTF-8");
	    bindtextdomain("FontForge-MenuShortCuts", getLocaleDir());
#if defined(__Mac)
	}
    }
#endif
    bind_textdomain_codeset("FontForge","UTF-8");
    bindtextdomain("FontForge", getLocaleDir());
    textdomain("FontForge");
    GResourceUseGetText();
    {
	char shareDir[PATH_MAX];
	char* sd = getShareDir();
	strncpy( shareDir, sd, PATH_MAX );
    shareDir[PATH_MAX-1] = '\0';
	if(!sd) {
	    strcpy( shareDir, SHAREDIR );
	}

	char path[PATH_MAX];
	snprintf(path, PATH_MAX, "%s%s", shareDir, "/pixmaps" );
	GGadgetSetImageDir( path );

	snprintf(path, PATH_MAX, "%s%s", shareDir, "/resources/fontforge.resource" );
	GResourceAddResourceFile(path, GResourceProgramName,false);
    }
    hotkeysLoad();
//    loadPrefsFiles();
    Prefs_LoadDefaultPreferences();

    if ( load_prefs!=NULL && strcasecmp(load_prefs,"Always")==0 )
	LoadPrefs();
    if ( default_encoding==NULL )
	default_encoding=FindOrMakeEncoding("ISO8859-1");
    if ( default_encoding==NULL )
	default_encoding=&custom;	/* In case iconv is broken */

    // This no longer starts embedded Python unless control passes to the Python executors,
    // which exit independently rather than returning here.
    CheckIsScript(argc,argv); /* Will run the script and exit if it is a script */
					/* If there is no UI, there is always a script */
			                /*  and we will never return from the above */
    if ( load_prefs==NULL ||
	    (strcasecmp(load_prefs,"Always")!=0 &&	/* Already loaded */
	     strcasecmp(load_prefs,"Never")!=0 ))
	LoadPrefs();
    GrokNavigationMask();
    for ( i=1; i<argc; ++i ) {
	char *pt = argv[i];
	if ( pt[0]=='-' && pt[1]=='-' )
	    ++pt;
	if ( strcmp(pt,"-sync")==0 )
	    GResourceAddResourceString("Gdraw.Synchronize: true",argv[0]);
	else if ( strcmp(pt,"-depth")==0 && i<argc-1 )
	    AddR(argv[0],"Gdraw.Depth", argv[++i]);
	else if ( strcmp(pt,"-vc")==0 && i<argc-1 )
	    AddR(argv[0],"Gdraw.VisualClass", argv[++i]);
	else if ( (strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0) && i<argc-1 )
	    AddR(argv[0],"Gdraw.Colormap", argv[++i]);
	else if ( (strcmp(pt,"-dontopenxdevices")==0) )
	    AddR(argv[0],"Gdraw.DontOpenXDevices", "true");
	else if ( strcmp(pt,"-keyboard")==0 && i<argc-1 )
	    AddR(argv[0],"Gdraw.Keyboard", argv[++i]);
	else if ( strcmp(pt,"-display")==0 && i<argc-1 )
	    display = argv[++i];
# if MyMemory
	else if ( strcmp(pt,"-memory")==0 )
	    __malloc_debug(5);
# endif
	else if ( strncmp(pt,"-usecairo",strlen("-usecairo"))==0 ) {
	    if ( strcmp(pt,"-usecairo=no")==0 )
	        use_cairo = false;
	    else
	        use_cairo = true;
	    GDrawEnableCairo(use_cairo);
	} else if ( strcmp(pt,"-nosplash")==0 )
	    splash = 0;
	else if ( strcmp(pt,"-quiet")==0 )
	    /* already checked for this earlier, no need to do it again */;
	else if ( strcmp(pt,"-unique")==0 )
	    unique = 1;
	else if ( strcmp(pt,"-forceuihidden")==0 )
	    cmdlinearg_forceUIHidden = 0;
	else if ( strcmp(pt,"-recover")==0 && i<argc-1 ) {
	    ++i;
	    if ( strcmp(argv[i],"none")==0 )
		recover=0;
	    else if ( strcmp(argv[i],"clean")==0 )
		recover= -1;
	    else if ( strcmp(argv[i],"auto")==0 )
		recover= 1;
	    else if ( strcmp(argv[i],"inquire")==0 )
		recover= 2;
	    else {
		fprintf( stderr, "Invalid argument to -recover, must be none, auto, inquire or clean\n" );
		dousage();
	    }
	} else if ( strcmp(pt,"-recover=none")==0 ) {
	    recover = 0;
	} else if ( strcmp(pt,"-recover=clean")==0 ) {
	    recover = -1;
	} else if ( strcmp(pt,"-recover=auto")==0 ) {
	    recover = 1;
	} else if ( strcmp(pt,"-recover=inquire")==0 ) {
	    recover = 2;
	} else if ( strcmp(pt,"-docs")==0 )
	    dohelp();
	else if ( strcmp(pt,"-help")==0 )
	    dousage();
	else if ( strcmp(pt,"-version")==0 || strcmp(pt,"-v")==0 || strcmp(pt,"-V")==0 )
	    doversion(FONTFORGE_MODTIME_STR);
	else if ( strcmp(pt,"-quit")==0 )
	    quit_request = true;
	else if ( strcmp(pt,"-home")==0 )
	    /* already did a chdir earlier, don't need to do it again */;
#if defined(__Mac)
	else if ( strncmp(pt,"-psn_",5)==0 ) {
	    /* OK, I don't know what _-psn_ means, but to GW it means */
	    /* we've been started on the mac from the FontForge.app   */
	    /* structure, and the current directory was (shudder) "/" */
	    /* (however, we changed to HOME earlier in main routine). */
	    unique = 1;
	    listen_to_apple_events = true; // This has been problematic on Mavericks and later.
	}
#endif
    }

    ensureDotFontForgeIsSetup();
#if defined(__MINGW32__) && !defined(_NO_LIBCAIRO)
    //Load any custom fonts for the user interface
    if (use_cairo) {
        char *system_load = getGResourceProgramDir();
        char *user_load = getFontForgeUserDir(Data);
        char lbuf[MAX_PATH];
        int lret;

        if (system_load != NULL) {
            //Follow the FontConfig APPSHAREFONTDIR location
            lret = snprintf(lbuf, MAX_PATH, "%s/../share/fonts", system_load);
            if (lret > 0 && lret < MAX_PATH) {
                WinLoadUserFonts(lbuf);
            }
        }
        if (user_load != NULL) {
            lret = snprintf(lbuf, MAX_PATH, "%s/%s", user_load, "ui-fonts");
            if (lret > 0 && lret < MAX_PATH) {
                WinLoadUserFonts(lbuf);
            }
            free(user_load);
        }
    }
#endif
    InitImageCache(); // This is in gtextinfo.c. It zeroes imagecache for us.
    atexit(&ClearImageCache); // We register the destructor, which is also in gtextinfo.c.
    GDrawCreateDisplays(display,argv[0]);
    atexit(&GDrawDestroyDisplays); // We register the destructor so that it runs even if we call exit without finishing this function.
    default_background = GDrawGetDefaultBackground(screen_display);
    InitToolIconClut(default_background);
    InitToolIcons();
    InitCursors();

    /**
     * we have to do a quick sniff of argv[] here to see if the user
     * wanted to skip loading these python init files.
     */
    for ( i=1; i<argc; ++i ) {
	char *pt = argv[i];

	if ( !strcmp(pt,"-SkipPythonInitFiles")) {
	    ProcessPythonInitFiles = 0;
	}
    }
    
#ifndef _NO_PYTHON
/*# ifndef GWW_TEST*/
    FontForge_InitializeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */
/*# endif*/
#endif

#ifndef _NO_PYTHON
    if( ProcessPythonInitFiles )
	PyFF_ProcessInitFiles();
#endif

    /* the splash screen used not to have a title bar (wam_nodecor) */
    /*  but I found I needed to know how much the window manager moved */
    /*  the window around, which I can determine if I have a positioned */
    /*  decorated window created at the begining */
    /* Actually I don't care any more */
    wattrs.mask = wam_events|wam_cursor|wam_bordwidth|wam_backcol|wam_positioned|wam_utf8_wtitle|wam_isdlg;
    wattrs.event_masks = ~(1<<et_charup);
    wattrs.positioned = 1;
    wattrs.cursor = ct_pointer;
    wattrs.utf8_window_title = "FontForge";
    wattrs.border_width = 2;
    wattrs.background_color = 0xffffff;
    wattrs.is_dlg = !listen_to_apple_events;
    pos.x = pos.y = 200;
    pos.width = splashimage.u.image->width;
    pos.height = splashimage.u.image->height-56;		/* 54 */
    GDrawBindSelection(NULL,sn_user1,"FontForge");
    if ( unique && GDrawSelectionOwned(NULL,sn_user1)) {
	/* Different event handler, not a dialog */
	wattrs.is_dlg = false;
	splashw = GDrawCreateTopWindow(NULL,&pos,request_e_h,NULL,&wattrs);
	PingOtherFontForge(argc,argv);
    } else {
	if ( quit_request )
exit( 0 );
	splashw = GDrawCreateTopWindow(NULL,&pos,splash_e_h,NULL,&wattrs);
    }

    memset(&rq,0,sizeof(rq));
    rq.utf8_family_name = SERIF_UI_FAMILIES;
    rq.point_size = 12;
    rq.weight = 400;
    splash_font = GDrawInstanciateFont(NULL,&rq);
    splash_font = GResourceFindFont("Splash.Font",splash_font);
    GDrawDecomposeFont(splash_font, &rq);
    rq.style = fs_italic;
    splash_italic = GDrawInstanciateFont(NULL,&rq);
    splash_italic = GResourceFindFont("Splash.ItalicFont",splash_italic);
    GDrawSetFont(splashw,splash_font);

    SplashLayout();
    localsplash = splash;

   if ( localsplash && !listen_to_apple_events )
	start_splash_screen();

    //
    // The below call will initialize the fontconfig cache if required.
    // That can take a while the first time it happens.
    //
   GDrawWindowFontMetrics(splashw,splash_font,&as,&ds,&ld);
   fh = as+ds+ld;

    if ( AutoSaveFrequency>0 )
	autosave_timer=GDrawRequestTimer(splashw,2*AutoSaveFrequency*1000,AutoSaveFrequency*1000,NULL);

    GDrawProcessPendingEvents(NULL);
    GDrawSetBuildCharHooks(BuildCharHook,InsCharHook);

    any = 0;
    if ( recover==-1 )
	CleanAutoRecovery();
    else if ( recover )
	any = DoAutoRecoveryExtended( recover-1 );
			
    openflags = 0;
    for ( i=1; i<argc; ++i ) {
	char buffer[1025];
	char *pt = argv[i];

	GDrawProcessPendingEvents(NULL);
	if ( pt[0]=='-' && pt[1]=='-' && pt[2]!='\0')
	    ++pt;
	if ( strcmp(pt,"-new")==0 ) {
	    FontNew();
	    any = 1;
#  if HANYANG
	} else if ( strcmp(pt,"-newkorean")==0 ) {
	    MenuNewComposition(NULL,NULL,NULL);
	    any = 1;
#  endif
	} else if ( !strcmp(pt,"-SkipPythonInitFiles")) {
	    // already handled above.
	} else if ( strcmp(pt,"-last")==0 ) {
	    if ( next_recent<RECENT_MAX && RecentFiles[next_recent]!=NULL )
		if ( ViewPostScriptFont(RecentFiles[next_recent++],openflags))
		    any = 1;
	} else if ( strcmp(pt,"-sync")==0 || strcmp(pt,"-memory")==0 ||
		    strcmp(pt,"-nosplash")==0 || strcmp(pt,"-recover=none")==0 ||
		    strcmp(pt,"-recover=clean")==0 || strcmp(pt,"-recover=auto")==0 ||
		    strcmp(pt,"-dontopenxdevices")==0 || strcmp(pt,"-unique")==0 ||
		    strncmp(pt,"-usecairo",strlen("-usecairo"))==0 ||
		    strcmp(pt,"-home")==0 || strcmp(pt,"-quiet")==0
		    || strcmp(pt,"-forceuihidden")==0 )
	    /* Already done, needed to be before display opened */;
	else if ( strncmp(pt,"-psn_",5)==0 )
	    /* Already done */;
	else if ( (strcmp(pt,"-depth")==0 || strcmp(pt,"-vc")==0 ||
		    strcmp(pt,"-cmap")==0 || strcmp(pt,"-colormap")==0 ||
		    strcmp(pt,"-keyboard")==0 ||
		    strcmp(pt,"-display")==0 || strcmp(pt,"-recover")==0 ) &&
		i<argc-1 )
	    ++i; /* Already done, needed to be before display opened */
	else if ( strcmp(pt,"-allglyphs")==0 )
	    openflags |= of_all_glyphs_in_ttc;
	else if ( strcmp(pt,"-open")==0 )
	    doopen = true;
	else {
	    printf("else argv[i]:%s\n", argv[i] );
	    if ( strstr(argv[i],"://")!=NULL ) {		/* Assume an absolute URL */
		strncpy(buffer,argv[i],sizeof(buffer));
		buffer[sizeof(buffer)-1]= '\0';
	    } else
		GFileGetAbsoluteName(argv[i],buffer,sizeof(buffer));
	    if ( GFileIsDir(buffer) || (strstr(buffer,"://")!=NULL && buffer[strlen(buffer)-1]=='/')) {
		char *fname;
		fname = malloc(strlen(buffer)+strlen("/glyphs/contents.plist")+1);
		strcpy(fname,buffer); strcat(fname,"/glyphs/contents.plist");
		if ( GFileExists(fname)) {
		    /* It's probably a Unified Font Object directory */
		    free(fname);
		    if ( ViewPostScriptFont(buffer,openflags) )
			any = 1;
		} else {
		    strcpy(fname,buffer); strcat(fname,"/font.props");
		    if ( GFileExists(fname)) {
			/* It's probably a sf dir collection */
			free(fname);
			if ( ViewPostScriptFont(buffer,openflags) )
			    any = 1;
		    } else {
			free(fname);
			if ( buffer[strlen(buffer)-1]!='/' ) {
			    /* If dirname doesn't end in "/" we'll be looking in parent dir */
			    buffer[strlen(buffer)+1]='\0';
			    buffer[strlen(buffer)] = '/';
			}
			fname = GetPostScriptFontName(buffer,false);
			if ( fname!=NULL )
			    ViewPostScriptFont(fname,openflags);
			any = 1;	/* Even if we didn't get a font, don't bring up dlg again */
			free(fname);
		    }
		}
	    } else if ( ViewPostScriptFont(buffer,openflags)!=0 )
		any = 1;
	}
    }
    if ( !any && !doopen )
	any = ReopenLastFonts();

    collabclient_ensureClientBeacon();
    collabclient_sniffForLocalServer();
#ifndef _NO_PYTHON
    PythonUI_namedpipe_Init();
#endif

#if defined(__Mac)
    if ( listen_to_apple_events ) {
	install_apple_event_handlers();
	install_mac_timer();
	setup_cocoa_app();

	
	// WARNING: See declaration of RunApplicationEventLoop() above as to
	// why you might not want to call that function anymore.
	// RunApplicationEventLoop();
	
    } else
#endif
    if ( doopen || !any )
	_FVMenuOpen(NULL);
    GDrawEventLoop(NULL);
    GDrawDestroyDisplays();

#ifndef _NO_PYTHON
/*# ifndef GWW_TEST*/
    FontForge_FinalizeEmbeddedPython(); /* !!!!!! debug (valgrind doesn't like python) */
/*# endif*/
#endif

    // These free menu translations, mostly.
    BitmapViewFinishNonStatic();
    MetricsViewFinishNonStatic();
    CharViewFinishNonStatic();
    FontViewFinishNonStatic();

    ClearImageCache(); // This frees the contents of imagecache.
    hotkeysSave();
    LastFonts_Save();

#ifndef _NO_LIBUNICODENAMES
    uninm_names_db_close(names_db);	/* close this database before exiting */
    uninm_blocks_db_close(blocks_db);
#endif

    lt_dlexit();

return( 0 );
}
static gboolean _show_group_dialog (CairoDockGroupDescription *pGroupDescription)
{
	gchar *cDescription = NULL;
	if (pGroupDescription->cDescription != NULL)
	{
		if (*pGroupDescription->cDescription == '/')
		{
			//g_print ("on recupere la description de %s\n", pGroupDescription->cDescription);
			
			gsize length = 0;
			GError *erreur = NULL;
			g_file_get_contents (pGroupDescription->cDescription,
				&cDescription,
				&length,
				&erreur);
			if (erreur != NULL)
			{
				cd_warning (erreur->message);
				g_error_free (erreur);
			}
		}
	}
	
	int iPreviewWidgetWidth;
	GtkWidget *pPreviewImage = cairo_dock_get_preview_image (&iPreviewWidgetWidth);
	if (pGroupDescription->cPreviewFilePath != NULL && strcmp (pGroupDescription->cPreviewFilePath, "none") != 0)
	{
		//g_print ("on recupere la prevue de %s\n", pGroupDescription->cPreviewFilePath);
		int iPreviewWidth, iPreviewHeight;
		GdkPixbuf *pPreviewPixbuf = NULL;
		if (gdk_pixbuf_get_file_info (pGroupDescription->cPreviewFilePath, &iPreviewWidth, &iPreviewHeight) != NULL)
		{
			if (iPreviewWidth > CAIRO_DOCK_PREVIEW_WIDTH)
			{
				iPreviewHeight *= 1.*CAIRO_DOCK_PREVIEW_WIDTH/iPreviewWidth;
				iPreviewWidth = CAIRO_DOCK_PREVIEW_WIDTH;
			}
			if (iPreviewHeight > CAIRO_DOCK_PREVIEW_HEIGHT)
			{
				iPreviewWidth *= 1.*CAIRO_DOCK_PREVIEW_HEIGHT/iPreviewHeight;
				iPreviewHeight = CAIRO_DOCK_PREVIEW_HEIGHT;
			}
			if (iPreviewWidth > iPreviewWidgetWidth)
			{
				iPreviewHeight *= 1.*iPreviewWidgetWidth/iPreviewWidth;
				iPreviewWidth = iPreviewWidgetWidth;
			}
			g_print ("preview : %dx%d\n", iPreviewWidth, iPreviewHeight);
			pPreviewPixbuf = gdk_pixbuf_new_from_file_at_size (pGroupDescription->cPreviewFilePath, iPreviewWidth, iPreviewHeight, NULL);
		}
		if (pPreviewPixbuf == NULL)
		{
			cd_warning ("pas de prevue disponible");
			pPreviewPixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
				TRUE,
				8,
				1,
				1);
		}
		gtk_image_set_from_pixbuf (GTK_IMAGE (pPreviewImage), pPreviewPixbuf);
		gdk_pixbuf_unref (pPreviewPixbuf);
		gtk_widget_show (pPreviewImage);
	}
	
	if (s_pDialog != NULL)
		if (! cairo_dock_dialog_unreference (s_pDialog))
			cairo_dock_dialog_unreference (s_pDialog);
	Icon *pIcon = cairo_dock_get_current_active_icon ();
	if (pIcon == NULL || pIcon->cParentDockName == NULL || pIcon->fPersonnalScale > 0)
		pIcon = cairo_dock_get_dialogless_icon ();
	CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon != NULL ? pIcon->cParentDockName : NULL);
	s_pDialog = cairo_dock_show_temporary_dialog_with_icon (dgettext (pGroupDescription->cGettextDomain, cDescription != NULL ? cDescription : pGroupDescription->cDescription), pIcon, CAIRO_CONTAINER (pDock), 0., pGroupDescription->cIcon);
	cairo_dock_dialog_reference (s_pDialog);
	
	g_free (cDescription);

	s_iSidShowGroupDialog = 0;
	return FALSE;
}
Beispiel #17
0
const char*
_inf_gettext(const char* msgid)
{
  return dgettext(GETTEXT_PACKAGE, msgid);
}
Beispiel #18
0
/*
 * Search the list of devices under SVM for the specified device.
 */
int
inuse_svm(char *slice, nvlist_t *attrs, int *errp)
{
	struct svm_list	*listp;
	int		found = 0;

	*errp = 0;
	if (slice == NULL) {
	    return (found);
	}

	(void) mutex_lock(&init_lock);
	if (!initialized) {
		/* dynamically load libmeta */
		if (init_svm()) {
			/*
			 * need to initialize the cluster library to
			 * avoid seg faults
			 */
			(mdl_sdssc_bind_library)();

			/* load the SVM cache */
			*errp = load_svm();

			if (*errp == 0) {
				/* start a thread to monitor the svm config */
				sysevent_handle_t *shp;
				const char *subclass_list[1];
				/*
				 * Only start the svmevent thread if
				 * we are not doing an install
				 */

				if (getenv("_LIBDISKMGT_INSTALL") == NULL) {
					shp = sysevent_bind_handle(
					    event_handler);
					if (shp != NULL) {
						subclass_list[0] = EC_SUB_ALL;
						if (sysevent_subscribe_event(
						    shp, EC_SVM_CONFIG,
						    subclass_list, 1) != 0) {
							*errp = errno;
						}
					} else {
						*errp = errno;
					}
					if (*errp) {
						/*
						 * If the sysevent thread fails,
						 * log the error but continue
						 * on. This failing to start
						 * is not catastrophic in
						 * particular for short lived
						 * consumers of libdiskmgt.
						 */
						syslog(LOG_WARNING,
						    dgettext(TEXT_DOMAIN,
						    "libdiskmgt: sysevent "
						    "thread for SVM failed "
						    "to start\n"));
						*errp = 0;
					}
				}
			}
		}

		if (*errp == 0) {
			initialized = 1;
		}
	}
	(void) mutex_unlock(&init_lock);

	(void) rw_rdlock(&svm_lock);
	listp = svm_listp;
	while (listp != NULL) {
	    if (strcmp(slice, listp->slice) == 0) {
		libdiskmgt_add_str(attrs, DM_USED_BY, DM_USE_SVM, errp);
		if (strcmp(listp->type, "mdb") == 0 ||
		    strcmp(listp->type, "hs") == 0) {

		    libdiskmgt_add_str(attrs, DM_USED_NAME, listp->type, errp);
		} else {
		    char name[MAXPATHLEN];
		    (void) snprintf(name, MAXPATHLEN, "%s:%s", listp->type,
			listp->name);
		    libdiskmgt_add_str(attrs, DM_USED_NAME, name, errp);
		}
		found = 1;
		break;
	    }
	    listp = listp->next;
	}
	(void) rw_unlock(&svm_lock);

	return (found);
}
Beispiel #19
0
GimpInitStatusFunc
gui_init (Gimp     *gimp,
          gboolean  no_splash)
{
  GimpInitStatusFunc  status_callback = NULL;
  gchar              *abort_message;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
  g_return_val_if_fail (the_gui_gimp == NULL, NULL);

  abort_message = gui_sanity_check ();
  if (abort_message)
    gui_abort (abort_message);

  the_gui_gimp = gimp;

  /* TRANSLATORS: there is no need to translate this in GIMP. This uses
   * "gtk20" domain as a special trick to determine language direction,
   * but xgettext extracts it anyway mistakenly into GIMP po files.
   * Leave an empty string as translation. It does not matter.
   */
  if (g_strcmp0 (dgettext ("gtk20", "default:LTR"), "default:RTL") == 0)
    /* Normally this should have been taken care of during command line
     * parsing as a post-parse hook of gtk_get_option_group(), using the
     * system locales.
     * But user config may have overriden the language, therefore we must
     * check the widget directions again.
     */
    gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
  else
    gtk_widget_set_default_direction (GTK_TEXT_DIR_LTR);

  gui_unique_init (gimp);
  gimp_language_store_parser_init ();

  gimp_widgets_init (gui_help_func,
                     gui_get_foreground_func,
                     gui_get_background_func,
                     NULL);

  g_type_class_ref (GIMP_TYPE_COLOR_SELECT);

  /*  disable automatic startup notification  */
  gtk_window_set_auto_startup_notification (FALSE);

  gimp_dnd_init (gimp);

  themes_init (gimp);

  initial_monitor = gimp_get_monitor_at_pointer (&initial_screen);
  gtk_widget_set_default_colormap (gdk_screen_get_rgb_colormap (initial_screen));

  if (! no_splash)
    {
      splash_create (gimp->be_verbose, initial_screen, initial_monitor);
      status_callback = splash_update;
    }

  g_signal_connect_after (gimp, "initialize",
                          G_CALLBACK (gui_initialize_after_callback),
                          NULL);

  g_signal_connect (gimp, "restore",
                    G_CALLBACK (gui_restore_callback),
                    NULL);
  g_signal_connect_after (gimp, "restore",
                          G_CALLBACK (gui_restore_after_callback),
                          NULL);

  g_signal_connect (gimp, "exit",
                    G_CALLBACK (gui_exit_callback),
                    NULL);
  g_signal_connect_after (gimp, "exit",
                          G_CALLBACK (gui_exit_after_callback),
                          NULL);

  return status_callback;
}
Beispiel #20
0
/*
 * mv_xattrs - Copies the content of the extended attribute files. Then
 * 	moves the extended system attributes from the input attribute files
 *      to the target attribute files. Moves the extended system attributes
 *	from source to the target file. This function returns 0 on success
 *	and nonzero on error.
 */
int
mv_xattrs(char *cmd, char *infile, char *outfile, int sattr, int silent)
{
	int srcfd = -1;
	int indfd = -1;
	int outdfd = -1;
	int tmpfd = -1;
	int sattrfd = -1;
	int tattrfd = -1;
	int asfd = -1;
	int atfd = -1;
	DIR *dirp = NULL;
	struct dirent *dp = NULL;
	char *etext = NULL;
	struct stat st1;
	struct stat st2;
	nvlist_t *response = NULL;
	nvlist_t *res = NULL;

	if ((srcfd = open(infile, O_RDONLY)) == -1) {
		etext = dgettext(TEXT_DOMAIN, "cannot open source");
		goto error;
	}
	if (sattr)
		response = sysattr_list(cmd, srcfd, infile);

	if ((indfd = openat(srcfd, ".", O_RDONLY|O_XATTR)) == -1) {
		etext = dgettext(TEXT_DOMAIN, "cannot openat source");
		goto error;
	}
	if ((outdfd = attropen(outfile, ".", O_RDONLY)) == -1) {
		etext = dgettext(TEXT_DOMAIN, "cannot attropen target");
		goto error;
	}
	if ((tmpfd = dup(indfd)) == -1) {
		etext = dgettext(TEXT_DOMAIN, "cannot dup descriptor");
		goto error;

	}
	if ((dirp = fdopendir(tmpfd)) == NULL) {
		etext = dgettext(TEXT_DOMAIN, "cannot access source");
		goto error;
	}
	while ((dp = readdir(dirp)) != NULL) {
		if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') ||
		    (dp->d_name[0] == '.' && dp->d_name[1] == '.' &&
		    dp->d_name[2] == '\0') ||
		    (sysattr_type(dp->d_name) == _RO_SATTR) ||
		    (sysattr_type(dp->d_name) == _RW_SATTR))
			continue;

		if ((sattrfd = openat(indfd, dp->d_name,
		    O_RDONLY)) == -1) {
			etext = dgettext(TEXT_DOMAIN,
			    "cannot open src attribute file");
			goto error;
		}
		if (fstat(sattrfd, &st1) < 0) {
			etext = dgettext(TEXT_DOMAIN,
			    "could not stat attribute file");
			goto error;
		}
		if ((tattrfd = openat(outdfd, dp->d_name,
		    O_RDWR|O_CREAT|O_TRUNC, st1.st_mode)) == -1) {
			etext = dgettext(TEXT_DOMAIN,
			    "cannot open target attribute file");
			goto error;
		}
		if (fstat(tattrfd, &st2) < 0) {
			etext = dgettext(TEXT_DOMAIN,
			    "could not stat attribute file");
			goto error;
		}
		if (writefile(sattrfd, tattrfd, infile, outfile, dp->d_name,
		    dp->d_name, &st1, &st2) != 0) {
			etext = dgettext(TEXT_DOMAIN,
			    "failed to copy extended attribute "
			    "from source to target");
			goto error;
		}

		errno = 0;
		if (sattr) {
			/*
			 * Gets non default extended system attributes from
			 * source to copy to target.
			 */
			if (dp->d_name != NULL)
				res = sysattr_list(cmd, sattrfd, dp->d_name);

			if (res != NULL &&
			    get_attrdirs(indfd, outdfd, dp->d_name, &asfd,
			    &atfd) != 0) {
				etext = dgettext(TEXT_DOMAIN,
				    "Failed to open attribute files");
				goto error;
			}
			/*
			 * Copy extended system attribute from source
			 * attribute file to target attribute file
			 */
			if (res != NULL &&
			    (renameat(asfd, VIEW_READWRITE, atfd,
			    VIEW_READWRITE) != 0)) {
				if (errno == EPERM)
					etext = dgettext(TEXT_DOMAIN,
					    "Permission denied -"
					    "failed to move system attribute");
				else
					etext = dgettext(TEXT_DOMAIN,
					    "failed to move extended "
					    "system attribute");
				goto error;
			}
		}
		if (sattrfd != -1)
			(void) close(sattrfd);
		if (tattrfd != -1)
			(void) close(tattrfd);
		if (asfd != -1)
			(void) close(asfd);
		if (atfd != -1)
			(void) close(atfd);
		if (res != NULL) {
			nvlist_free(res);
			res = NULL;
		}
	}
	errno = 0;
	/* Copy extended system attribute from source to target */

	if (response != NULL) {
		if (renameat(indfd, VIEW_READWRITE, outdfd,
		    VIEW_READWRITE) == 0)
			goto done;

		if (errno == EPERM)
			etext = dgettext(TEXT_DOMAIN, "Permission denied");
		else
			etext = dgettext(TEXT_DOMAIN,
			    "failed to move system attribute");
	}
error:
	nvlist_free(res);
	if (silent == 0 && etext != NULL) {
		if (!sattr)
			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
			    "%s: %s: cannot move extended attributes, "),
			    cmd, infile);
		else
			(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
			    "%s: %s: cannot move extended system "
			    "attributes, "), cmd, infile);
		perror(etext);
	}
done:
	if (dirp)
		(void) closedir(dirp);
	if (sattrfd != -1)
		(void) close(sattrfd);
	if (tattrfd != -1)
		(void) close(tattrfd);
	if (asfd != -1)
		(void) close(asfd);
	if (atfd != -1)
		(void) close(atfd);
	if (indfd != -1)
		(void) close(indfd);
	if (outdfd != -1)
		(void) close(outdfd);
	nvlist_free(response);
	if (etext != NULL)
		return (1);
	else
		return (0);
}
Beispiel #21
0
static PyObject *
PLy_output(volatile int level, PyObject *self, PyObject *args, PyObject *kw)
{
	int			sqlstate = 0;
	char	   *volatile sqlstatestr = NULL;
	char	   *volatile message = NULL;
	char	   *volatile detail = NULL;
	char	   *volatile hint = NULL;
	char	   *volatile column_name = NULL;
	char	   *volatile constraint_name = NULL;
	char	   *volatile datatype_name = NULL;
	char	   *volatile table_name = NULL;
	char	   *volatile schema_name = NULL;
	volatile MemoryContext oldcontext;
	PyObject   *key,
			   *value;
	PyObject   *volatile so;
	Py_ssize_t	pos = 0;

	if (PyTuple_Size(args) == 1)
	{
		/*
		 * Treat single argument specially to avoid undesirable ('tuple',)
		 * decoration.
		 */
		PyObject   *o;

		if (!PyArg_UnpackTuple(args, "plpy.elog", 1, 1, &o))
			PLy_elog(ERROR, "could not unpack arguments in plpy.elog");
		so = PyObject_Str(o);
	}
	else
		so = PyObject_Str(args);

	if (so == NULL || ((message = PyString_AsString(so)) == NULL))
	{
		level = ERROR;
		message = dgettext(TEXTDOMAIN, "could not parse error message in plpy.elog");
	}
	message = pstrdup(message);

	Py_XDECREF(so);

	if (kw != NULL)
	{
		while (PyDict_Next(kw, &pos, &key, &value))
		{
			char	   *keyword = PyString_AsString(key);

			if (strcmp(keyword, "message") == 0)
			{
				/* the message should not be overwriten */
				if (PyTuple_Size(args) != 0)
				{
					PLy_exception_set(PyExc_TypeError, "Argument 'message' given by name and position");
					return NULL;
				}

				if (message)
					pfree(message);
				message = object_to_string(value);
			}
			else if (strcmp(keyword, "detail") == 0)
				detail = object_to_string(value);
			else if (strcmp(keyword, "hint") == 0)
				hint = object_to_string(value);
			else if (strcmp(keyword, "sqlstate") == 0)
				sqlstatestr = object_to_string(value);
			else if (strcmp(keyword, "schema_name") == 0)
				schema_name = object_to_string(value);
			else if (strcmp(keyword, "table_name") == 0)
				table_name = object_to_string(value);
			else if (strcmp(keyword, "column_name") == 0)
				column_name = object_to_string(value);
			else if (strcmp(keyword, "datatype_name") == 0)
				datatype_name = object_to_string(value);
			else if (strcmp(keyword, "constraint_name") == 0)
				constraint_name = object_to_string(value);
			else
			{
				PLy_exception_set(PyExc_TypeError,
					 "'%s' is an invalid keyword argument for this function",
								  keyword);
				return NULL;
			}
		}
	}

	if (sqlstatestr != NULL)
	{
		if (strlen(sqlstatestr) != 5)
		{
			PLy_exception_set(PyExc_ValueError, "invalid SQLSTATE code");
			return NULL;
		}

		if (strspn(sqlstatestr, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") != 5)
		{
			PLy_exception_set(PyExc_ValueError, "invalid SQLSTATE code");
			return NULL;
		}

		sqlstate = MAKE_SQLSTATE(sqlstatestr[0],
								 sqlstatestr[1],
								 sqlstatestr[2],
								 sqlstatestr[3],
								 sqlstatestr[4]);
	}

	oldcontext = CurrentMemoryContext;
	PG_TRY();
	{
		if (message != NULL)
			pg_verifymbstr(message, strlen(message), false);
		if (detail != NULL)
			pg_verifymbstr(detail, strlen(detail), false);
		if (hint != NULL)
			pg_verifymbstr(hint, strlen(hint), false);
		if (schema_name != NULL)
			pg_verifymbstr(schema_name, strlen(schema_name), false);
		if (table_name != NULL)
			pg_verifymbstr(table_name, strlen(table_name), false);
		if (column_name != NULL)
			pg_verifymbstr(column_name, strlen(column_name), false);
		if (datatype_name != NULL)
			pg_verifymbstr(datatype_name, strlen(datatype_name), false);
		if (constraint_name != NULL)
			pg_verifymbstr(constraint_name, strlen(constraint_name), false);

		ereport(level,
				((sqlstate != 0) ? errcode(sqlstate) : 0,
				 (message != NULL) ? errmsg_internal("%s", message) : 0,
				 (detail != NULL) ? errdetail_internal("%s", detail) : 0,
				 (hint != NULL) ? errhint("%s", hint) : 0,
				 (column_name != NULL) ?
				 err_generic_string(PG_DIAG_COLUMN_NAME, column_name) : 0,
				 (constraint_name != NULL) ?
			err_generic_string(PG_DIAG_CONSTRAINT_NAME, constraint_name) : 0,
				 (datatype_name != NULL) ?
				 err_generic_string(PG_DIAG_DATATYPE_NAME, datatype_name) : 0,
				 (table_name != NULL) ?
				 err_generic_string(PG_DIAG_TABLE_NAME, table_name) : 0,
				 (schema_name != NULL) ?
				 err_generic_string(PG_DIAG_SCHEMA_NAME, schema_name) : 0));
	}
	PG_CATCH();
	{
		ErrorData  *edata;

		MemoryContextSwitchTo(oldcontext);
		edata = CopyErrorData();
		FlushErrorState();

		PLy_exception_set_with_details(PLy_exc_error, edata);
		FreeErrorData(edata);

		return NULL;
	}
	PG_END_TRY();

	/*
	 * return a legal object so the interpreter will continue on its merry way
	 */
	Py_INCREF(Py_None);
	return Py_None;
}
Beispiel #22
0
/*
 * Mount the given filesystem.
 */
int
zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
{
	struct stat buf;
	char mountpoint[ZFS_MAXPROPLEN];
	char mntopts[MNT_LINE_MAX];
	char overlay[ZFS_MAXPROPLEN];
	libzfs_handle_t *hdl = zhp->zfs_hdl;
	int remount = 0, rc;

	if (options == NULL) {
		(void) strlcpy(mntopts, MNTOPT_DEFAULTS, sizeof (mntopts));
	} else {
		(void) strlcpy(mntopts, options, sizeof (mntopts));
	}

	if (strstr(mntopts, MNTOPT_REMOUNT) != NULL)
		remount = 1;

	/*
	 * If the pool is imported read-only then all mounts must be read-only
	 */
	if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
		(void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts));

	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
		return (0);

	/*
	 * Append default mount options which apply to the mount point.
	 * This is done because under Linux (unlike Solaris) multiple mount
	 * points may reference a single super block.  This means that just
	 * given a super block there is no back reference to update the per
	 * mount point options.
	 */
	rc = zfs_add_options(zhp, mntopts, sizeof (mntopts));
	if (rc) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "default options unavailable"));
		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
		    mountpoint));
	}

	/*
	 * Append zfsutil option so the mount helper allow the mount
	 */
	strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts));

	/* Create the directory if it doesn't already exist */
	if (lstat(mountpoint, &buf) != 0) {
		if (mkdirp(mountpoint, 0755) != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "failed to create mountpoint"));
			return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
			    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
			    mountpoint));
		}
	}

	/*
	 * Overlay mounts are disabled by default but may be enabled
	 * via the 'overlay' property or the 'zfs mount -O' option.
	 */
	if (!(flags & MS_OVERLAY)) {
		if (zfs_prop_get(zhp, ZFS_PROP_OVERLAY, overlay,
			    sizeof (overlay), NULL, NULL, 0, B_FALSE) == 0) {
			if (strcmp(overlay, "on") == 0) {
				flags |= MS_OVERLAY;
			}
		}
	}

	/*
	 * Determine if the mountpoint is empty.  If so, refuse to perform the
	 * mount.  We don't perform this check if 'remount' is
	 * specified or if overlay option(-O) is given
	 */
	if ((flags & MS_OVERLAY) == 0 && !remount &&
	    !dir_is_empty(mountpoint)) {
		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
		    "directory is not empty"));
		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint));
	}

	/* perform the mount */
	rc = do_mount(zfs_get_name(zhp), mountpoint, mntopts);
	if (rc) {
		/*
		 * Generic errors are nasty, but there are just way too many
		 * from mount(), and they're well-understood.  We pick a few
		 * common ones to improve upon.
		 */
		if (rc == EBUSY) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "mountpoint or dataset is busy"));
		} else if (rc == EPERM) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Insufficient privileges"));
		} else if (rc == ENOTSUP) {
			char buf[256];
			int spa_version;

			VERIFY(zfs_spa_version(zhp, &spa_version) == 0);
			(void) snprintf(buf, sizeof (buf),
			    dgettext(TEXT_DOMAIN, "Can't mount a version %lld "
			    "file system on a version %d pool. Pool must be"
			    " upgraded to mount this file system."),
			    (u_longlong_t)zfs_prop_get_int(zhp,
			    ZFS_PROP_VERSION), spa_version);
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf));
		} else {
			zfs_error_aux(hdl, strerror(rc));
		}
		return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
		    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
		    zhp->zfs_name));
	}

	/* remove the mounted entry before re-adding on remount */
	if (remount)
		libzfs_mnttab_remove(hdl, zhp->zfs_name);

	/* add the mounted entry into our cache */
	libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts);
	return (0);
}
Beispiel #23
0
int
zfs_crypto_load_key(zfs_handle_t *zhp, boolean_t noop, char *alt_keylocation)
{
	int ret, attempts = 0;
	char errbuf[1024];
	uint64_t keystatus, iters = 0, salt = 0;
	uint64_t keyformat = ZFS_KEYFORMAT_NONE;
	char prop_keylocation[MAXNAMELEN];
	char prop_encroot[MAXNAMELEN];
	char *keylocation = NULL;
	uint8_t *key_material = NULL, *key_data = NULL;
	size_t key_material_len;
	boolean_t is_encroot, can_retry = B_FALSE, correctible = B_FALSE;

	(void) snprintf(errbuf, sizeof (errbuf),
	    dgettext(TEXT_DOMAIN, "Key load error"));

	/* check that encryption is enabled for the pool */
	if (!encryption_feature_is_enabled(zhp->zpool_hdl)) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Encryption feature not enabled."));
		ret = EINVAL;
		goto error;
	}

	/* Fetch the keyformat. Check that the dataset is encrypted. */
	keyformat = zfs_prop_get_int(zhp, ZFS_PROP_KEYFORMAT);
	if (keyformat == ZFS_KEYFORMAT_NONE) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "'%s' is not encrypted."), zfs_get_name(zhp));
		ret = EINVAL;
		goto error;
	}

	/*
	 * Fetch the key location. Check that we are working with an
	 * encryption root.
	 */
	ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, prop_encroot);
	if (ret != 0) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Failed to get encryption root for '%s'."),
		    zfs_get_name(zhp));
		goto error;
	} else if (!is_encroot) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Keys must be loaded for encryption root of '%s' (%s)."),
		    zfs_get_name(zhp), prop_encroot);
		ret = EINVAL;
		goto error;
	}

	/*
	 * if the caller has elected to override the keylocation property
	 * use that instead
	 */
	if (alt_keylocation != NULL) {
		keylocation = alt_keylocation;
	} else {
		ret = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION, prop_keylocation,
		    sizeof (prop_keylocation), NULL, NULL, 0, B_TRUE);
		if (ret != 0) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Failed to get keylocation for '%s'."),
			    zfs_get_name(zhp));
			goto error;
		}

		keylocation = prop_keylocation;
	}

	/* check that the key is unloaded unless this is a noop */
	if (!noop) {
		keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
		if (keystatus == ZFS_KEYSTATUS_AVAILABLE) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Key already loaded for '%s'."), zfs_get_name(zhp));
			ret = EEXIST;
			goto error;
		}
	}

	/* passphrase formats require a salt and pbkdf2_iters property */
	if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) {
		salt = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_SALT);
		iters = zfs_prop_get_int(zhp, ZFS_PROP_PBKDF2_ITERS);
	}

try_again:
	/* fetching and deriving the key are correctible errors. set the flag */
	correctible = B_TRUE;

	/* get key material from key format and location */
	ret = get_key_material(zhp->zfs_hdl, B_FALSE, B_FALSE, keyformat,
	    keylocation, zfs_get_name(zhp), &key_material, &key_material_len,
	    &can_retry);
	if (ret != 0)
		goto error;

	/* derive a key from the key material */
	ret = derive_key(zhp->zfs_hdl, keyformat, iters, key_material,
	    key_material_len, salt, &key_data);
	if (ret != 0)
		goto error;

	correctible = B_FALSE;

	/* pass the wrapping key and noop flag to the ioctl */
	ret = lzc_load_key(zhp->zfs_name, noop, key_data, WRAPPING_KEY_LEN);
	if (ret != 0) {
		switch (ret) {
		case EPERM:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Permission denied."));
			break;
		case EINVAL:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Invalid parameters provided for dataset %s."),
			    zfs_get_name(zhp));
			break;
		case EEXIST:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Key already loaded for '%s'."), zfs_get_name(zhp));
			break;
		case EBUSY:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "'%s' is busy."), zfs_get_name(zhp));
			break;
		case EACCES:
			correctible = B_TRUE;
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Incorrect key provided for '%s'."),
			    zfs_get_name(zhp));
			break;
		}
		goto error;
	}

	free(key_material);
	free(key_data);

	return (0);

error:
	zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
	if (key_material != NULL)
		free(key_material);
	if (key_data != NULL)
		free(key_data);

	/*
	 * Here we decide if it is ok to allow the user to retry entering their
	 * key. The can_retry flag will be set if the user is entering their
	 * key from an interactive prompt. The correctible flag will only be
	 * set if an error that occured could be corrected by retrying. Both
	 * flags are needed to allow the user to attempt key entry again
	 */
	if (can_retry && correctible && attempts <= MAX_KEY_PROMPT_ATTEMPTS) {
		attempts++;
		goto try_again;
	}

	return (ret);
}
Beispiel #24
0
/*
 * Share the given filesystem according to the options in the specified
 * protocol specific properties (sharenfs, sharesmb).  We rely
 * on "libshare" to do the dirty work for us.
 */
static int
zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
{
	char mountpoint[ZFS_MAXPROPLEN];
	char shareopts[ZFS_MAXPROPLEN];
	char sourcestr[ZFS_MAXPROPLEN];
	libzfs_handle_t *hdl = zhp->zfs_hdl;
	sa_share_t share;
	zfs_share_proto_t *curr_proto;
	zprop_source_t sourcetype;
	int ret;

	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
		return (0);

	for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
		/*
		 * Return success if there are no share options.
		 */
		if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
		    shareopts, sizeof (shareopts), &sourcetype, sourcestr,
		    ZFS_MAXPROPLEN, B_FALSE) != 0 ||
		    strcmp(shareopts, "off") == 0)
			continue;

		ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API);
		if (ret != SA_OK) {
			(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
			    dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
			    zfs_get_name(zhp), sa_errorstr(ret));
			return (-1);
		}

		/*
		 * If the 'zoned' property is set, then zfs_is_mountable()
		 * will have already bailed out if we are in the global zone.
		 * But local zones cannot be NFS servers, so we ignore it for
		 * local zones as well.
		 */
		if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
			continue;

		share = sa_find_share(hdl->libzfs_sharehdl, mountpoint);
		if (share == NULL) {
			/*
			 * This may be a new file system that was just
			 * created so isn't in the internal cache
			 * (second time through). Rather than
			 * reloading the entire configuration, we can
			 * assume ZFS has done the checking and it is
			 * safe to add this to the internal
			 * configuration.
			 */
			if (sa_zfs_process_share(hdl->libzfs_sharehdl,
			    NULL, NULL, mountpoint,
			    proto_table[*curr_proto].p_name, sourcetype,
			    shareopts, sourcestr, zhp->zfs_name) != SA_OK) {
				(void) zfs_error_fmt(hdl,
				    proto_table[*curr_proto].p_share_err,
				    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
				    zfs_get_name(zhp));
				return (-1);
			}
			hdl->libzfs_shareflags |= ZFSSHARE_MISS;
			share = sa_find_share(hdl->libzfs_sharehdl,
			    mountpoint);
		}
		if (share != NULL) {
			int err;
			err = sa_enable_share(share,
			    proto_table[*curr_proto].p_name);
			if (err != SA_OK) {
				(void) zfs_error_fmt(hdl,
				    proto_table[*curr_proto].p_share_err,
				    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
				    zfs_get_name(zhp));
				return (-1);
			}
		} else {
			(void) zfs_error_fmt(hdl,
			    proto_table[*curr_proto].p_share_err,
			    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
			    zfs_get_name(zhp));
			return (-1);
		}

	}
	return (0);
}
Beispiel #25
0
int
zfs_crypto_rewrap(zfs_handle_t *zhp, nvlist_t *raw_props, boolean_t inheritkey)
{
	int ret;
	char errbuf[1024];
	boolean_t is_encroot;
	nvlist_t *props = NULL;
	uint8_t *wkeydata = NULL;
	uint_t wkeylen = 0;
	dcp_cmd_t cmd = (inheritkey) ? DCP_CMD_INHERIT : DCP_CMD_NEW_KEY;
	uint64_t crypt, pcrypt, keystatus, pkeystatus;
	uint64_t keyformat = ZFS_KEYFORMAT_NONE;
	zfs_handle_t *pzhp = NULL;
	char *keylocation = NULL;
	char origin_name[MAXNAMELEN];
	char prop_keylocation[MAXNAMELEN];
	char parent_name[ZFS_MAX_DATASET_NAME_LEN];

	(void) snprintf(errbuf, sizeof (errbuf),
	    dgettext(TEXT_DOMAIN, "Key change error"));

	/* check that encryption is enabled for the pool */
	if (!encryption_feature_is_enabled(zhp->zpool_hdl)) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Encryption feature not enabled."));
		ret = EINVAL;
		goto error;
	}

	/* get crypt from dataset */
	crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
	if (crypt == ZIO_CRYPT_OFF) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Dataset not encrypted."));
		ret = EINVAL;
		goto error;
	}

	/* get the encryption root of the dataset */
	ret = zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
	if (ret != 0) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Failed to get encryption root for '%s'."),
		    zfs_get_name(zhp));
		goto error;
	}

	/* Clones use their origin's key and cannot rewrap it */
	ret = zfs_prop_get(zhp, ZFS_PROP_ORIGIN, origin_name,
	    sizeof (origin_name), NULL, NULL, 0, B_TRUE);
	if (ret == 0 && strcmp(origin_name, "") != 0) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Keys cannot be changed on clones."));
		ret = EINVAL;
		goto error;
	}

	/*
	 * If the user wants to use the inheritkey variant of this function
	 * we don't need to collect any crypto arguments.
	 */
	if (!inheritkey) {
		/* validate the provided properties */
		ret = zfs_crypto_verify_rewrap_nvlist(zhp, raw_props, &props,
		    errbuf);
		if (ret != 0)
			goto error;

		/*
		 * Load keyformat and keylocation from the nvlist. Fetch from
		 * the dataset properties if not specified.
		 */
		(void) nvlist_lookup_uint64(props,
		    zfs_prop_to_name(ZFS_PROP_KEYFORMAT), &keyformat);
		(void) nvlist_lookup_string(props,
		    zfs_prop_to_name(ZFS_PROP_KEYLOCATION), &keylocation);

		if (is_encroot) {
			/*
			 * If this is already an ecryption root, just keep
			 * any properties not set by the user.
			 */
			if (keyformat == ZFS_KEYFORMAT_NONE) {
				keyformat = zfs_prop_get_int(zhp,
				    ZFS_PROP_KEYFORMAT);
				ret = nvlist_add_uint64(props,
				    zfs_prop_to_name(ZFS_PROP_KEYFORMAT),
				    keyformat);
				if (ret != 0) {
					zfs_error_aux(zhp->zfs_hdl,
					    dgettext(TEXT_DOMAIN, "Failed to "
					    "get existing keyformat "
					    "property."));
					goto error;
				}
			}

			if (keylocation == NULL) {
				ret = zfs_prop_get(zhp, ZFS_PROP_KEYLOCATION,
				    prop_keylocation, sizeof (prop_keylocation),
				    NULL, NULL, 0, B_TRUE);
				if (ret != 0) {
					zfs_error_aux(zhp->zfs_hdl,
					    dgettext(TEXT_DOMAIN, "Failed to "
					    "get existing keylocation "
					    "property."));
					goto error;
				}

				keylocation = prop_keylocation;
			}
		} else {
			/* need a new key for non-encryption roots */
			if (keyformat == ZFS_KEYFORMAT_NONE) {
				ret = EINVAL;
				zfs_error_aux(zhp->zfs_hdl,
				    dgettext(TEXT_DOMAIN, "Keyformat required "
				    "for new encryption root."));
				goto error;
			}

			/* default to prompt if no keylocation is specified */
			if (keylocation == NULL) {
				keylocation = "prompt";
				ret = nvlist_add_string(props,
				    zfs_prop_to_name(ZFS_PROP_KEYLOCATION),
				    keylocation);
				if (ret != 0)
					goto error;
			}
		}

		/* fetch the new wrapping key and associated properties */
		ret = populate_create_encryption_params_nvlists(zhp->zfs_hdl,
		    zhp, B_TRUE, keyformat, keylocation, props, &wkeydata,
		    &wkeylen);
		if (ret != 0)
			goto error;
	} else {
		/* check that zhp is an encryption root */
		if (!is_encroot) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Key inheritting can only be performed on "
			    "encryption roots."));
			ret = EINVAL;
			goto error;
		}

		/* get the parent's name */
		ret = zfs_parent_name(zhp, parent_name, sizeof (parent_name));
		if (ret != 0) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Root dataset cannot inherit key."));
			ret = EINVAL;
			goto error;
		}

		/* get a handle to the parent */
		pzhp = make_dataset_handle(zhp->zfs_hdl, parent_name);
		if (pzhp == NULL) {
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Failed to lookup parent."));
			ret = ENOENT;
			goto error;
		}

		/* parent must be encrypted */
		pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION);
		if (pcrypt == ZIO_CRYPT_OFF) {
			zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Parent must be encrypted."));
			ret = EINVAL;
			goto error;
		}

		/* check that the parent's key is loaded */
		pkeystatus = zfs_prop_get_int(pzhp, ZFS_PROP_KEYSTATUS);
		if (pkeystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
			zfs_error_aux(pzhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Parent key must be loaded."));
			ret = EACCES;
			goto error;
		}
	}

	/* check that the key is loaded */
	keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
	if (keystatus == ZFS_KEYSTATUS_UNAVAILABLE) {
		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
		    "Key must be loaded."));
		ret = EACCES;
		goto error;
	}

	/* call the ioctl */
	ret = lzc_change_key(zhp->zfs_name, cmd, props, wkeydata, wkeylen);
	if (ret != 0) {
		switch (ret) {
		case EPERM:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Permission denied."));
			break;
		case EINVAL:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Invalid properties for key change."));
			break;
		case EACCES:
			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
			    "Key is not currently loaded."));
			break;
		}
		zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
	}

	if (pzhp != NULL)
		zfs_close(pzhp);
	if (props != NULL)
		nvlist_free(props);
	if (wkeydata != NULL)
		free(wkeydata);

	return (ret);

error:
	if (pzhp != NULL)
		zfs_close(pzhp);
	if (props != NULL)
		nvlist_free(props);
	if (wkeydata != NULL)
		free(wkeydata);

	zfs_error(zhp->zfs_hdl, EZFS_CRYPTOFAILED, errbuf);
	return (ret);
}
Beispiel #26
0
QString u2dTr(const char* text, const char* domain)
{
    return QString::fromUtf8(dgettext(domain, text));
}
Beispiel #27
0
static int
populate_create_encryption_params_nvlists(libzfs_handle_t *hdl,
    zfs_handle_t *zhp, boolean_t newkey, zfs_keyformat_t keyformat,
    char *keylocation, nvlist_t *props, uint8_t **wkeydata, uint_t *wkeylen)
{
	int ret;
	uint64_t iters = 0, salt = 0;
	uint8_t *key_material = NULL;
	size_t key_material_len = 0;
	uint8_t *key_data = NULL;
	const char *fsname = (zhp) ? zfs_get_name(zhp) : NULL;

	/* get key material from keyformat and keylocation */
	ret = get_key_material(hdl, B_TRUE, newkey, keyformat, keylocation,
	    fsname, &key_material, &key_material_len, NULL);
	if (ret != 0)
		goto error;

	/* passphrase formats require a salt and pbkdf2 iters property */
	if (keyformat == ZFS_KEYFORMAT_PASSPHRASE) {
		/* always generate a new salt */
		random_init();
		ret = random_get_bytes((uint8_t *)&salt, sizeof (uint64_t));
		if (ret != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Failed to generate salt."));
			goto error;
		}
		random_fini();

		ret = nvlist_add_uint64(props,
		    zfs_prop_to_name(ZFS_PROP_PBKDF2_SALT), salt);
		if (ret != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
				"Failed to add salt to properties."));
			goto error;
		}

		/*
		 * If not otherwise specified, use the default number of
		 * pbkdf2 iterations. If specified, we have already checked
		 * that the given value is greater than MIN_PBKDF2_ITERATIONS
		 * during zfs_valid_proplist().
		 */
		ret = nvlist_lookup_uint64(props,
		    zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters);
		if (ret == ENOENT) {
			iters = DEFAULT_PBKDF2_ITERATIONS;
			ret = nvlist_add_uint64(props,
			    zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), iters);
			if (ret != 0)
				goto error;
		} else if (ret != 0) {
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Failed to get pbkdf2 iterations."));
			goto error;
		}
	} else {
		/* check that pbkdf2iters was not specified by the user */
		ret = nvlist_lookup_uint64(props,
		    zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), &iters);
		if (ret == 0) {
			ret = EINVAL;
			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
			    "Cannot specify pbkdf2iters with a non-passphrase "
			    "keyformat."));
			goto error;
		}
	}

	/* derive a key from the key material */
	ret = derive_key(hdl, keyformat, iters, key_material, key_material_len,
	    salt, &key_data);
	if (ret != 0)
		goto error;

	free(key_material);

	*wkeydata = key_data;
	*wkeylen = WRAPPING_KEY_LEN;
	return (0);

error:
	if (key_material != NULL)
		free(key_material);
	if (key_data != NULL)
		free(key_data);

	*wkeydata = NULL;
	*wkeylen = 0;
	return (ret);
}
Beispiel #28
0
/*
 * Given a list of directories to search, find all pools stored on disk.  This
 * includes partial pools which are not available to import.  If no args are
 * given (argc is 0), then the default directory (/dev/dsk) is searched.
 * poolname or guid (but not both) are provided by the caller when trying
 * to import a specific pool.
 */
static nvlist_t *
zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
{
	int i, dirs = iarg->paths;
	struct dirent64 *dp;
	char path[MAXPATHLEN];
	char *end, **dir = iarg->path;
	size_t pathleft;
	nvlist_t *ret = NULL;
	static char *default_dir = "/dev/dsk";
	pool_list_t pools = { 0 };
	pool_entry_t *pe, *penext;
	vdev_entry_t *ve, *venext;
	config_entry_t *ce, *cenext;
	name_entry_t *ne, *nenext;
	avl_tree_t slice_cache;
	rdsk_node_t *slice;
	void *cookie;

	if (dirs == 0) {
		dirs = 1;
		dir = &default_dir;
	}

	/*
	 * Go through and read the label configuration information from every
	 * possible device, organizing the information according to pool GUID
	 * and toplevel GUID.
	 */
	for (i = 0; i < dirs; i++) {
		tpool_t *t;
		char *rdsk;
		int dfd;
		boolean_t config_failed = B_FALSE;
		DIR *dirp;

		/* use realpath to normalize the path */
		if (realpath(dir[i], path) == 0) {
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]);
			goto error;
		}
		end = &path[strlen(path)];
		*end++ = '/';
		*end = 0;
		pathleft = &path[sizeof (path)] - end;

		/*
		 * Using raw devices instead of block devices when we're
		 * reading the labels skips a bunch of slow operations during
		 * close(2) processing, so we replace /dev/dsk with /dev/rdsk.
		 */
		if (strcmp(path, "/dev/dsk/") == 0)
			rdsk = "/dev/rdsk/";
		else
			rdsk = path;

		if ((dfd = open64(rdsk, O_RDONLY)) < 0 ||
		    (dirp = fdopendir(dfd)) == NULL) {
			if (dfd >= 0)
				(void) close(dfd);
			zfs_error_aux(hdl, strerror(errno));
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
			    rdsk);
			goto error;
		}

		avl_create(&slice_cache, slice_cache_compare,
		    sizeof (rdsk_node_t), offsetof(rdsk_node_t, rn_node));
		/*
		 * This is not MT-safe, but we have no MT consumers of libzfs
		 */
		while ((dp = readdir64(dirp)) != NULL) {
			const char *name = dp->d_name;
			if (name[0] == '.' &&
			    (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
				continue;

			slice = zfs_alloc(hdl, sizeof (rdsk_node_t));
			slice->rn_name = zfs_strdup(hdl, name);
			slice->rn_avl = &slice_cache;
			slice->rn_dfd = dfd;
			slice->rn_hdl = hdl;
			slice->rn_nozpool = B_FALSE;
			avl_add(&slice_cache, slice);
		}
		/*
		 * create a thread pool to do all of this in parallel;
		 * rn_nozpool is not protected, so this is racy in that
		 * multiple tasks could decide that the same slice can
		 * not hold a zpool, which is benign.  Also choose
		 * double the number of processors; we hold a lot of
		 * locks in the kernel, so going beyond this doesn't
		 * buy us much.
		 */
		t = tpool_create(1, 2 * sysconf(_SC_NPROCESSORS_ONLN),
		    0, NULL);
		for (slice = avl_first(&slice_cache); slice;
		    (slice = avl_walk(&slice_cache, slice,
		    AVL_AFTER)))
			(void) tpool_dispatch(t, zpool_open_func, slice);
		tpool_wait(t);
		tpool_destroy(t);

		cookie = NULL;
		while ((slice = avl_destroy_nodes(&slice_cache,
		    &cookie)) != NULL) {
			if (slice->rn_config != NULL && !config_failed) {
				nvlist_t *config = slice->rn_config;
				boolean_t matched = B_TRUE;

				if (iarg->poolname != NULL) {
					char *pname;

					matched = nvlist_lookup_string(config,
					    ZPOOL_CONFIG_POOL_NAME,
					    &pname) == 0 &&
					    strcmp(iarg->poolname, pname) == 0;
				} else if (iarg->guid != 0) {
					uint64_t this_guid;

					matched = nvlist_lookup_uint64(config,
					    ZPOOL_CONFIG_POOL_GUID,
					    &this_guid) == 0 &&
					    iarg->guid == this_guid;
				}
				if (!matched) {
					nvlist_free(config);
				} else {
					/*
					 * use the non-raw path for the config
					 */
					(void) strlcpy(end, slice->rn_name,
					    pathleft);
					if (add_config(hdl, &pools, path,
					    config) != 0)
						config_failed = B_TRUE;
				}
			}
			free(slice->rn_name);
			free(slice);
		}
		avl_destroy(&slice_cache);

		(void) closedir(dirp);

		if (config_failed)
			goto error;
	}

	ret = get_configs(hdl, &pools, iarg->can_be_active);

error:
	for (pe = pools.pools; pe != NULL; pe = penext) {
		penext = pe->pe_next;
		for (ve = pe->pe_vdevs; ve != NULL; ve = venext) {
			venext = ve->ve_next;
			for (ce = ve->ve_configs; ce != NULL; ce = cenext) {
				cenext = ce->ce_next;
				if (ce->ce_config)
					nvlist_free(ce->ce_config);
				free(ce);
			}
			free(ve);
		}
		free(pe);
	}

	for (ne = pools.names; ne != NULL; ne = nenext) {
		nenext = ne->ne_next;
		free(ne->ne_name);
		free(ne);
	}

	return (ret);
}
Beispiel #29
0
/*
 * Given a cache file, return the contents as a list of importable pools.
 * poolname or guid (but not both) are provided by the caller when trying
 * to import a specific pool.
 */
nvlist_t *
zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile,
    char *poolname, uint64_t guid)
{
	char *buf;
	int fd;
	struct stat64 statbuf;
	nvlist_t *raw, *src, *dst;
	nvlist_t *pools;
	nvpair_t *elem;
	char *name;
	uint64_t this_guid;
	boolean_t active;

	verify(poolname == NULL || guid == 0);

	if ((fd = open(cachefile, O_RDONLY)) < 0) {
		zfs_error_aux(hdl, "%s", strerror(errno));
		(void) zfs_error(hdl, EZFS_BADCACHE,
		    dgettext(TEXT_DOMAIN, "failed to open cache file"));
		return (NULL);
	}

	if (fstat64(fd, &statbuf) != 0) {
		zfs_error_aux(hdl, "%s", strerror(errno));
		(void) close(fd);
		(void) zfs_error(hdl, EZFS_BADCACHE,
		    dgettext(TEXT_DOMAIN, "failed to get size of cache file"));
		return (NULL);
	}

	if ((buf = zfs_alloc(hdl, statbuf.st_size)) == NULL) {
		(void) close(fd);
		return (NULL);
	}

	if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
		(void) close(fd);
		free(buf);
		(void) zfs_error(hdl, EZFS_BADCACHE,
		    dgettext(TEXT_DOMAIN,
		    "failed to read cache file contents"));
		return (NULL);
	}

	(void) close(fd);

	if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) {
		free(buf);
		(void) zfs_error(hdl, EZFS_BADCACHE,
		    dgettext(TEXT_DOMAIN,
		    "invalid or corrupt cache file contents"));
		return (NULL);
	}

	free(buf);

	/*
	 * Go through and get the current state of the pools and refresh their
	 * state.
	 */
	if (nvlist_alloc(&pools, 0, 0) != 0) {
		(void) no_memory(hdl);
		nvlist_free(raw);
		return (NULL);
	}

	elem = NULL;
	while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
		verify(nvpair_value_nvlist(elem, &src) == 0);

		verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME,
		    &name) == 0);
		if (poolname != NULL && strcmp(poolname, name) != 0)
			continue;

		verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
		    &this_guid) == 0);
		if (guid != 0) {
			verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
			    &this_guid) == 0);
			if (guid != this_guid)
				continue;
		}

		if (pool_active(hdl, name, this_guid, &active) != 0) {
			nvlist_free(raw);
			nvlist_free(pools);
			return (NULL);
		}

		if (active)
			continue;

		if ((dst = refresh_config(hdl, src)) == NULL) {
			nvlist_free(raw);
			nvlist_free(pools);
			return (NULL);
		}

		if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
			(void) no_memory(hdl);
			nvlist_free(dst);
			nvlist_free(raw);
			nvlist_free(pools);
			return (NULL);
		}
		nvlist_free(dst);
	}

	nvlist_free(raw);
	return (pools);
}
Beispiel #30
0
static int
prompt_pkcs11_pin(libzfs_handle_t *hdl, zfs_cmd_t *zc, zfs_crypto_zckey_t cmd,
    pkcs11_uri_t *p11uri, char **pin, uint32_t *pinlen)
{
	char prompt[MAXPROMPTLEN];
	char *input;
	char dsname[MAXNAMELEN];

	/*
	 * If the PKCS#11 uri has a pinfile argument read the pin from
	 * there.
	 *
	 * Otherwise if the libzfs_handle_t has crypto data we assume this is
	 * the PIN given we can only be in here with a PKCS#11 uri.
	 *
	 * Finally if that is empty then if we can prompt then do so using
	 * getpassphrase().
	 *
	 * Abuse zfs_can_prompt_if_needed() by pretending we are
	 * "passphrase,prompt".
	 */
	if (p11uri->pinfile) {
		struct stat sbuf;
		int pinfd = open(p11uri->pinfile, O_RDONLY);
		char *pbuf;

		if (pinfd == -1)
			return (-1);
		if (fstat(pinfd, &sbuf) != 0)
			return (-1);
		pbuf = zfs_alloc(hdl, sbuf.st_size);
		if (read(pinfd, pbuf, sbuf.st_size) != sbuf.st_size) {
			free(pbuf);
			return (-1);
		}
		(void) close(pinfd);
		pbuf[sbuf.st_size] = '\0';
		*pinlen = sbuf.st_size;
		if (pbuf[sbuf.st_size - 1] == '\n' ||
		    pbuf[sbuf.st_size - 1] == '\r') {
			*pinlen = *pinlen - 1;
		}
		*pin = pbuf;
		return (0);
	}

	if (hdl->libzfs_crypt.zc_key_data != NULL &&
	    hdl->libzfs_crypt.zc_key_data_len != 0) {
		*pinlen = hdl->libzfs_crypt.zc_key_data_len;
		*pin = zfs_alloc(hdl, *pinlen);
		bcopy(hdl->libzfs_crypt.zc_key_data, *pin, *pinlen);
		return (0);
	}
	if (!zfs_can_prompt_if_needed("passphrase,prompt")) {
		errno = ENOTTY;
		return (-1);
	}

	zfs_cmd_target_dsname(zc, cmd, dsname, sizeof (dsname));
	if (p11uri->token)  {
		(void) snprintf(prompt, MAXPROMPTLEN,
		    dgettext(TEXT_DOMAIN,
		    "Enter '%s' PKCS#11 token PIN for '%s': "),
		    p11uri->token, dsname);
	} else {
		(void) snprintf(prompt, MAXPROMPTLEN,
		    dgettext(TEXT_DOMAIN,
		    "Enter PKCS#11 token PIN for '%s': "), dsname);
	}
	input = getpassphrase(prompt);

	if (input != NULL) {
		*pin = strdup(input);
		*pinlen = strlen(*pin);
	} else {
		return (-1);
	}
	return (0);
}