Exemplo n.º 1
0
/* The main GPG decryption routine for libfko.
*/
int
gpgme_decrypt(fko_ctx_t fko_ctx, unsigned char *indata,
        size_t in_len, const char *pw, unsigned char **out, size_t *out_len)
{
    char                   *tmp_buf;
    int                     res;

    gpgme_ctx_t             gpg_ctx     = NULL;
    gpgme_data_t            cipher      = NULL;
    gpgme_data_t            plaintext   = NULL;
    gpgme_error_t           err;
    gpgme_decrypt_result_t  decrypt_res;
    gpgme_verify_result_t   verify_res;

    /* Initialize gpgme
    */
    res = init_gpgme(fko_ctx);
    if(res != FKO_SUCCESS)
        return(res);

    gpg_ctx = fko_ctx->gpg_ctx;

    err = gpgme_data_new(&plaintext);
    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;

        fko_ctx->gpg_err = err;

        return(FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ);
    }

    /* Initialize the cipher data (place into gpgme_data object)
    */
    err = gpgme_data_new_from_mem(&cipher, (char*)indata, in_len, 0);
    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        gpgme_data_release(plaintext);
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;

        fko_ctx->gpg_err = err;

        return(FKO_ERROR_GPGME_CIPHER_DATA_OBJ);
    }

    /* Set the passphrase callback.
    */
    gpgme_set_passphrase_cb(gpg_ctx, my_passphrase_cb, (void*)pw);

    /* Now decrypt and verify.
    */
    err = gpgme_op_decrypt_verify(gpg_ctx, cipher, plaintext);
    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        gpgme_data_release(plaintext);
        gpgme_data_release(cipher);
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;

        fko_ctx->gpg_err = err;

        return(FKO_ERROR_GPGME_DECRYPT_FAILED);
    }

    /* Done with the cipher text.
    */
    gpgme_data_release(cipher);

    /* We check the "usupported_algorithm" flag in the decrypt result.
    */
    decrypt_res = gpgme_op_decrypt_result(gpg_ctx);

    if(decrypt_res->unsupported_algorithm)
    {
        gpgme_data_release(plaintext);
        gpgme_release(gpg_ctx);
        fko_ctx->gpg_ctx = NULL;

        return(FKO_ERROR_GPGME_DECRYPT_UNSUPPORTED_ALGORITHM);
    }

    /* Now verify the signatures if so configured.
    */
    if(fko_ctx->verify_gpg_sigs)
    {
        verify_res  = gpgme_op_verify_result(gpg_ctx);

        res = process_sigs(fko_ctx, verify_res);

        if(res != FKO_SUCCESS)
        {
            gpgme_data_release(plaintext);
            gpgme_release(gpg_ctx);
            fko_ctx->gpg_ctx = NULL;

            return(res);
        }
    }

    /* Get the encrypted data and its length from the gpgme data object.
    */
    tmp_buf = gpgme_data_release_and_get_mem(plaintext, out_len);

    /* Use calloc here with an extra byte because I am not sure if all systems
     * will include the terminating NULL with the decrypted data (which is
     * expected to be a string).
    */
    *out = calloc(1, *out_len+1); /* This is freed upon fko_ctx destruction. */

    if(*out == NULL)
        res = FKO_ERROR_MEMORY_ALLOCATION;
    else
    {
        memcpy(*out, tmp_buf, *out_len);
        res = FKO_SUCCESS;
    }

    gpgme_free(tmp_buf);

    return(res);
}
Exemplo n.º 2
0
int
main (int argc, char *argv[])
{
  DSPAM_CTX *CTX = NULL, *CTX2;
  char *user;
  int do_sigs   = 0;
  int do_probs  = 0;
  int do_unused = 0;
  int age_sigs   = 14;
  int age_probs  = 30;
  int age_unused[4] = { 90, 30, 15, 15 };
  int i, help = 0;
  struct nt *users = NULL;
  struct nt_node *node = NULL;
#ifndef _WIN32
#ifdef TRUSTED_USER_SECURITY
  struct passwd *p = getpwuid (getuid ());

#endif
#endif

 /* Read dspam.conf */
                                                                                
  agent_config = read_config(NULL);
  if (!agent_config) {
    LOG(LOG_ERR, ERR_AGENT_READ_CONFIG);
    fprintf (stderr, ERR_AGENT_READ_CONFIG "\n");
    exit(EXIT_FAILURE);
  }
                                                                                
  if (!_ds_read_attribute(agent_config, "Home")) {
    LOG(LOG_ERR, ERR_AGENT_DSPAM_HOME);
    fprintf (stderr, ERR_AGENT_DSPAM_HOME "\n");
    goto bail;
  }
                                                                                
  if (libdspam_init(_ds_read_attribute(agent_config, "StorageDriver")) != 0) {
    LOG(LOG_ERR, ERR_DRV_INIT);
    fprintf (stderr, ERR_DRV_INIT "\n");
    _ds_destroy_config(agent_config);
    exit(EXIT_FAILURE);
  }

#ifndef _WIN32
#ifdef TRUSTED_USER_SECURITY
  if (!_ds_match_attribute(agent_config, "Trust", p->pw_name) && p->pw_uid) {
    fprintf(stderr, ERR_TRUSTED_MODE "\n");
    goto bail;
  }
#endif
#endif

  for(i=0;i<argc;i++) {
                                                                                
    if (!strncmp (argv[i], "--profile=", 10))
    {
      if (!_ds_match_attribute(agent_config, "Profile", argv[i]+10)) {
        LOG(LOG_ERR, ERR_AGENT_NO_SUCH_PROFILE, argv[i]+10);
        fprintf (stderr, ERR_AGENT_NO_SUCH_PROFILE "\n", argv[i]+10);
        goto bail;
      } else {
        _ds_overwrite_attribute(agent_config, "DefaultProfile", argv[i]+10);
      }
      break;
    }
  }

#ifdef DEBUG
  fprintf (stdout, "dspam_clean starting\n");
#endif

  if (_ds_read_attribute(agent_config, "PurgeSignatures") &&
      !_ds_match_attribute(agent_config, "PurgeSignatures", "off"))  
  {
    do_sigs = 1;
    age_sigs = atoi(_ds_read_attribute(agent_config, "PurgeSignatures"));
  }
  
  if (_ds_read_attribute(agent_config, "PurgeNeutral") &&
      !_ds_match_attribute(agent_config, "PurgeNeutral", "off"))
  {
    do_probs = 1;
    age_probs = atoi(_ds_read_attribute(agent_config, "PurgeNeutral"));
  }

  if (_ds_read_attribute(agent_config, "PurgeUnused") &&
      !_ds_match_attribute(agent_config, "PurgeUnused", "off"))
  {
    int i;

    do_unused = 1;
    age_unused[0] = atoi(_ds_read_attribute(agent_config, "PurgeUnused"));
    age_unused[1] = atoi(_ds_read_attribute(agent_config, "PurgeHapaxes"));
    age_unused[2] = atoi(_ds_read_attribute(agent_config, "PurgeHits1S"));
    age_unused[3] = atoi(_ds_read_attribute(agent_config, "PurgeHits1I"));

    for(i=0;i<4;i++) 
      if (age_unused[i]==0)
        do_unused = 0;
  }

  users = nt_create(NT_CHAR);
  if (users == NULL) {
    fprintf(stderr, "%s", ERR_MEM_ALLOC);
    goto bail;
  }

  for(i=0;i<argc;i++) {
    if (!strncmp(argv[i], "-p", 2)) {
      do_probs = 1;
      if (strlen(argv[i])>2)
        age_probs = atoi(argv[i]+2);
    }
    else if (!strncmp(argv[i], "-s", 2)) {
      do_sigs = 1;
      if (strlen(argv[i])>2)
        age_sigs = atoi(argv[i]+2);
    } else if (!strncmp(argv[i], "-u", 2)) {
      do_unused = 1;
      if (strlen(argv[i])>2) {
        char *c = strdup(argv[i]+2);
        char *d = strtok(c, ",");
        int j = 0;
        while(d != NULL && j<4) {
          age_unused[j] = atoi(d);
          j++;
          d = strtok(NULL, ",");
        }
        free(c);
      }
    }
    else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
      help = 1;
    else if (i>0) 
      nt_add(users, argv[i]);
  }

  if (help || (!do_probs && !do_sigs && !do_unused)) {
    fprintf(stderr, "%s", CLEANSYNTAX);
    _ds_destroy_config(agent_config);
    nt_destroy(users);
    libdspam_shutdown();
    if (help) {
      exit(EXIT_SUCCESS);
    }
    exit(EXIT_FAILURE);
  }
      
  open_ctx = open_mtx = NULL;

  signal (SIGINT, dieout);
  signal (SIGPIPE, dieout);
  signal (SIGTERM, dieout);

  dspam_init_driver (NULL);

  if (users->items == 0) {
    CTX = dspam_create (NULL, NULL, _ds_read_attribute(agent_config, "Home"), DSM_TOOLS, 0);
    open_ctx = CTX;
    if (CTX == NULL)
    {
      fprintf (stderr, "Could not initialize context: %s\n", strerror (errno));
      dspam_shutdown_driver (NULL);
      goto bail;
    }

    set_libdspam_attributes(CTX);
    if (dspam_attach(CTX, NULL)) {
      LOG (LOG_WARNING, "unable to attach dspam context");
      fprintf (stderr, "Unable to attach DSPAM context\n");
      goto bail;
    }

    user = _ds_get_nextuser (CTX);
  } else {
    node = users->first;
    if (node != NULL)
      user = node->ptr;
    else 
      goto bail;
  }

  while (user != NULL)
  {
#ifdef DEBUG
    printf ("PROCESSING USER: %s\n", user);
#endif
    CTX2 = dspam_create (user, NULL,  _ds_read_attribute(agent_config, "Home"), DSM_TOOLS, 0);
    open_mtx = CTX2;

    if (CTX2 == NULL)
    {
      fprintf (stderr, "Could not initialize context: %s\n",
               strerror (errno));
      return EUNKNOWN;
    }

    set_libdspam_attributes(CTX2);
    if (dspam_attach(CTX2, NULL)) {
      LOG (LOG_WARNING, "unable to attach dspam context");
      fprintf (stderr, "Unable to attach DSPAM context\n");
      goto bail;
    }

    if (do_sigs)
      process_sigs(CTX2, age_sigs);
    if (do_probs)
      process_probs(CTX2, age_probs);
    if (do_unused)
      process_unused(CTX2, age_unused[0], age_unused[1], age_unused[2], age_unused[3]);
    dspam_destroy (CTX2);
    open_mtx = NULL;

    if (users->items == 0) {
      user = _ds_get_nextuser (CTX);
    } else {
      if (node == NULL || node->next == NULL) {
        node = NULL;
        user = NULL;
      } else {
        node = node->next;
        user = node->ptr;
      }
    }
  }

  if (users->items == 0) {
    dspam_destroy (CTX);
    open_ctx = NULL;
  }

  dspam_shutdown_driver (NULL);
  _ds_destroy_config(agent_config);
  nt_destroy(users);
  libdspam_shutdown();
  exit (EXIT_SUCCESS);

bail:

  if (open_ctx)
    dspam_destroy(open_ctx);
  if (open_mtx)
    dspam_destroy(open_mtx);
  _ds_destroy_config(agent_config);
  nt_destroy(users);
  libdspam_shutdown();
  exit(EXIT_FAILURE);
}