int parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout ) { int r; struct handler * h; vector cmdvec = NULL; struct timespec tmo; r = get_cmdvec(cmd, &cmdvec); if (r) { *reply = genhelp_handler(cmd, r); *len = strlen(*reply) + 1; return 0; } h = find_handler(fingerprint(cmdvec)); if (!h || !h->fn) { *reply = genhelp_handler(cmd, EINVAL); *len = strlen(*reply) + 1; free_keys(cmdvec); return 0; } /* * execute handler */ if (clock_gettime(CLOCK_MONOTONIC, &tmo) == 0) { tmo.tv_sec += timeout; } else { tmo.tv_sec = 0; } if (h->locked) { int locked = 0; struct vectors * vecs = (struct vectors *)data; pthread_cleanup_push(cleanup_lock, &vecs->lock); if (tmo.tv_sec) { r = timedlock(&vecs->lock, &tmo); } else { lock(&vecs->lock); r = 0; } if (r == 0) { locked = 1; pthread_testcancel(); r = h->fn(cmdvec, reply, len, data); } pthread_cleanup_pop(locked); } else r = h->fn(cmdvec, reply, len, data); free_keys(cmdvec); return r; }
int load_keys (void) { int r = 0; keys = vector_alloc(); if (!keys) return 1; r += add_key(keys, "list", LIST, 0); r += add_key(keys, "show", LIST, 0); r += add_key(keys, "add", ADD, 0); r += add_key(keys, "remove", DEL, 0); r += add_key(keys, "del", DEL, 0); r += add_key(keys, "switch", SWITCH, 0); r += add_key(keys, "switchgroup", SWITCH, 0); r += add_key(keys, "suspend", SUSPEND, 0); r += add_key(keys, "resume", RESUME, 0); r += add_key(keys, "reinstate", REINSTATE, 0); r += add_key(keys, "fail", FAIL, 0); r += add_key(keys, "resize", RESIZE, 0); r += add_key(keys, "reset", RESET, 0); r += add_key(keys, "reload", RELOAD, 0); r += add_key(keys, "forcequeueing", FORCEQ, 0); r += add_key(keys, "disablequeueing", DISABLEQ, 0); r += add_key(keys, "restorequeueing", RESTOREQ, 0); r += add_key(keys, "paths", PATHS, 0); r += add_key(keys, "maps", MAPS, 0); r += add_key(keys, "multipaths", MAPS, 0); r += add_key(keys, "path", PATH, 1); r += add_key(keys, "map", MAP, 1); r += add_key(keys, "multipath", MAP, 1); r += add_key(keys, "group", GROUP, 1); r += add_key(keys, "reconfigure", RECONFIGURE, 0); r += add_key(keys, "daemon", DAEMON, 0); r += add_key(keys, "status", STATUS, 0); r += add_key(keys, "stats", STATS, 0); r += add_key(keys, "topology", TOPOLOGY, 0); r += add_key(keys, "config", CONFIG, 0); r += add_key(keys, "blacklist", BLACKLIST, 0); r += add_key(keys, "devices", DEVICES, 0); r += add_key(keys, "raw", RAW, 0); r += add_key(keys, "wildcards", WILDCARDS, 0); r += add_key(keys, "quit", QUIT, 0); r += add_key(keys, "exit", QUIT, 0); r += add_key(keys, "shutdown", SHUTDOWN, 0); r += add_key(keys, "getprstatus", GETPRSTATUS, 0); r += add_key(keys, "setprstatus", SETPRSTATUS, 0); r += add_key(keys, "unsetprstatus", UNSETPRSTATUS, 0); r += add_key(keys, "format", FMT, 1); r += add_key(keys, "json", JSON, 0); if (r) { free_keys(keys); keys = NULL; return 1; } return 0; }
void free_all_keys(RegEntryDesc *descs){ RegEntryDesc *tmp = descs; for(;tmp->servicename != NULL; ++tmp){ free_keys(tmp->entries); free(tmp->servicename); } free(descs); }
static void free_keys(struct kmap_trie_entry *kmap, struct kmap_trie_entry *parent, int prepare) { if (kmap == NULL) return; free_keys(kmap->contseq, kmap, prepare); free_keys(kmap->next, kmap, prepare); if (!kmap->alloced && kmap - parent == 1) return; /* find first element in array */ while (!kmap->alloced) kmap--; kmap->alloced += prepare ? 1 : -1; if (!prepare && kmap->alloced == 1) free(kmap); }
static ERL_NIF_TERM x509_make_cert_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int expiry, serial; ASN1_INTEGER *asn1serial = NULL; BIGNUM *bn_rsa_genkey=NULL; BIO *bio_signing_private=NULL, *bio_issuer_cert = NULL, *bio_newcert_public = NULL; BIO *bio_x509=NULL; char *issuer_cert_pem=NULL; X509 *pX509 = NULL; X509 *pIssuerX509 = NULL; X509_NAME *pX509Name = NULL; X509_NAME *pIssuerName = NULL; x509_subject_entry *subject_entries; int num_subject_entries; int iret = 0; RSA *rsa=NULL; unsigned long f4=RSA_F4; unsigned args_len=-1; char *signing_keys[2], *cert_keys[2]; ERL_NIF_TERM tail, *arg_terms=NULL; int idx; ERL_NIF_TERM ret, x509term; int x509len; unsigned char *x509data; EVP_PKEY *evp_signing_private = EVP_PKEY_new(); EVP_PKEY *evp_newcert_public_key = EVP_PKEY_new(); /* set RSA key gen type */ bn_rsa_genkey = BN_new(); BN_set_word(bn_rsa_genkey, f4); // // 1. stick subject of CA cert into NewCert // 2. stick public key of NewKeypair into NewCert // 3. sign NewCert with CA keypair /* Should be 6 elements in the list of X509 parameters. We'll check each */ if(!enif_get_list_length(env, argv[0], &args_len) || args_len != 6 || NULL == (arg_terms = (ERL_NIF_TERM*)malloc(args_len * sizeof(ERL_NIF_TERM)))) return enif_make_badarg(env); enif_get_list_cell(env, argv[0], &arg_terms[0], &tail); for(idx=1; idx<args_len; idx++){ if(!enif_get_list_cell(env, tail, &arg_terms[idx], &tail)){ free(arg_terms); return enif_make_badarg(env); } } idx=0; /* get the signing private key */ x509_parse_keypair(env, "signing_key", arg_terms[idx++], signing_keys); /* get the issuer cert */ x509_parse_issuer_cert(env, arg_terms[idx++], &issuer_cert_pem); /* get the soon-to-be cert's public key */ x509_parse_keypair(env, "newcert_public_key", arg_terms[idx++], cert_keys); /* get the subject */ x509_parse_subject(env, arg_terms[idx++], &num_subject_entries, &subject_entries); /* get the serial number */ x509_parse_int_tuple(env, arg_terms[idx++], "serial", &serial); /* get the expiry */ x509_parse_int_tuple(env, arg_terms[idx++], "expiry", &expiry); /* work the OpenSSL cert creation magic */ if ((bio_signing_private = BIO_new_mem_buf(signing_keys[1], -1)) && (rsa = PEM_read_bio_RSAPrivateKey(bio_signing_private, NULL, NULL, NULL)) && (iret = EVP_PKEY_assign_RSA(evp_signing_private, rsa)) && (bio_newcert_public = BIO_new_mem_buf(cert_keys[0], -1)) && (evp_newcert_public_key = PEM_read_bio_PUBKEY(bio_newcert_public, NULL, NULL, NULL)) && (bio_issuer_cert = BIO_new_mem_buf(issuer_cert_pem, -1)) && (pIssuerX509 = PEM_read_bio_X509(bio_issuer_cert, NULL, NULL, NULL)) && (pX509 = X509_new())) { /* if we've managed to generate a key and allocate structure memory, set X509 fields */ asn1serial = ASN1_INTEGER_new(); X509_set_version(pX509, 2); /* cert_helper uses '3' here */ ASN1_INTEGER_set(asn1serial, serial); X509_set_serialNumber(pX509, asn1serial); X509_gmtime_adj(X509_get_notBefore(pX509),0); X509_gmtime_adj(X509_get_notAfter(pX509),(long)60*60*24*expiry); X509_set_pubkey(pX509, evp_newcert_public_key); pX509Name = X509_get_subject_name(pX509); while(--num_subject_entries >= 0){ X509_NAME_add_entry_by_txt(pX509Name, (subject_entries[num_subject_entries]).name, MBSTRING_ASC, (unsigned char*)(subject_entries[num_subject_entries]).value, -1, -1, 0); } pIssuerName = X509_get_issuer_name(pIssuerX509); X509_set_issuer_name(pX509, pIssuerName); X509_sign(pX509, evp_signing_private, digest); bio_x509 = BIO_new(BIO_s_mem()); PEM_write_bio_X509(bio_x509, pX509); x509len = BIO_get_mem_data(bio_x509, &x509data); memcpy(enif_make_new_binary(env, x509len, &x509term), x509data, x509len); ret = enif_make_tuple2(env, atom_x509_cert, x509term); } done: if(arg_terms) free(arg_terms); free_keys(signing_keys); free_keys(cert_keys); free_subject_entries(num_subject_entries, subject_entries); if(pX509) X509_free(pX509); if(pIssuerX509) X509_free(pIssuerX509); if(issuer_cert_pem) free(issuer_cert_pem); if(bio_issuer_cert) { BIO_set_close(bio_issuer_cert, BIO_NOCLOSE); BIO_free_all(bio_issuer_cert); } if(bio_signing_private) { BIO_set_close(bio_signing_private, BIO_NOCLOSE); BIO_free_all(bio_signing_private); } if(bio_newcert_public) { BIO_set_close(bio_newcert_public, BIO_NOCLOSE); BIO_free_all(bio_newcert_public); } if(bio_x509) BIO_free_all(bio_x509); if(asn1serial) ASN1_INTEGER_free(asn1serial); if(bn_rsa_genkey) BN_free(bn_rsa_genkey); if(rsa) RSA_free(rsa); return ret; }
/** * crypto: the crypto service (#SeahorseServiceCrypto) * recipients: A list of recipients (keyids "openpgp:B8098FB063E2C811") * Must be empty when symmetric encryption is used. * signer: optional, the keyid of the signer * flags: FLAG_SYMMETRIC to perform symmetric encryption * cleartext: the text to encrypt * clearlength: Length of the cleartext * crypttext: the encrypted text (out) * cryptlength: the length of this text (out) * textmode: TRUE if gpgme should use textmode * ascii_armor: TRUE if GPGME should use ascii armor * error: The Error * * Handles encryption in a generic way. Can be used by several DBus APIs * * Returns TRUE on success **/ static gboolean crypto_encrypt_generic (SeahorseServiceCrypto *crypto, const char **recipients, const char *signer, int flags, const char *cleartext, gsize clearlength, char **crypttext, gsize *cryptlength, gboolean textmode, gboolean ascii_armor, GError **error) { GList *recipkeys = NULL; SeahorseGpgmeOperation *pop; SeahorseObject *signkey = NULL; SeahorseObject *skey; gpgme_key_t *recips; gboolean symmetric = FALSE; gpgme_data_t plain, cipher; gpgme_error_t gerr; gboolean ret = TRUE; GSettings *settings; gchar *keyid; if ((flags & FLAG_SYMMETRIC) == FLAG_SYMMETRIC) symmetric = TRUE; if (symmetric && recipients[0] != NULL) { g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Recipients specified for symmetric encryption")); return FALSE; } /* The signer */ if (signer && signer[0]) { signkey = seahorse_context_object_from_dbus (SCTX_APP (), signer); if (!signkey) { g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Invalid or unrecognized signer: %s"), signer); return FALSE; } if (!SEAHORSE_IS_GPGME_KEY (signkey) || !(seahorse_object_get_flags (signkey) & SEAHORSE_FLAG_CAN_SIGN)) { g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Key is not valid for signing: %s"), signer); return FALSE; } } if (!symmetric) { /* The recipients */ for( ; recipients[0]; recipients++) { skey = seahorse_context_object_from_dbus (SCTX_APP (), recipients[0]); if (!skey) { g_list_free (recipkeys); g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Invalid or unrecognized recipient: %s"), recipients[0]); return FALSE; } if (!SEAHORSE_IS_GPGME_KEY (skey) || !(seahorse_object_get_flags (skey) & SEAHORSE_FLAG_CAN_ENCRYPT)) { g_list_free (recipkeys); g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Key is not a valid recipient for encryption: %s"), recipients[0]); return FALSE; } recipkeys = g_list_prepend (recipkeys, SEAHORSE_PGP_KEY (skey)); } if (!recipkeys) { g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("No recipients specified")); return FALSE; } } pop = seahorse_gpgme_operation_new (NULL); /* new data form text */ gerr = gpgme_data_new_from_mem (&plain, cleartext, clearlength, FALSE); g_return_val_if_fail (GPG_IS_OK (gerr), FALSE); gerr = gpgme_data_new (&cipher); g_return_val_if_fail (GPG_IS_OK (gerr), FALSE); /* encrypt with armor */ gpgme_set_textmode (pop->gctx, textmode); gpgme_set_armor (pop->gctx, ascii_armor); if (symmetric) { /* gpgme_op_encrypt{_sign,}_start() will perform symmetric encryption * when no recipients are specified. */ recips = NULL; } else { /* Add the default key if set and necessary */ settings = g_settings_new ("org.gnome.crypto.pgp"); if (g_settings_get_boolean (settings, "encrypt-to-self")) { keyid = g_settings_get_string (settings, "default-key"); if (keyid && keyid[0]) { skey = seahorse_context_find_object (NULL, g_quark_from_string (keyid), SEAHORSE_LOCATION_LOCAL); if (SEAHORSE_IS_PGP_KEY (skey)) recipkeys = g_list_append (recipkeys, skey); } g_free (keyid); } g_object_unref (settings); /* Make keys into the right format for GPGME */ recips = keylist_to_keys (recipkeys); g_list_free (recipkeys); } /* Do the encryption */ if (signkey) { gpgme_signers_add (pop->gctx, seahorse_gpgme_key_get_private (SEAHORSE_GPGME_KEY (signkey))); gerr = gpgme_op_encrypt_sign_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher); } else { gerr = gpgme_op_encrypt_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher); } free_keys (recips); /* Frees cipher */ ret = process_crypto_result (pop, gerr, cipher, crypttext, cryptlength, error); g_object_unref (pop); gpgme_data_release (plain); return ret; }
void pbs_test(char *data) { pbs_parameters pbs; pbs_pk pk; pbs_sk sk; pbs_bank_state bstate; pbs_client_state cstate; pbs_signature signature; pbs_workspace workspace; struct timespec bank_start, bank_end, verify_start, verify_end; long bank_nanos = 0; long verify_nanos = 0; int success, i = 0; load_parameters(&pbs); /* use this to generate keys */ /* gen_keys(&pbs, &sk, &pk); printf("skx:%s\n", BN_bn2hex(sk.x)); printf("pky:%s\n", BN_bn2hex(pk.y)); */ load_keys(&sk, &pk); int date1 = time(NULL) / 86400; int date2 = date1 + 7; int date3 = date1 + 28; int infolen = 3 * sizeof(date1) + 6; /* 3 ints, 2 commas, null byte */ char info[infolen]; snprintf(info, infolen, "%d,%d,%d", date1, date2, date3); /* printf("%s\n", info); */ /* do a bunch of signatures and verifies */ /* FIXME this can be made much more efficient */ char *pos = data; for (i = 0; i < NUM_LOOPS_PER_RUN; ++i) { BIGNUM *a = BN_new(); BIGNUM *b = BN_new(); BIGNUM *e = BN_new(); BIGNUM *r = BN_new(); BIGNUM *c = BN_new(); BIGNUM *s = BN_new(); BIGNUM *d = BN_new(); /* client sends bank request, bank sends back a,b,info */ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &bank_start); bank_sign_init(a, b, &bstate, info, &pbs); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &bank_end); bank_nanos = get_timer_nanos(&bank_start, &bank_end); /* client initialization */ sign_init(&cstate, &signature, &workspace); /* client uses a,b,info and its message to produce e for bank */ sign_update(e, &cstate, &pbs, &pk, data, info, a, b); /* bank uses e to produce r,c,s,d for client */ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &bank_start); bank_sign_update(r, c, s, d, &bstate, &pbs, &sk, e); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &bank_end); bank_nanos += get_timer_nanos(&bank_start, &bank_end); /* client finishes signature */ sign_final(&signature, r, c, s, d, &cstate, &pbs); /* now verify */ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &verify_start); success = verify(&signature, &pk, &pbs, info, data, &workspace); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &verify_end); verify_nanos = get_timer_nanos(&verify_start, &verify_end); if (success != 0) { printf("Signature incorrect\n"); } pos += CELL_NETWORK_SIZE + 1; BN_free(a); BN_free(b); BN_free(e); BN_free(r); BN_free(c); BN_free(s); BN_free(d); free_bank_state(&bstate); free_client_state(&cstate); free_signature(&signature); free_workspace(&workspace); printf("pbs Bank effort: 1 signature %ld nanoseconds (%d/%d)\n", bank_nanos, i+1, NUM_LOOPS_PER_RUN); printf("pbs Signature verification: 1 verify %ld nanoseconds (%d/%d)\n", verify_nanos, i+1, NUM_LOOPS_PER_RUN); } free_keys(&sk, &pk); free_parameters(&pbs); #ifdef DEBUG /* signature results */ printBN(signature.delta, "delta:"); printBN(signature.sigma, "sigma:"); printBN(signature.omega, "omega:"); printBN(signature.rho, "rho:"); printf("info:%s\n", info); printf("message:%s\n", message); printBN(a, "a:"); printBN(b, "b:"); printBN(e, "e:"); printBN(r, "r:"); printBN(c, "c:"); printBN(s, "s:"); printBN(d, "d:"); printBN(cstate.t1, "t1:"); printBN(cstate.t2, "t2:"); printBN(cstate.t3, "t3:"); printBN(cstate.t4, "t4:"); printBN(cstate.epsilon, "epsilon:"); printBN(bstate.d, "d:"); printBN(bstate.s, "s:"); printBN(bstate.u, "u:"); printBN(pbs.g, "g:"); printBN(pbs.p, "p:"); printBN(pbs.q, "q:"); printBN(pk.y, "y:"); printBN(sk.x, "x:"); /* sanity checks */ BIGNUM *temp1 = BN_new(); BIGNUM *temp2 = BN_new(); BN_CTX *ctx = BN_CTX_new(); /* q |? p-1 */ BN_sub(temp1, pbs.p, BN_value_one()); BN_mod(temp2, temp1, pbs.q, ctx); printf("q|p-1 remainder: %s\n", BN_bn2hex(temp2)); /* g^q =? 1 mod p */ BN_mod_exp(temp1, pbs.g, pbs.q, pbs.p, ctx); printf("g^q =? 1 mod p result: %s\n", BN_bn2hex(temp1)); #endif /* BN_free(a); BN_free(b); BN_free(e); BN_free(r); BN_free(c); BN_free(s); BN_free(d); free_bank_state(&bstate); free_client_state(&cstate); free_signature(&signature); free_keys(&sk, &pk); free_parameters(&pbs); */ }
RegEntry *get_keys(char *servicename){ RegEntry *res = NULL; HKEY prog_key; int key_opened = 0; int i; DWORD ret; char *copy; char *tmpbuf; DWORD tmpbuflen; char key_to_open[MAX_KEY_LEN]; DWORD val_type; char *val_data = malloc(MAX_KEY_LEN); DWORD val_datalen; DWORD val_datasiz = MAX_KEY_LEN; if(strlen(PROG_KEY) + strlen(servicename) + 2 > MAX_KEY_LEN) goto error; sprintf(key_to_open,"%s\\%s",PROG_KEY,servicename); if(RegOpenKeyEx(BASE_KEY, key_to_open, 0, KEY_QUERY_VALUE, &prog_key) != ERROR_SUCCESS) goto error; key_opened = 1; res = malloc(num_reg_entries*sizeof(RegEntry)); for(i=0;i<num_reg_entries;++i) res[i].name = NULL; for(i=0;i<num_reg_entries;++i){ for(;;){ val_datalen = val_datasiz; ret = RegQueryValueEx(prog_key, reg_entries[i].name, NULL, &val_type, (BYTE *) val_data, &val_datalen); if(ret == ERROR_SUCCESS){ if(reg_entries[i].type == val_type) break; else goto error; } else if(ret == ERROR_MORE_DATA){ val_data = realloc(val_data,val_datasiz = val_datalen); } else { goto error; } } res[i] = reg_entries[i]; copy = NULL; switch(reg_entries[i].type){ case REG_EXPAND_SZ: if(!val_datalen || val_data[0] == '\0'){ copy = (char *) noString; res[i].data.expand.unexpanded = (char *) noString; } else { tmpbuf = malloc(MAX_KEY_LEN); tmpbuflen = (DWORD) MAX_KEY_LEN; for(;;){ ret = ExpandEnvironmentStrings(val_data,tmpbuf,tmpbuflen); if(!ret){ free(tmpbuf); goto error; }else if(ret > tmpbuflen){ tmpbuf=realloc(tmpbuf,tmpbuflen=ret); } else { copy = strdup(tmpbuf); free(tmpbuf); break; } } res[i].data.expand.unexpanded = strdup(val_data); } case REG_MULTI_SZ: case REG_SZ: if(!copy){ if(!val_datalen || ((val_datalen == 1 && val_data[0] == '\0') || (val_datalen == 2 && val_data[0] == '\0' && val_data[1] == '\0'))){ copy = (char *) noString; } else { copy = malloc(val_datalen); memcpy(copy,val_data,val_datalen); } } res[i].data.bytes = copy; break; case REG_DWORD: memcpy(&res[i].data.value,val_data,sizeof(DWORD)); break; default: goto error; } } RegCloseKey(prog_key); free(val_data); return res; error: free(val_data); if(res != NULL) free_keys(res); if(key_opened) RegCloseKey(prog_key); return NULL; }
static int get_cmdvec (char * cmd, vector *v) { int i; int r = 0; int get_param = 0; char * buff; struct key * kw = NULL; struct key * cmdkw = NULL; vector cmdvec, strvec; strvec = alloc_strvec(cmd); if (!strvec) return E_NOMEM; cmdvec = vector_alloc(); if (!cmdvec) { free_strvec(strvec); return E_NOMEM; } vector_foreach_slot(strvec, buff, i) { if (*buff == '"') continue; if (get_param) { get_param = 0; cmdkw->param = strdup(buff); continue; } kw = find_key(buff); if (!kw) { r = E_SYNTAX; goto out; } cmdkw = alloc_key(); if (!cmdkw) { r = E_NOMEM; goto out; } if (!vector_alloc_slot(cmdvec)) { FREE(cmdkw); r = E_NOMEM; goto out; } vector_set_slot(cmdvec, cmdkw); cmdkw->code = kw->code; cmdkw->has_param = kw->has_param; if (kw->has_param) get_param = 1; } if (get_param) { r = E_NOPARM; goto out; } *v = cmdvec; free_strvec(strvec); return 0; out: free_strvec(strvec); free_keys(cmdvec); return r; }
/** * crypto: the crypto service (#SeahorseServiceCrypto) * recipients: A list of recipients (keyids "openpgp:B8098FB063E2C811") * signer: optional, the keyid of the signer * flags: 0, not used * cleartext: the text to encrypt * clearlength: Length of the cleartext * crypttext: the encrypted text (out) * cryptlength: the length of this text (out) * textmode: TRUE if gpgme should use textmode * ascii_armor: TRUE if GPGME should use ascii armor * error: The Error * * Handles encryption in a generic way. Can be used by several DBus APIs * * Returns TRUE on success **/ static gboolean crypto_encrypt_generic (SeahorseServiceCrypto *crypto, const char **recipients, const char *signer, int flags, const char *cleartext, gsize clearlength, char **crypttext, gsize *cryptlength, gboolean textmode, gboolean ascii_armor, GError **error) { GList *recipkeys = NULL; SeahorseGpgmeOperation *pop; SeahorseObject *signkey = NULL; SeahorseObject *skey; gpgme_key_t *recips; gpgme_data_t plain, cipher; gpgme_error_t gerr; gboolean ret = TRUE; /* * TODO: Once we support different kinds of keys that support encryption * then all this logic will need to change. */ /* The signer */ if (signer && signer[0]) { signkey = seahorse_context_object_from_dbus (SCTX_APP (), signer); if (!signkey) { g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Invalid or unrecognized signer: %s"), signer); return FALSE; } if (!SEAHORSE_IS_GPGME_KEY (signkey) || !(seahorse_object_get_flags (signkey) & SEAHORSE_FLAG_CAN_SIGN)) { g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Key is not valid for signing: %s"), signer); return FALSE; } } /* The recipients */ for( ; recipients[0]; recipients++) { skey = seahorse_context_object_from_dbus (SCTX_APP (), recipients[0]); if (!skey) { g_list_free (recipkeys); g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Invalid or unrecognized recipient: %s"), recipients[0]); return FALSE; } if (!SEAHORSE_IS_GPGME_KEY (skey) || !(seahorse_object_get_flags (skey) & SEAHORSE_FLAG_CAN_ENCRYPT)) { g_list_free (recipkeys); g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("Key is not a valid recipient for encryption: %s"), recipients[0]); return FALSE; } recipkeys = g_list_prepend (recipkeys, SEAHORSE_PGP_KEY (skey)); } if (!recipkeys) { g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, _("No recipients specified")); return FALSE; } pop = seahorse_gpgme_operation_new (NULL); /* new data form text */ gerr = gpgme_data_new_from_mem (&plain, cleartext, clearlength, FALSE); g_return_val_if_fail (GPG_IS_OK (gerr), FALSE); gerr = gpgme_data_new (&cipher); g_return_val_if_fail (GPG_IS_OK (gerr), FALSE); /* encrypt with armor */ gpgme_set_textmode (pop->gctx, textmode); gpgme_set_armor (pop->gctx, ascii_armor); /* Add the default key if set and necessary */ if (seahorse_gconf_get_boolean (ENCRYPTSELF_KEY)) { skey = SEAHORSE_OBJECT (seahorse_context_get_default_key (SCTX_APP ())); if (SEAHORSE_IS_PGP_KEY (skey)) recipkeys = g_list_append (recipkeys, skey); } /* Make keys into the right format for GPGME */ recips = keylist_to_keys (recipkeys); g_list_free (recipkeys); /* Do the encryption */ if (signkey) { gpgme_signers_add (pop->gctx, seahorse_gpgme_key_get_private (SEAHORSE_GPGME_KEY (signkey))); gerr = gpgme_op_encrypt_sign_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher); } else { gerr = gpgme_op_encrypt_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher); } free_keys (recips); /* Frees cipher */ ret = process_crypto_result (pop, gerr, cipher, crypttext, cryptlength, error); g_object_unref (pop); gpgme_data_release (plain); return ret; }
static void freeKeymap() { free_keys(kmap_trie_root, NULL, 1); free_keys(kmap_trie_root, NULL, 0); kmap_trie_root = NULL; }
/* * This is the readline completion handler */ char * key_generator (const char * str, int state) { static int index, len, has_param; static uint64_t rlfp; struct key * kw; int i; struct handler *h; vector v = NULL; if (!state) { index = 0; has_param = 0; rlfp = 0; len = strlen(str); int r = get_cmdvec(rl_line_buffer, &v); /* * If a word completion is in progess, we don't want * to take an exact keyword match in the fingerprint. * For ex "show map[tab]" would validate "map" and discard * "maps" as a valid candidate. */ if (v && len) vector_del_slot(v, VECTOR_SIZE(v) - 1); /* * Clean up the mess if we dropped the last slot of a 1-slot * vector */ if (v && !VECTOR_SIZE(v)) { vector_free(v); v = NULL; } /* * If last keyword takes a param, don't even try to guess */ if (r == EINVAL) { has_param = 1; return (strdup("(value)")); } /* * Compute a command fingerprint to find out possible completions. * Once done, the vector is useless. Free it. */ if (v) { rlfp = fingerprint(v); free_keys(v); } } /* * No more completions for parameter placeholder. * Brave souls might try to add parameter completion by walking paths and * multipaths vectors. */ if (has_param) return ((char *)NULL); /* * Loop through keywords for completion candidates */ vector_foreach_slot_after (keys, kw, index) { if (!strncmp(kw->str, str, len)) { /* * Discard keywords already in the command line */ if (key_match_fingerprint(kw, rlfp)) { struct key * curkw = find_key(str); if (!curkw || (curkw != kw)) continue; } /* * Discard keywords making syntax errors. * * nfp is the candidate fingerprint we try to * validate against all known command fingerprints. */ uint64_t nfp = rlfp | kw->code; vector_foreach_slot(handlers, h, i) { if (!rlfp || ((h->fingerprint & nfp) == nfp)) { /* * At least one full command is * possible with this keyword : * Consider it validated */ index++; return (strdup(kw->str)); } } } } /* * No more candidates */ return ((char *)NULL); }
void cli_exit(void) { free_handlers(); free_keys(keys); keys = NULL; }