/* Expand mail special characters: * # the previous file * & the current mbox * +file the file named in the folder directory (set folder=foo) * Note 1) The followig notations are left intact, since they are * handled by mu_mailbox_create_default: * % system mailbox * %user system mailbox of the user * Note 2) Allocates memory */ char * mail_expand_name (const char *name) { switch (name[0]) { case '#': if (!prev_name) { util_error (_("No previous file")); return NULL; } else name = xstrdup (prev_name); break; case '&': name = getenv ("MBOX"); if (!name) util_error (_("MBOX environment variable not set")); else name = xstrdup (name); break; case '+': name = util_folder_path (name); break; default: name = xstrdup (name); break; } return (char*) name; }
int eapi_load(easyflash_cart_t * cart, const char* filename) { unsigned char buf[EAPI_SIZE + 2]; unsigned int load_addr = 0; util_message("Loading EAPI '%s'...", filename); if (util_prgfile_load(filename, buf, EAPI_SIZE, 0, &load_addr) < 0) { return -1; } if (load_addr != EAPI_FILE_LOAD_ADDR) { util_error("load address $%04x, expecting $%04x!", load_addr, EAPI_FILE_LOAD_ADDR); return -1; } if (check_header(buf) != 0) { util_error("file '%s' doesn't have EAPI header!", filename); return -1; } memcpy(eapi_data, buf, EAPI_SIZE); cart->main_flash_state |= MAIN_STATE_HAVE_EAPI; return 0; }
int do_delete_key(sc_card_t *card, u8 in_key_id) { sc_path_t path; int r = SC_SUCCESS; /* Currently, only Gnuk supports deleting keys */ if (card->type != SC_CARD_TYPE_OPENPGP_GNUK) { util_error("only Gnuk supports deleting keys. General OpenPGP doesn't"); return SC_ERROR_NOT_SUPPORTED; } if (in_key_id < 1 || (in_key_id > 3 && in_key_id != 'a')) { util_error("invalid key id %d", in_key_id); return SC_ERROR_INVALID_ARGUMENTS; } if (in_key_id == 1 || in_key_id == 'a') { sc_format_path("B601", &path); r |= sc_delete_file(card, &path); } if (in_key_id == 2 || in_key_id == 'a') { sc_format_path("B801", &path); r |= sc_delete_file(card, &path); } if (in_key_id == 3 || in_key_id == 'a') { sc_format_path("A401", &path); r |= sc_delete_file(card, &path); } return r; }
int do_verify(sc_card_t *card, char *type, const char *in_pin) { struct sc_pin_cmd_data data; int tries_left; int r; if (!type || !in_pin) return SC_ERROR_INVALID_ARGUMENTS; if (strncasecmp("CHV", type, 3) != 0) { util_error("invalid PIN type. Please use CHV1, CHV2 or CHV3"); return SC_ERROR_INVALID_ARGUMENTS; } if (type[3] < '1' || type[3] > '3' || type[4] != '\0') { util_error("invalid PIN reference. Please use CHV1, CHV2 or CHV3"); return SC_ERROR_INVALID_PIN_REFERENCE; } memset(&data, 0, sizeof(struct sc_pin_cmd_data)); data.cmd = SC_PIN_CMD_VERIFY; data.pin_type = SC_AC_CHV; data.pin_reference = type[3] - '0'; data.pin1.data = (unsigned char *) in_pin; data.pin1.len = (int)strlen(in_pin); r = sc_pin_cmd(card, &data, &tries_left); return r; }
static int do_dump_do(sc_card_t *card, unsigned int tag) { int r; size_t length; unsigned char buffer[254]; // Private DO are specified up to 254 bytes memset(buffer, '\0', sizeof(buffer)); if (tag < 0x101 || tag > 0x104) { util_error("illegal DO identifier %04X", tag); return SC_ERROR_INVALID_ARGUMENTS; } r = sc_get_data(card, tag, buffer, sizeof(buffer)); if (r < 0) { util_error("failed to get data object DO %04X: %s", tag, sc_strerror(r)); if (SC_ERROR_SECURITY_STATUS_NOT_SATISFIED == r) { util_error("make sure the 'verify' and 'pin' parameters are correct"); } return r; } length = (size_t) r; /* r is guaranteed to be non-negative */ if (opt_raw) { int tmp; FILE *fp; #ifndef _WIN32 tmp = dup(fileno(stdout)); #else tmp = _dup(_fileno(stdout)); #endif if (tmp < 0) return EXIT_FAILURE; fp = freopen(NULL, "wb", stdout); if (fp) { r = (int) fwrite(buffer, sizeof(char), length, fp); } #ifndef _WIN32 dup2(tmp, fileno(stdout)); #else _dup2(tmp, _fileno(stdout)); #endif clearerr(stdout); close(tmp); if (length != (size_t) r) /* fail on write errors */ return EXIT_FAILURE; } else { util_hex_dump_asc(stdout, buffer, length, -1); } return EXIT_SUCCESS; }
static int do_info(sc_card_t *card, const struct ef_name_map *map) { int i; u8 buf[2048]; for (i = 0; map[i].ef != NULL; i++) { sc_path_t path; sc_file_t *file; size_t count; int r; sc_format_path(map[i].ef, &path); r = sc_select_file(card, &path, &file); if (r) { util_error("failed to select EF %s: %s", map[i].ef, sc_strerror(r)); return EXIT_FAILURE; } count = file->size; if (!count) continue; if (count > sizeof(buf) - 1) { util_error("too small buffer to read the OpenPGP map"); return EXIT_FAILURE; } r = sc_read_binary(card, 0, buf, count, 0); if (r < 0) { util_error("failed to read %s: %s", map[i].ef, sc_strerror(r)); return EXIT_FAILURE; } if (r != (signed) count || (size_t) r < map[i].offset + map[i].length) { util_error("%s: expecting %"SC_FORMAT_LEN_SIZE_T"d bytes, got only %d", map[i].ef, count, r); return EXIT_FAILURE; } if (map[i].offset > 0) { memmove(buf, buf + map[i].offset, map[i].length); count -= map[i].offset; } if (map[i].length > 0 && count > map[i].length) count = map[i].length; if (map[i].type == TYPE_STRING) buf[count] = '\0'; display_data(&map[i], buf, count); } return EXIT_SUCCESS; }
int mail_previous (int argc, char **argv) { size_t n; mu_message_t msg; if (argc < 2) { int rc = 1; n = get_cursor (); if (n) while (--n > 0) { if (util_isdeleted (n)) continue; rc = util_get_message (mbox, n, &msg); if (rc == 0) break; } if (rc) { util_error (_("No applicable message")); return 1; } } else { msgset_t *list = NULL; int rc = msgset_parse (argc, argv, MSG_NODELETED|MSG_SILENT, &list); if (!rc) { n = list->msg_part[0]; msgset_free (list); if (util_get_message (mbox, n, &msg)) return 1; } else { util_error (_("No applicable message")); return 1; } } set_cursor (n); util_do_command ("print"); return 0; }
static void alias_print (char *name) { if (!name) { mu_iterator_t itr; if (!aliases) return; mu_assoc_get_iterator (aliases, &itr); for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) { const char *name; alias_t al; if (mu_iterator_current_kv (itr, (const void **)&name, (void**)&al)) continue; alias_print_group (name, al); } } else { alias_t al; al = alias_lookup (name); if (!al) { util_error (_("\"%s\": not a group"), name); return; } alias_print_group (name, al); } }
/** * Delete key, for OpenPGP card. * This function is not complete and is reserved for future version (> 2) of OpenPGP card. **/ int delete_key_openpgp(sc_card_t *card, u8 in_key_id) { char *del_fingerprint = "00:DA:00:C6:14:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"; char *del_creationtime = "00:DA:00:CD:04:00:00:00:00"; /* We need to replace the 4th byte later */ char *apdustring = NULL; u8 buf[SC_MAX_APDU_BUFFER_SIZE]; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_apdu_t apdu; size_t len0; int i; int r = SC_SUCCESS; for (i = 0; i < 2; i++) { if (i == 0) /* Reset fingerprint */ apdustring = del_fingerprint; else /* Reset creation time */ apdustring = del_creationtime; /* Convert the string to binary array */ len0 = sizeof(buf); sc_hex_to_bin(apdustring, buf, &len0); /* Replace DO tag, subject to key ID */ buf[3] = buf[3] + in_key_id; /* Build APDU from binary array */ r = sc_bytes2apdu(card->ctx, buf, len0, &apdu); if (r) { util_error("failed to build APDU: %s", sc_strerror(r)); return r; } apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); /* Send APDU to card */ r = sc_transmit_apdu(card, &apdu); if (r) { util_error("transmitting APDU failed: %s", sc_strerror(r)); return r; } } /* TODO: Rewrite Extended Header List. * Not support by OpenGPG v2 yet */ return r; }
int lst_save_begin(const char *filename) { if (fd_o != NULL) { util_error("already open!", filename); return -1; } fd_o = fopen(filename, MODE_WRITE_TEXT); if (fd_o == NULL) { util_error("problems creating file '%s'!", filename); return -1; } fprintf(fd_o, "# ndefpack v" PACKAGE_VERSION " LST file\n" "#\n" "# Format: (INITEM)\n" "# FILE[" LST_SEP_CHAR "NAME[" LST_SEP_CHAR "TYPE]]\n" "# FILE - CRT or PRG file:\n" "# CRT\n" "# A cartridge .crt file.\n" "# The following cart types are supported:\n" "# * generic (CRT ID 0; 8k, 16k, Ultimax)\n" "# * Ocean (CRT ID 5)\n" "# * EasyFlash xbank (CRT ID 33)\n" "# PRG\n" "# Normal .prg file.\n" "# NAME - name on EasyFS, shown by loader (cleaned up FILE if omitted)\n" "# TYPE - type of entry; one of the following:\n" "# t - normal (default if omitted)\n" "# h - hidden, not shown by loader\n" "# a - force 64k alignment (only valid for xbank carts)\n" "# e - EAPI; file is 2+768 B, load address $C000 and \"eapi\" signature\n" "# o - Ocean boot code; file is <= 2+1256 B, load address >= $FB18\n" "# O - Ocean loader; file is 2+8192 B, load address = $A000\n" "# n - normal boot code; file is <= 2+1256 B, load address >= $FB18\n" "# N - normal loader; file is 2+8192 B, load address = $8000\n" "#\n" "\n" ); return lst_check_write_error(); }
/* ** This routine prints a custom error message rather than one of the standard ** ones from the BIL error message table. It takes the message string as ** an argument and then passes it off to abil_loadmsg() to be output. ** ** This routine assumes the custom error message has been I18Nized beforehand. */ int abil_print_custom_load_err(STRING errmsgstr) { if (!abil_loadmsg_err_printed()) { util_error(abil_loadmsg(errmsgstr)); abil_loadmsg_set_err_printed(TRUE); } return 0; }
static int lst_check_write_error(void) { if (ferror(fd_o)) { util_error("problems writing to file!"); fclose(fd_o); fd_o = NULL; return -1; } return 0; }
void collection_remove(struct collection *col, void *element) { int i; for(i=0; i<col->capacity; i++) { if(col->list[i] == element) { col->list[i] = NULL; return; } } util_error("collection_remove: element %p not present in collection %p (cap %d)", element, col, col->capacity); }
/* ** This routine prints one of the standard BIL load error messages by ** looking it up in the error message table, fetching the right string ** from the message catalog, and passing it to abil_loadmsg() to be output. ** ** All the I18N has to happen here (before abil_loadmsg() is called)... */ int abil_print_load_err(int errmsg) { static BOOL errmsg_tbl_init = FALSE; char msg[1024]; int msgLen = 0; *msg = 0; *msg = 0; /* ** Load up the error message table if this is the first time we've ** needed to output an error message. */ if(errmsg_tbl_init == FALSE) { abil_load_errmsg_table(); errmsg_tbl_init = TRUE; } if ((errmsg == ERR_NOT_IMPL) && (!util_be_verbose())) { return 0; } if (!abil_loadmsg_err_printed()) { if(Errormsg[errmsg].msg_id < 0) { strcat(msg, catgets(ABIL_MESSAGE_CATD, ABIL_MESSAGE_SET, 33, "syntax error")); } else { strcat(msg, catgets(ABIL_MESSAGE_CATD, ABIL_MESSAGE_SET, Errormsg[errmsg].msg_id, Errormsg[errmsg].def_str)); } if ((msgLen = strlen(msg)) > 0) { if (msg[msgLen-1] == '\n') { msg[msgLen-1] = 0; } } util_error(abil_loadmsg(msg)); abil_loadmsg_set_err_printed(TRUE); } return 0; }
int lst_load(easyflash_cart_t * cart, const char *filename) { FILE *fd = NULL; char buf[BUFSIZE]; fd = fopen(filename, MODE_READ_TEXT); if (fd == NULL) { util_error("problems opening file '%s'!", filename); return -1; } do { buf[0] = 0; if (fgets(buf, BUFSIZE - 1, fd)) { char *p; size_t len = strlen(buf); if (len == 0) { break; } /* remove newline */ buf[len - 1] = 0; /* remove comments */ if ((p = strchr(buf, '#'))) { *p = 0; } if (*buf != 0) { if (lst_parse_entry(cart, buf) < 0) { goto fail; } } } } while (!feof(fd)); fclose(fd); return main_flash_place_entries(cart); fail: fclose(fd); return -1; }
int lst_parse_entry(easyflash_cart_t * cart, const char *buf_in) { int res = -1; char *filename = NULL; char *menuname = NULL; char *typestr = NULL; lst_type_t type = LST_TYPE_NORMAL; char *buf = strdup(buf_in); filename = strtok(buf, LST_SEP_CHAR "\r\n"); menuname = strtok(NULL, LST_SEP_CHAR "\r\n"); if (menuname != NULL) { typestr = strtok(NULL, "\r\n"); if ((typestr != NULL) && (typestr[1] != 0)) { util_error("too long type!"); goto fail; } } if (typestr != NULL) { for (type = LST_TYPE_NORMAL; type < LST_TYPE_NUM; ++type) { if (lst_type_char[type] == typestr[0]) { break; } } if (type == LST_TYPE_NUM) { util_error("invalid type '%c'!", typestr[0]); goto fail; } } switch (type) { case LST_TYPE_NORMAL: case LST_TYPE_HIDDEN: case LST_TYPE_ALIGN64K: res = main_flash_add_file(cart, filename, menuname, type == LST_TYPE_HIDDEN, type == LST_TYPE_ALIGN64K, 0); break; case LST_TYPE_EAPI: res = eapi_load(cart, filename) || eapi_inject(cart, 1); break; case LST_TYPE_BOOTO: case LST_TYPE_BOOTN: res = boot_load(cart, filename, type == LST_TYPE_BOOTO); break; case LST_TYPE_LOADERO: case LST_TYPE_LOADERN: res = loader_load(cart, filename, type == LST_TYPE_LOADERO); break; default: break; } free(buf); return res; fail: free(buf); return -1; }
static int decode_options(int argc, char **argv) { int c; char *endptr; unsigned long val; while ((c = getopt_long(argc, argv,"r:x:CUG:KEht:wvVd:", options, (int *) 0)) != EOF) { switch (c) { case 'r': opt_reader = optarg; break; case 'x': if (exec_program) free(exec_program); exec_program = strdup(optarg); break; case OPT_RAW: opt_raw = 1; break; case OPT_PRETTY: opt_raw = 0; break; case OPT_VERIFY: opt_verify++; if (verifytype) free(verifytype); verifytype = strdup(optarg); actions++; break; case OPT_PIN: opt_pin++; util_get_pin(optarg, &pin); break; case 'C': opt_cardinfo++; actions++; break; case 'U': opt_userinfo++; actions++; break; case 'K': opt_keyinfo++; actions++; break; case 'G': opt_genkey++; key_id = optarg[0] - '0'; actions++; break; case 't': if (keytype) free(keytype); keytype = strdup(optarg); break; case 'h': util_print_usage_and_die(app_name, options, option_help, NULL); break; case 'w': opt_wait = 1; break; case 'v': verbose++; break; case 'V': show_version(); exit(EXIT_SUCCESS); break; case 'E': opt_erase++; actions++; break; case OPT_DELKEY: opt_delkey++; if (strcmp(optarg, "all") != 0) /* Arg string is not 'all' */ key_id = optarg[0] - '0'; else /* Arg string is 'all' */ key_id = 'a'; actions++; break; case 'd': endptr = NULL; val = strtoul(optarg, &endptr, 16); if (endptr == NULL || endptr == optarg || *endptr != '\0') { util_error("Unable to parse DO identifier"); exit(EXIT_FAILURE); } if (opt_dump_do < sizeof(do_dump_idx) / sizeof(*do_dump_idx)) { do_dump_idx[opt_dump_do] = (unsigned int) (val | 0x100); opt_dump_do++; } actions++; break; default: util_print_usage_and_die(app_name, options, option_help, NULL); } } return optind; }
/* ** determine which builtin action and write the appropriate code. */ static int write_builtin_action( GenCodeInfo genCodeInfo, ABObj action, ABObj toObj, AB_BUILTIN_ACTION builtin_action, STRING actionTKResource, /* in toolkit */ STRING actionResource /* in source code */ ) { #define IS(type) (obj_get_func_type(action) ==(type)) #define SVAL(action) ((STRING)obj_get_arg_string(action)) #define IVAL(action) ((int)obj_get_arg_int(action)) File codeFile = genCodeInfo->code_file; int return_value = 0; if (!codeFile || !action || !toObj || !builtin_action) return return_value; switch (builtin_action) { case AB_STDACT_ENABLE: abio_print_line(codeFile, NULL); abio_print_line(codeFile, "XtSetSensitive(%s, True);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_STDACT_DISABLE: abio_print_line(codeFile, NULL); abio_print_line(codeFile, "XtSetSensitive(%s, False);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_STDACT_SHOW: switch((obj_get_root(toObj))->type) { case AB_TYPE_BASE_WINDOW: abio_print_line(codeFile, "XtPopup(%s, XtGrabNone);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_TYPE_DIALOG: case AB_TYPE_FILE_CHOOSER: default: abio_print_line(codeFile, "XtManageChild(%s);", abmfP_get_c_name(genCodeInfo, toObj)); break; } break; case AB_STDACT_HIDE: switch((obj_get_root(toObj))->type) { case AB_TYPE_BASE_WINDOW: abio_print_line(codeFile, "XtPopdown(%s);", abmfP_get_c_name(genCodeInfo, toObj)); break; case AB_TYPE_DIALOG: case AB_TYPE_FILE_CHOOSER: default: abio_print_line(codeFile, "XtUnmanageChild(%s);", abmfP_get_c_name(genCodeInfo, toObj)); break; } break; case AB_STDACT_SET_LABEL: /* check toObj for root */ if ( obj_get_label_type(obj_get_root(toObj)) == AB_LABEL_GLYPH) { abio_printf(codeFile, "%s(%s, ", abmfP_lib_set_label_from_image_file->name, abmfP_get_c_name(genCodeInfo, toObj)); abio_put_string(codeFile, SVAL(action)); abio_puts(codeFile, ");\n"); } else { assert(actionTKResource != NULL); printf_setval(genCodeInfo, toObj, actionTKResource, SVAL(action), NULL); } break; case AB_STDACT_SET_VALUE: printf_setval(genCodeInfo, toObj, actionTKResource, IVAL(action), NULL); break; case AB_STDACT_SET_TEXT: printf_setval(genCodeInfo, toObj, actionTKResource, SVAL(action), NULL); break; /* case AB_STDACT_SHOW_HELP: */ /* abio_print_line(codeFile, NULL); */ /* abio_print_line(codeFile, */ /* "XtCallCallbacks(%s,XmNhelpCallback,(XtPointer)NULL);", */ /* abmfP_get_c_name(genCodeInfo, toObj)); */ /* break; */ default: { static char msg[255]; if (obj_get_name(action) != NULL) { char *action_name = obj_get_name(action); sprintf(msg, catgets(Dtb_project_catd, 1, 76, "Unknown action name, %s"), action_name); } else { int action_type = obj_get_func_builtin(action); sprintf(msg, catgets(Dtb_project_catd, 1, 77, "Unknown action type, %d"), action_type); } util_error(msg); return_value = ERR_INTERNAL; /* * return msg; Just print message and go on - JT */ } break; } /* switch func.value.builtin */ return return_value; #undef IS #undef SVAL #undef IVAL }
int main(int argc, char **argv) { sc_context_t *ctx = NULL; sc_context_param_t ctx_param; sc_card_t *card = NULL; int r; int argind = 0; int exit_status = EXIT_SUCCESS; /* decode options */ argind = decode_options(argc, argv); /* connect to the card */ memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { util_fatal("failed to establish context: %s", sc_strerror(r)); return EXIT_FAILURE; } r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r) { util_fatal("failed to connect to card: %s", sc_strerror(r)); return EXIT_FAILURE; } /* check card type */ if ((card->type != SC_CARD_TYPE_OPENPGP_BASE) && (card->type != SC_CARD_TYPE_OPENPGP_V1) && (card->type != SC_CARD_TYPE_OPENPGP_V2) && (card->type != SC_CARD_TYPE_OPENPGP_V3) && (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) { util_error("card type %X: not an OpenPGP card", card->type); exit_status = EXIT_FAILURE; goto out; } /* fail on too many arguments */ if (argind > argc) util_print_usage_and_die(app_name, options, option_help, NULL); /* set default action */ if (!actions) opt_userinfo = 1; if (opt_cardinfo) exit_status |= do_info(card, card_data); if (opt_userinfo) exit_status |= do_info(card, user_data); if (opt_keyinfo) exit_status |= do_info(card, key_data); if (opt_verify && opt_pin) { exit_status |= do_verify(card, verifytype, pin); } if (opt_dump_do) { size_t n; for (n = 0; n < opt_dump_do; n++) { exit_status |= do_dump_do(card, do_dump_idx[n]); } } if (opt_genkey) exit_status |= do_genkey(card, key_id, keytype); if (exec_program) { char *const largv[] = {exec_program, NULL}; sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); #ifndef _WIN32 execv(exec_program, largv); #else _execv(exec_program, (const char * const*)largv); #endif /* we should not get here */ perror("execv()"); exit(EXIT_FAILURE); } if (opt_delkey) exit_status |= do_delete_key(card, key_id); if (opt_erase) exit_status |= do_erase(card); out: sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); exit(exit_status); }
int main(int argc, char **argv) { sc_context_t *ctx = NULL; sc_context_param_t ctx_param; sc_card_t *card = NULL; int r; int argind = 0; int exit_status = EXIT_SUCCESS; /* decode options */ argind = decode_options(argc, argv); /* connect to the card */ memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { util_fatal("failed to establish context: %s\n", sc_strerror(r)); return EXIT_FAILURE; } if (verbose > 1) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r) { util_fatal("failed to connect to card: %s\n", sc_strerror(r)); return EXIT_FAILURE; } /* check card type */ if ((card->type != SC_CARD_TYPE_OPENPGP_V1) && (card->type != SC_CARD_TYPE_OPENPGP_V2)) { util_error("not an OpenPGP card"); exit_status = EXIT_FAILURE; goto out; } /* fail on too many arguments */ if (argind > argc) util_print_usage_and_die(app_name, options, option_help, NULL); /* set default action */ if (!actions) opt_userinfo = 1; if (opt_userinfo) exit_status |= do_userinfo(card); if (opt_verify && opt_pin) { exit_status |= do_verify(card, verifytype, pin); } if (opt_dump_do) { exit_status |= do_dump_do(card, 0x0100 + do_dump_idx); } if (opt_genkey) exit_status |= do_genkey(card, key_id, key_len); if (exec_program) { char *const largv[] = {exec_program, NULL}; sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); execv(exec_program, largv); /* we should not get here */ perror("execv()"); exit(EXIT_FAILURE); } out: sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); exit(exit_status); }
int mail_file (int argc, char **argv) { if (argc == 1) { mail_summary (0, NULL); } else if (argc == 2) { /* switch folders */ char *pname; mu_url_t url; mu_mailbox_t newbox = NULL; char *name = mail_expand_name (argv[1]); int status; if (!name) return 1; if ((status = mu_mailbox_create_default (&newbox, name)) != 0 || (status = mu_mailbox_open (newbox, MU_STREAM_RDWR)) != 0) { mu_mailbox_destroy (&newbox); util_error(_("Cannot open mailbox %s: %s"), name, mu_strerror (status)); free (name); return 1; } free (name); /* won't need it any more */ page_invalidate (1); /* Invalidate current page map */ mu_mailbox_get_url (mbox, &url); pname = strdup (mu_url_to_string (url)); if (mail_mbox_close ()) { if (pname) free (pname); mu_mailbox_close (newbox); mu_mailbox_destroy (&newbox); return 1; } if (prev_name) free (prev_name); prev_name = pname; mbox = newbox; mu_mailbox_messages_count (mbox, &total); set_cursor (1); if (mailvar_get (NULL, "header", mailvar_type_boolean, 0) == 0) { util_do_command ("summary"); util_do_command ("headers"); } return 0; } else { util_error(_("%s takes only one argument"), argv[0]); } return 1; }
int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype) { int r; sc_cardctl_openpgp_keygen_info_t key_info; u8 fingerprints[60]; sc_path_t path; sc_file_t *file; /* validate in_key_id */ if (in_key_id < 1 || in_key_id > 3) { util_error("unknown key ID %d", in_key_id); return SC_ERROR_INVALID_ARGUMENTS; } /* fall back to RSA 2048 if keytype is not given */ if (!keytype) keytype = "RSA2048"; memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); /* generate key depending on keytype passed */ if (strncasecmp("RSA", keytype, strlen("RSA")) == 0) { size_t keylen = 2048; /* default length for RSA keys */ const char *keylen_ptr = keytype + strlen("RSA"); /* try to get key length from keytype, e.g. "rsa3072" -> 3072 */ if (strlen(keylen_ptr) > 0) { if (strspn(keylen_ptr, "0123456789") == strlen(keylen_ptr) && atol(keylen_ptr) >= 1024 && atol(keylen_ptr) <= 4096) { keylen = atol(keylen_ptr); } else { util_error("illegal key type: %s", keytype); return EXIT_FAILURE; } } /* set key_info */ key_info.key_id = in_key_id; key_info.algorithm = SC_OPENPGP_KEYALGO_RSA; key_info.u.rsa.modulus_len = keylen; key_info.u.rsa.modulus = malloc(BYTES4BITS(keylen)); r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); free(key_info.u.rsa.modulus); if (r < 0) { util_error("failed to generate key: %s", sc_strerror(r)); return EXIT_FAILURE; } } else { //TODO: deal with EC keys util_error("Generating non-RSA keys is not yet implemented"); return EXIT_FAILURE; } sc_format_path("006E007300C5", &path); r = sc_select_file(card, &path, &file); if (r < 0) { util_error("failed to retrieve fingerprints: %s", sc_strerror(r)); return EXIT_FAILURE; } r = sc_read_binary(card, 0, fingerprints, 60, 0); if (r < 0) { util_error("failed to retrieve fingerprints: %s", sc_strerror(r)); return EXIT_FAILURE; } printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(in_key_id - 1), 20)); return EXIT_SUCCESS; }