Example #1
0
/**
 * @brief encrypt or sign the file specified at parentKey
 * @param pluginConfig holds the plugin configuration
 * @param parentKey holds the path to the file to be encrypted. Will hold an error description in case of failure.
 * @retval 1 on success
 * @retval -1 on error, errorKey holds an error description
 */
static int fcryptEncrypt (KeySet * pluginConfig, Key * parentKey)
{
	Key * k;
	const size_t recipientCount = getRecipientCount (pluginConfig, ELEKTRA_RECIPIENT_KEY);
	const size_t signatureCount = getRecipientCount (pluginConfig, ELEKTRA_SIGNATURE_KEY);

	if (recipientCount == 0 && signatureCount == 0)
	{
		ELEKTRA_SET_ERRORF (
			ELEKTRA_ERROR_NO_GPG_RECIPIENTS, parentKey,
			"Missing GPG recipient key (specified as %s) or GPG signature key (specified as %s) in plugin configuration.",
			ELEKTRA_RECIPIENT_KEY, ELEKTRA_SIGNATURE_KEY);
		return -1;
	}

	int tmpFileFd = -1;
	char * tmpFile = getTemporaryFileName (pluginConfig, keyString (parentKey), &tmpFileFd);
	if (!tmpFile)
	{
		ELEKTRA_SET_ERROR (87, parentKey, "Memory allocation failed");
		return -1;
	}

	const size_t testMode = inTestMode (pluginConfig);
	const size_t textMode = inTextMode (pluginConfig);

	// prepare argument vector for gpg call
	// 7 static arguments (magic number below) are:
	//   1. path to the binary
	//   2. --batch
	//   3. -o
	//   4. path to tmp file
	//   5. yes
	//   6. file to be encrypted
	//   7. NULL terminator
	int argc = 7 + (2 * recipientCount) + (2 * signatureCount) + (2 * testMode) + textMode + (recipientCount > 0 ? 1 : 0) +
		   (signatureCount > 0 ? 1 : 0);
	kdb_unsigned_short_t i = 0;
	char * argv[argc];
	argv[i++] = NULL;
	argv[i++] = "--batch";
	argv[i++] = "-o";
	argv[i++] = tmpFile;
	argv[i++] = "--yes"; // overwrite files if they exist

	// add recipients
	Key * gpgRecipientRoot = ksLookupByName (pluginConfig, ELEKTRA_RECIPIENT_KEY, 0);

	// append root (gpg/key) as gpg recipient
	if (gpgRecipientRoot && strlen (keyString (gpgRecipientRoot)) > 0)
	{
		argv[i++] = "-r";
		// NOTE argv[] values will not be modified, so const can be discarded safely
		argv[i++] = (char *) keyString (gpgRecipientRoot);
	}

	// append keys beneath root (crypto/key/#_) as gpg recipients
	if (gpgRecipientRoot)
	{
		ksRewind (pluginConfig);
		while ((k = ksNext (pluginConfig)) != 0)
		{
			const char * kStringVal = keyString (k);
			if (keyIsBelow (k, gpgRecipientRoot) && strlen (kStringVal) > 0)
			{
				argv[i++] = "-r";
				// NOTE argv[] values will not be modified, so const can be discarded safely
				argv[i++] = (char *) kStringVal;
			}
		}
	}


	// add signature keys
	Key * gpgSignatureRoot = ksLookupByName (pluginConfig, ELEKTRA_SIGNATURE_KEY, 0);

	// append root signature key
	if (gpgSignatureRoot && strlen (keyString (gpgSignatureRoot)) > 0)
	{
		argv[i++] = "-u";
		// NOTE argv[] values will not be modified, so const can be discarded safely
		argv[i++] = (char *) keyString (gpgSignatureRoot);
	}

	// append keys beneath root (fcrypt/sign/#_) as gpg signature keys
	if (gpgSignatureRoot)
	{
		ksRewind (pluginConfig);
		while ((k = ksNext (pluginConfig)) != 0)
		{
			const char * kStringVal = keyString (k);
			if (keyIsBelow (k, gpgSignatureRoot) && strlen (kStringVal) > 0)
			{
				argv[i++] = "-u";
				// NOTE argv[] values will not be modified, so const can be discarded safely
				argv[i++] = (char *) kStringVal;
			}
		}
	}

	// if we are in test mode we add the trust model
	if (testMode > 0)
	{
		argv[i++] = "--trust-model";
		argv[i++] = "always";
	}

	// ASCII armor in text mode
	if (textMode)
	{
		argv[i++] = "--armor";
	}

	// prepare rest of the argument vector
	if (recipientCount > 0)
	{
		// encrypt the file
		argv[i++] = "-e";
	}

	if (signatureCount > 0)
	{
		if (textMode && recipientCount == 0)
		{
			// clear-sign the file
			argv[i++] = "--clearsign";
		}
		else
		{
			// sign the file
			argv[i++] = "-s";
		}
	}

	argv[i++] = (char *) keyString (parentKey);
	argv[i++] = NULL;

	// NOTE the encryption process works like this:
	// gpg2 --batch --yes -o encryptedFile -r keyID -e configFile
	// mv encryptedFile configFile

	return fcryptGpgCallAndCleanup (parentKey, pluginConfig, argv, argc, tmpFileFd, tmpFile);
}
Example #2
0
/**
 * @brief decrypt the file specified at parentKey
 * @param pluginConfig holds the plugin configuration
 * @param parentKey holds the path to the file to be encrypted. Will hold an error description in case of failure.
 * @param state holds the plugin state
 * @retval 1 on success
 * @retval -1 on error, errorKey holds an error description
 */
static int fcryptDecrypt (KeySet * pluginConfig, Key * parentKey, fcryptState * state)
{
	int tmpFileFd = -1;
	char * tmpFile = getTemporaryFileName (pluginConfig, keyString (parentKey), &tmpFileFd);
	if (!tmpFile)
	{
		ELEKTRA_SET_ERROR (87, parentKey, "Memory allocation failed");
		return -1;
	}

	const size_t testMode = inTestMode (pluginConfig);

	// prepare argument vector for gpg call
	// 8 static arguments (magic number below) are:
	//   1. path to the binary
	//   2. --batch
	//   3. -o
	//   4. path to tmp file
	//   5. yes
	//   6. -d
	//   7. file to be encrypted
	//   8. NULL terminator
	int argc = 8 + (2 * testMode);
	char * argv[argc];
	int i = 0;

	argv[i++] = NULL;
	argv[i++] = "--batch";
	argv[i++] = "--yes";

	// if we are in test mode we add the trust model
	if (testMode)
	{
		argv[i++] = "--trust-model";
		argv[i++] = "always";
	}

	argv[i++] = "-o";
	argv[i++] = tmpFile;
	argv[i++] = "-d";
	// safely discarding const from keyString() return value
	argv[i++] = (char *) keyString (parentKey);
	argv[i++] = NULL;

	// NOTE the decryption process works like this:
	// gpg2 --batch --yes -o tmpfile -d configFile
	int result = ELEKTRA_PLUGIN_FUNCTION (gpgCall) (pluginConfig, parentKey, NULL, argv, argc);
	if (result == 1)
	{
		state->originalFilePath = elektraStrDup (keyString (parentKey));
		state->tmpFilePath = tmpFile;
		state->tmpFileFd = tmpFileFd;
		keySetString (parentKey, tmpFile);
	}
	else
	{
		// if anything went wrong above the temporary file is shredded and removed
		shredTemporaryFile (tmpFileFd, parentKey);
		if (unlink (tmpFile))
		{
			ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_UNLINK, parentKey, "Affected file: %s, error description: %s", tmpFile,
					      strerror (errno));
		}
		if (close (tmpFileFd))
		{
			ELEKTRA_ADD_WARNINGF (ELEKTRA_WARNING_FCRYPT_CLOSE, parentKey, "%s", strerror (errno));
		}
		elektraFree (tmpFile);
	}
	return result;
}
Example #3
0
  int RowTemporaryWritter::process(Row& row)
  {
    if (this->columns.size() == 0)
    {
      uint16_t columnId = 1;
      for (Row::row_t::const_reverse_iterator it = row.computedRow.rbegin(); it != row.computedRow.rend(); ++it)
      {
        if (!(*it).displayed)
          continue;
        
        std::string name = (*it).columnName;
        if ((*it).tableName != "")
        {
          // FIXME
          // name = (*it).tableName + "." + name;
        }
        unsigned int ID = columnId;
        unsigned int size = (*it).size; 
        aq::ColumnType type = (*it).type;
        std::string type_str = columnTypeToStr(type);

        Column::Ptr column(new Column(name, ID, size, type));
        column->Temporary = true;
        column->setTableName((*it).tableName);
        this->columns.push_back(column);

        boost::shared_ptr<ColumnTemporaryWritter> ctw(new ColumnTemporaryWritter);
        ctw->column = column;
        ctw->filename = getTemporaryFileName( tableId, columnId, 0, type_str.c_str(), size);
        ctw->filename = path + "/" + ctw->filename;
        ctw->file = fopen(ctw->filename.c_str(), "wb");
        this->columnsWritter.push_back(ctw);
        
        columnId++;
      }
    }

    if (row.completed)
    {
      this->totalCount += 1;

      uint16_t c = 0;
      uint64_t count = row.count;
      for (Row::row_t::const_reverse_iterator it = row.computedRow.rbegin(); it != row.computedRow.rend(); ++it)
      {
        if (!(*it).displayed)
          continue;
        assert((*it).item != NULL);

        switch (this->columnsWritter[c]->column->Type)
        {
        case ColumnType::COL_TYPE_BIG_INT:
        case ColumnType::COL_TYPE_DATE:
          {
            int64_t value = static_cast<int64_t>((*it).item->numval);
            fwrite(&value, sizeof(int64_t), 1, this->columnsWritter[c]->file);
          }
          break;
        case ColumnType::COL_TYPE_DOUBLE:
          {
            double value = (*it).item->numval;
            fwrite(&value, sizeof(double), 1, this->columnsWritter[c]->file);
          }
          break;
        case ColumnType::COL_TYPE_INT:
          {
            int32_t value = static_cast<int32_t>((*it).item->numval);
            fwrite(&value, sizeof(int32_t), 1, this->columnsWritter[c]->file);
          }
          break;
        case ColumnType::COL_TYPE_VARCHAR:
          {
            assert(strlen((*it).item->strval.c_str()) <= this->columnsWritter[c]->column->Size);
            char * value = new char[this->columnsWritter[c]->column->Size + 1];
            memset(value, 0, this->columnsWritter[c]->column->Size + 1);
            strcpy(value, (*it).item->strval.c_str());
            fwrite(value, sizeof(char) * this->columnsWritter[c]->column->Size, 1, this->columnsWritter[c]->file);
            free(value);
          }
          break;
        }
        
        if ((this->totalCount % this->packetSize) == 0)
        {
          unsigned int packet = this->totalCount / this->packetSize;
          unsigned int ID = c + 1;
          unsigned int size = (*it).size; 
          aq::ColumnType type = (*it).type;
          std::string type_str = columnTypeToStr(type);
          boost::shared_ptr<ColumnTemporaryWritter> ctw = this->columnsWritter[c];
          ctw->filename = getTemporaryFileName( tableId, ID, packet, type_str.c_str(), size);
          ctw->filename = path + "/" + ctw->filename;
          fclose(ctw->file);
          ctw->file = fopen(ctw->filename.c_str(), "wb");
        }

        this->columnsWritter[c]->nbEl += 1;
        c++;
      }
    }

    if (row.flush)
    {
      for (auto& ctw : this->columnsWritter) 
      { 
        fclose(ctw->file); 
        ctw->file = 0;
      }
    }

    return 0;
  }