/** * The Modhex encoding is described in Yubikey manual, as a start point You * can read this: @link https://www.yubico.com/modhex-calculator/ . * @param p2Modhex what to encode. * @return input Modhex encoded. * */ const string YubikoOtpKeyConfig::hex2Modhex(const string& p2Modhex) { const unsigned long mySz = p2Modhex.size(); const unsigned long mySz2 = mySz / 2; vector<uint8_t> myBytes(mySz2, uint8_t(0)); yubikey_hex_decode(reinterpret_cast<char*>(&myBytes[0]), p2Modhex.c_str(), mySz); string myPubId(mySz + 1, '\0'); yubikey_modhex_encode(&myPubId[0], reinterpret_cast<char*>(&myBytes[0]), mySz2); myPubId.resize(mySz); return myPubId; }
int YubiKeyUtil::hexModhexEncode(char *result, size_t *resultLen, const unsigned char *str, size_t strLen, bool modhex) { *resultLen = strLen * 2; if (modhex) { yubikey_modhex_encode((char *)result, (char *)str, strLen); return 1; } else { yubikey_hex_encode((char *)result, (char *)str, strLen); return 1; } return 0; }
static void modhex_test1 (void) { char buf[1024]; char buf2[1024]; yubikey_modhex_encode (buf, "test", 4); printf ("modhex-encode(\"test\") = %s\n", buf); assert (strcmp (buf, "ifhgieif") == 0); printf ("Modhex-1.1 success\n"); printf ("modhex-decode(\"%s\") = ", buf); yubikey_modhex_decode (buf2, buf, sizeof (buf2)); printf ("%.*s\n", 4, buf2); assert (memcmp (buf2, "test", 4) == 0); printf ("Modhex-1.2 success\n"); }
int _ykp_json_export_cfg(const YKP_CONFIG *cfg, char *json, size_t len) { json_object *jobj = json_object_new_object(); json_object *yprod_json = json_object_new_object(); json_object *options_json = json_object_new_object(); if(cfg) { YK_CONFIG ycfg = cfg->ykcore_config; int mode = MODE_OTP_YUBICO; struct map_st *p; json_object *target_config = NULL; json_object *prot_obj = NULL; int protection = ykp_get_acccode_type(cfg); if((ycfg.tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP){ if((ycfg.cfgFlags & CFGFLAG_CHAL_HMAC) == CFGFLAG_CHAL_HMAC) { mode = MODE_CHAL_HMAC; } else if((ycfg.cfgFlags & CFGFLAG_CHAL_YUBICO) == CFGFLAG_CHAL_YUBICO) { mode = MODE_CHAL_YUBICO; } else { mode = MODE_OATH_HOTP; } } else if((ycfg.cfgFlags & CFGFLAG_STATIC_TICKET) == CFGFLAG_STATIC_TICKET) { mode = MODE_STATIC_TICKET; } for(p = _modes_map; p->flag; p++) { if(p->flag == mode) { json_object *jmode = json_object_new_string(p->json_text); json_object_object_add(yprod_json, "mode", jmode); break; } } if(cfg->command == SLOT_CONFIG) { target_config = json_object_new_int(1); } else if(cfg->command == SLOT_CONFIG2) { target_config = json_object_new_int(2); } if(target_config) { json_object_object_add(yprod_json, "targetConfig", target_config); } if(protection == YKP_ACCCODE_NONE) { prot_obj = json_object_new_string("none"); } else if(protection == YKP_ACCCODE_RANDOM) { prot_obj = json_object_new_string("random"); } else if(protection == YKP_ACCCODE_SERIAL) { prot_obj = json_object_new_string("id"); } if(prot_obj) { json_object_object_add(yprod_json, "protection", prot_obj); } json_object_object_add(jobj, "yubiProdConfig", yprod_json); json_object_object_add(yprod_json, "options", options_json); if(ycfg.fixedSize != 0 && mode != MODE_STATIC_TICKET) { json_object *jPrefix; char prefix[5] = {0}; json_object *scope; if(mode == MODE_OTP_YUBICO && ycfg.fixed[0] == 0x00 && ycfg.fixed[1] == 0x00) { scope = json_object_new_string("yubiCloud"); } else { scope = json_object_new_string("privatePrefix"); } json_object_object_add(yprod_json, "scope", scope); yubikey_modhex_encode(prefix, (const char*)ycfg.fixed, 2); if(mode == MODE_OATH_HOTP) { int flag = ycfg.cfgFlags & CFGFLAG_OATH_FIXED_MODHEX; json_object *fixed_modhex = json_object_new_boolean( flag == CFGFLAG_OATH_FIXED_MODHEX ? 1 : 0); json_object_object_add(options_json, "fixedModhex", fixed_modhex); if(flag == 0) { yubikey_hex_encode(prefix, (const char*)ycfg.fixed, 2); } else if(flag == CFGFLAG_OATH_FIXED_MODHEX1) { yubikey_hex_encode(prefix + 2, (const char*)ycfg.fixed + 1, 1); } } jPrefix = json_object_new_string(prefix); json_object_object_add(yprod_json, "prefix", jPrefix); } else if(mode != MODE_STATIC_TICKET) { json_object *scope = json_object_new_string("noPublicId"); json_object_object_add(yprod_json, "scope", scope); } if(mode == MODE_OATH_HOTP) { json_object *oathDigits; json_object *randomSeed; if((ycfg.cfgFlags & CFGFLAG_OATH_HOTP8) == CFGFLAG_OATH_HOTP8) { oathDigits = json_object_new_int(8); } else { oathDigits = json_object_new_int(6); } json_object_object_add(options_json, "oathDigits", oathDigits); if((ycfg.uid[5] == 0x01 || ycfg.uid[5] == 0x00) && ycfg.uid[4] == 0x00) { json_object *fixedSeedvalue = json_object_new_int(ycfg.uid[5] << 4); json_object_object_add(options_json, "fixedSeedvalue", fixedSeedvalue); randomSeed = json_object_new_boolean(0); } else { randomSeed = json_object_new_boolean(1); } json_object_object_add(options_json, "randomSeed", randomSeed); } for(p = _ticket_flags_map; p->flag; p++) { if(!p->json_text) { continue; } if(p->mode && (mode & p->mode) == mode) { int set = (ycfg.tktFlags & p->flag) == p->flag; json_object *jsetting = json_object_new_boolean(set); json_object_object_add(options_json, p->json_text, jsetting); } } for(p = _config_flags_map; p->flag; p++) { if(!p->json_text) { continue; } if(p->mode && (mode & p->mode) == mode) { int set = (ycfg.cfgFlags & p->flag) == p->flag; json_object *jsetting = json_object_new_boolean(set); json_object_object_add(options_json, p->json_text, jsetting); } } for(p = _extended_flags_map; p->flag; p++) { if(!p->json_text) { continue; } if(p->mode && (mode & p->mode) == mode) { int set = (ycfg.extFlags & p->flag) == p->flag; json_object *jsetting = json_object_new_boolean(set); json_object_object_add(options_json, p->json_text, jsetting); } } } #ifdef HAVE_JSON_OBJECT_TO_JSON_STRING_EXT strncpy(json, json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PRETTY), len); #else strncpy(json, json_object_to_json_string(jobj), len); #endif /* free the root object, will free all children */ json_object_put(jobj); return strlen(json); }
int main(int argc, char **argv) { YK_KEY *yk = 0; bool error = true; int exit_code = 0; /* Options */ bool serial_dec = false; bool serial_modhex = false; bool serial_hex = false; bool version = false; bool touch_level = false; bool pgm_seq = false; bool slot1 = false; bool slot2 = false; bool vid = false; bool pid = false; bool quiet = false; yk_errno = 0; if (! parse_args(argc, argv, &serial_dec, &serial_modhex, &serial_hex, &version, &touch_level, &pgm_seq, &quiet, &slot1, &slot2, &vid, &pid, &exit_code)) exit(exit_code); if (!yk_init()) { exit_code = 1; goto err; } if (!(yk = yk_open_first_key())) { exit_code = 1; goto err; } if(serial_dec || serial_modhex || serial_hex) { unsigned int serial; int ret = yk_get_serial(yk, 1, 0, &serial); if(!ret) { exit_code = 1; goto err; } if(serial_dec) { if(!quiet) printf("serial: "); printf("%d\n", serial); } if(serial_modhex || serial_hex) { char buf[64]; char hex_serial[64]; char modhex_serial[64]; char *ptr = buf; int chars = snprintf(buf + 1, 63, "%x", serial); if(chars % 2 == 1) { buf[0] = '0'; } else { ptr += 1; } if(serial_hex) { if(!quiet) printf("serial_hex: "); printf("%s\n", ptr); } if(serial_modhex) { yubikey_hex_decode(hex_serial, ptr, strlen(ptr)); yubikey_modhex_encode(modhex_serial, hex_serial, strlen(hex_serial)); if(!quiet) printf("serial_modhex: "); printf("%s\n", modhex_serial); } } } if(version || touch_level || pgm_seq || slot1 || slot2) { YK_STATUS *st = ykds_alloc(); if(!yk_get_status(yk, st)) { ykds_free(st); exit_code = 1; goto err; } if(version) { if(!quiet) printf("version: "); printf("%d.%d.%d\n", ykds_version_major(st), ykds_version_minor(st), ykds_version_build(st)); } if(touch_level) { if(!quiet) printf("touch_level: "); printf("%d\n", ykds_touch_level(st)); } if(pgm_seq) { if(!quiet) printf("programming_sequence: "); printf("%d\n", ykds_pgm_seq(st)); } if(slot1) { if(!quiet) printf("slot1_status: "); printf("%d\n", (ykds_touch_level(st) & CONFIG1_VALID) == CONFIG1_VALID); } if(slot2) { if(!quiet) printf("slot2_status: "); printf("%d\n", (ykds_touch_level(st) & CONFIG2_VALID) == CONFIG2_VALID); } ykds_free(st); } if(vid || pid) { int vendor_id, product_id; if(!yk_get_key_vid_pid(yk, &vendor_id, &product_id)) { exit_code = 1; goto err; } if(vid) { if(!quiet) printf("vendor_id: "); printf("%x\n", vendor_id); } if(pid) { if(!quiet) printf("product_id: "); printf("%x\n", product_id); } } exit_code = 0; error = false; err: if (error || exit_code != 0) { report_yk_error(); } if (yk && !yk_close_key(yk)) { report_yk_error(); exit_code = 2; } if (!yk_release()) { report_yk_error(); exit_code = 2; } exit(exit_code); }
int main (int argc, char *argv[]) { uint8_t buf[128]; uint8_t key[YUBIKEY_KEY_SIZE]; char *aeskey, *token; yubikey_token_st tok; /* Parse command line parameters. */ if (argc <= 2) { printf ("Usage: %s <aeskey> <token>\n", argv[0]); printf (" AESKEY:\tHex encoded AES-key.\n"); printf (" TOKEN:\t\tModHex encoded token.\n"); return EXIT_FAILURE; } aeskey = argv[1]; token = argv[2]; if (strlen (aeskey) != 32) { printf ("error: Hex encoded AES-key must be 32 characters.\n"); return EXIT_FAILURE; } if (strlen (token) > 32) { printf ("warning: overlong token, ignoring prefix: %.*s\n", (int) strlen (token) - 32, token); token = token + (strlen (token) - 32); } if (strlen (token) != 32) { printf ("error: ModHex encoded token must be 32 characters.\n"); return EXIT_FAILURE; } /* Debug. */ printf ("Input:\n"); printf (" token: %s\n", token); yubikey_modhex_decode ((char *) key, token, YUBIKEY_KEY_SIZE); { size_t i; printf (" "); for (i = 0; i < YUBIKEY_KEY_SIZE; i++) printf ("%02x ", key[i] & 0xFF); printf ("\n"); } printf (" aeskey: %s\n", aeskey); yubikey_hex_decode ((char *) key, aeskey, YUBIKEY_KEY_SIZE); { size_t i; printf (" "); for (i = 0; i < YUBIKEY_KEY_SIZE; i++) printf ("%02x ", key[i] & 0xFF); printf ("\n"); } /* Pack up dynamic password, decrypt it and verify checksum */ yubikey_parse ((uint8_t *) token, key, &tok); printf ("Output:\n"); { size_t i; printf (" "); for (i = 0; i < YUBIKEY_BLOCK_SIZE; i++) printf ("%02x ", ((uint8_t *) & tok)[i] & 0xFF); printf ("\n"); } printf ("\nStruct:\n"); /* Debug */ { size_t i; printf (" uid: "); for (i = 0; i < YUBIKEY_UID_SIZE; i++) printf ("%02x ", tok.uid[i] & 0xFF); printf ("\n"); } printf (" counter: %d (0x%04x)\n", tok.ctr, tok.ctr); printf (" timestamp (low): %d (0x%04x)\n", tok.tstpl, tok.tstpl); printf (" timestamp (high): %d (0x%02x)\n", tok.tstph, tok.tstph); printf (" session use: %d (0x%02x)\n", tok.use, tok.use); printf (" random: %d (0x%02x)\n", tok.rnd, tok.rnd); printf (" crc: %d (0x%04x)\n", tok.crc, tok.crc); printf ("\nDerived:\n"); printf (" cleaned counter: %d (0x%04x)\n", yubikey_counter (tok.ctr), yubikey_counter (tok.ctr)); yubikey_modhex_encode ((char *) buf, (char *) tok.uid, YUBIKEY_UID_SIZE); printf (" modhex uid: %s\n", buf); printf (" triggered by caps lock: %s\n", yubikey_capslock (tok.ctr) ? "yes" : "no"); printf (" crc: %04X\n", yubikey_crc16 ((void *) &tok, YUBIKEY_KEY_SIZE)); printf (" crc check: "); if (yubikey_crc_ok_p ((uint8_t *) & tok)) { printf ("ok\n"); return EXIT_SUCCESS; } printf ("fail\n"); return EXIT_FAILURE; }
int main(int argc, char **argv) { YK_KEY *yk = 0; bool error = true; int exit_code = 0; /* Options */ bool serial_dec = false; bool serial_modhex = false; bool serial_hex = false; bool version = false; bool touch_level = false; bool pgm_seq = false; bool quiet = false; yk_errno = 0; if (! parse_args(argc, argv, &serial_dec, &serial_modhex, &serial_hex, &version, &touch_level, &pgm_seq, &quiet, &exit_code)) exit(exit_code); if (!yk_init()) { exit_code = 1; goto err; } if (!(yk = yk_open_first_key())) { exit_code = 1; goto err; } if(serial_dec || serial_modhex || serial_hex) { unsigned int serial; int ret = yk_get_serial(yk, 1, 0, &serial); if(!ret) { exit_code = 1; goto err; } if(serial_dec) { if(!quiet) printf("serial: "); printf("%d\n", serial); } if(serial_hex) { if(!quiet) printf("serial_hex: "); printf("%x\n", serial); } if(serial_modhex) { char buf[64]; char hex_serial[64]; char modhex_serial[64]; snprintf(buf, 64, "%x", serial); yubikey_hex_decode(hex_serial, buf, strlen(buf)); yubikey_modhex_encode(modhex_serial, hex_serial, strlen(hex_serial)); if(!quiet) printf("serial_modhex: "); printf("%s\n", modhex_serial); } } if(version || touch_level || pgm_seq) { YK_STATUS *st = ykds_alloc(); if(!yk_get_status(yk, st)) { ykds_free(st); exit_code = 1; goto err; } if(version) { if(!quiet) printf("version: "); printf("%d.%d.%d\n", ykds_version_major(st), ykds_version_minor(st), ykds_version_build(st)); } if(touch_level) { if(!quiet) printf("touch_level: "); printf("%d\n", ykds_touch_level(st)); } if(pgm_seq) { if(!quiet) printf("programming_sequence: "); printf("%d\n", ykds_pgm_seq(st)); } ykds_free(st); } exit_code = 0; error = false; err: if (error || exit_code != 0) { report_yk_error(); } if (yk && !yk_close_key(yk)) { report_yk_error(); exit_code = 2; } if (!yk_release()) { report_yk_error(); exit_code = 2; } exit(exit_code); }
int main (void) { char buf[1024]; size_t i; int rc; yubikey_token_st tok; /* Test Modhex */ yubikey_modhex_encode (buf, "test", 4); printf ("modhex-encode(\"test\") = %s\n", buf); if (strcmp (buf, "ifhgieif") != 0) { printf ("ModHex failure\n"); return 1; } printf ("Modhex-1 success\n"); printf ("modhex-decode(\"%s\") = ", buf); yubikey_modhex_decode (buf, buf, strlen ((char *) buf)); printf ("%.*s\n", 4, buf); if (memcmp (buf, "test", 4) != 0) { printf ("ModHex failure\n"); return 1; } printf ("Modhex-2 success\n"); strcpy (buf, "cbdefghijklnrtuv"); rc = yubikey_modhex_p (buf); printf ("hex-p(\"%s\") = %d\n", buf, rc); if (!rc) { printf ("Hex_p failure\n"); return 1; } printf ("Hex-3 success\n"); strcpy (buf, "0123Xabc"); rc = yubikey_hex_p (buf); printf ("hex-p(\"%s\") = %d\n", buf, rc); if (rc) { printf ("Hex_p failure\n"); return 1; } printf ("Hex-3 success\n"); /* Test Hex */ yubikey_hex_encode (buf, "test", 4); printf ("hex-encode(\"test\") = %s\n", buf); if (strcmp (buf, "74657374") != 0) { printf ("Hex failure\n"); return 1; } printf ("Hex-1 success\n"); printf ("hex-decode(\"%s\") = ", buf); yubikey_hex_decode (buf, buf, strlen ((char *) buf)); printf ("%.*s\n", 4, buf); if (memcmp (buf, "test", 4) != 0) { printf ("Hex failure\n"); return 1; } printf ("Hex-2 success\n"); strcpy (buf, "0123456789abcdef"); rc = yubikey_hex_p (buf); printf ("hex-p(\"%s\") = %d\n", buf, rc); if (!rc) { printf ("Hex_p failure\n"); return 1; } printf ("Hex-3 success\n"); strcpy (buf, "0123Xabc"); rc = yubikey_hex_p (buf); printf ("hex-p(\"%s\") = %d\n", buf, rc); if (rc) { printf ("Hex_p failure\n"); return 1; } printf ("Hex-3 success\n"); /* Test AES */ { uint8_t buf[1024]; char out[1024]; uint8_t key[16 + 1]; memcpy (buf, "0123456789abcdef\0", 17); memcpy (key, "abcdef0123456789\0", 17); printf ("aes-decrypt (data=%s, key=%s)\n => ", (char *) buf, (char *) key); yubikey_aes_decrypt (buf, key); for (i = 0; i < 16; i++) printf ("%02x", buf[i] & 0xFF); printf ("\n"); if (memcmp (buf, "\x83\x8a\x46\x7f\x34\x63\x95\x51" "\x75\x5b\xd3\x2a\x4a\x2f\x15\xe1", 16) != 0) { printf ("AES failure\n"); return 1; } printf ("AES-1 success\n"); yubikey_aes_encrypt (buf, key); if (memcmp (buf, "0123456789abcdef", 16) != 0) { printf ("AES encryption failure\n"); return 1; } printf ("AES-2 success\n"); /* Test OTP */ memcpy ((void *) &tok, "\x16\xe1\xe5\xd9\xd3\x99\x10\x04\x45\x20\x07\xe3\x02\x00\x00", 16); memcpy (key, "abcdef0123456789", 16); yubikey_generate ((void *) &tok, key, out); yubikey_parse ((uint8_t *) out, key, &tok); if (memcmp (&tok, "\x16\xe1\xe5\xd9\xd3\x99\x10\x04\x45\x20\x07\xe3\x02\x00\x00", 16) != 0) { printf ("OTP generation - parse failure\n"); return 1; } printf ("OTP-1 success\n"); } return 0; }
static int yubikey_auth_core(myConf_t *myConf, REQUEST *request) { int passLen = 0, session = 0, counter = 0, i = 0; MD5_CTX ctx; int result = 0; char *filename = "/usr/local/etc/raddb/yubico/users"; //get password by removing the last 32 characters of the password if (strlen(request->password->vp_strvalue) <= 32) { DEBUG("rlm_yubikey: Password too short."); return RLM_MODULE_REJECT; } passLen = strlen(request->password->vp_strvalue) - 32; strncpy(myConf->pass, request->password->vp_strvalue, passLen); myConf->pass[passLen] = '\0'; strncpy(myConf->token, request->password->vp_strvalue + passLen, 32); myConf->token[32] = '\0'; //md5 stuff MD5Init(&ctx); DEBUG("rlm_yubikey: length: %d, string: %s", passLen, myConf->pass); MD5Update(&ctx, (unsigned char *)myConf->pass, passLen); MD5Final(&ctx); MD5toString(&ctx, myConf->md5ComputedString); myConf->md5ComputedString[32] = '\0'; DEBUG("rlm_yubikey: MD5string of your pass: %s", myConf->md5ComputedString); DEBUG("rlm_yubikey: Username: %s", request->username->vp_strvalue); //read file result = config_read_file(&(myConf->config), filename); if (result != CONFIG_TRUE) { DEBUG("rlm_yubikey: Failed to parse configuration file: config_read_file (&config, filename);"); DEBUG("config_error_text()= %s and config_error_line()=%d", config_error_text(&(myConf->config)), config_error_line(&(myConf->config))); return RLM_MODULE_FAIL; } //parse file myConf->config_setting = config_lookup(&(myConf->config), USERS_PATH); if (myConf->config_setting == NULL) { DEBUG("rlm_yubikey: Failed to parse configuration file: config_lookup failed to find the users node"); return RLM_MODULE_FAIL; } //go through the list of users for (i = 0; i < config_setting_length(myConf->config_setting); i++) { DEBUG("Trying i: %d", i); config_setting_t *tmpSetting = NULL; tmpSetting = config_setting_get_elem(myConf->config_setting, i); if (tmpSetting == NULL) { DEBUG("rlm_yubikey: Failed to parse configuration file: config_setting_get_elem(config_setting,i);"); return RLM_MODULE_FAIL; } if ((config_setting_get_string_elem(tmpSetting, 0) == NULL) || (config_setting_get_string_elem(tmpSetting, 1) == NULL) || (config_setting_get_string_elem(tmpSetting, 2) == NULL)) { DEBUG("rlm_yubikey: Failed to parse configuration file while reading the username/password/aeskey triplet "); return RLM_MODULE_FAIL; } //check usernames are equal if (strcmp(request->username->vp_strvalue, config_setting_get_string_elem(tmpSetting, 0)) != 0) { //users do not match. No need to debug this //Go to next iteration continue; } //check passwords are equal if (strcmp(myConf->md5ComputedString, config_setting_get_string_elem(tmpSetting, 1)) != 0) { //passwords do not match. We debug DEBUG("rlm_yubikey: Password does not match for user %s", request->username->vp_strvalue); //Go to next iteration continue; } //check aes stuff - mostly copied from the ykdebug.c that comes with the low-level yubikey library uint8_t buf[128]; const char *aeskey = config_setting_get_string_elem(tmpSetting, 2); char *token = myConf->token; uint8_t key[YUBIKEY_KEY_SIZE]; yubikey_token_st tok; yubikey_modhex_decode((char*) key, token, YUBIKEY_KEY_SIZE); DEBUG("rlm_yubikey: aeskey: %s", aeskey); yubikey_hex_decode((char*) key, aeskey, YUBIKEY_KEY_SIZE); /* Pack up dynamic password, decrypt it and verify checksum */ yubikey_parse((uint8_t*) token, key, &tok); DEBUG("rlm_yubikey: Struct:"); size_t i; char *tmp = (char*) malloc(1024); for (i = 0; i < YUBIKEY_UID_SIZE; i++) { sprintf(tmp + i, "%c ", tok.uid[i] & 0xFF); } tmp[YUBIKEY_UID_SIZE + i] = 0; DEBUG("rlm_yubikey: uid:%s", tmp); free(tmp); DEBUG("rlm_yubikey: counter: %d (0x%04x)", tok.ctr, tok.ctr); DEBUG("rlm_yubikey: timestamp (low): %d (0x%04x)", tok.tstpl, tok.tstpl); DEBUG("rlm_yubikey: timestamp (high): %d (0x%02x)", tok.tstph, tok.tstph); DEBUG("rlm_yubikey: session use: %d (0x%02x)", tok.use, tok.use); DEBUG("rlm_yubikey: random: %d (0x%02x)", tok.rnd, tok.rnd); DEBUG("rlm_yubikey: crc: %d (0x%04x)", tok.crc, tok.crc); DEBUG("rlm_yubikey: Derived:"); DEBUG("rlm_yubikey: cleaned counter: %d (0x%04x)",yubikey_counter(tok.ctr), yubikey_counter(tok.ctr)); yubikey_modhex_encode((char*) buf, (char*) tok.uid, YUBIKEY_UID_SIZE); DEBUG("rlm_yubikey: modhex uid: %s", buf); DEBUG("rlm_yubikey: triggered by caps lock: %s", yubikey_capslock(tok.ctr) ? "yes" : "no"); DEBUG("rlm_yubikey: crc: %04X", yubikey_crc16((void*) & tok, YUBIKEY_KEY_SIZE)); DEBUG("rlm_yubikey: crc check: "); if (yubikey_crc_ok_p((uint8_t*) & tok)) { DEBUG("rlm_yubikey: ok"); char *tmppath = KEYS_PATH; char *path = (char*) malloc(strlen(tmppath) + 32 + 1); strcpy(path, tmppath); strcat(path, aeskey); myConf->config_setting = config_lookup(&(myConf->config), path); if (myConf->config_setting == NULL) { DEBUG("rlm_yubikey: Error parsing file: %s not found", path); return RLM_MODULE_FAIL; } //checking counter and session and update them if necessary counter = config_setting_get_int_elem(myConf->config_setting, 0); session = config_setting_get_int_elem(myConf->config_setting, 1); DEBUG("rlm_yubikey: Read counter: %d, session: %d", counter, session); if ((tok.ctr < counter)||((tok.ctr == counter) && (tok.use <= session))) { DEBUG("rlm_yubikey: someone tried to login with an old generated hash"); return RLM_MODULE_REJECT; } //updating config file with counter and session config_setting_set_int_elem(myConf->config_setting, 0, tok.ctr); config_setting_set_int_elem(myConf->config_setting, 1, tok.use); DEBUG("rlm_yubikey: Written element: %ld", config_setting_get_int_elem(myConf->config_setting, 0)); DEBUG("rlm_yubikey: Written element: %ld", config_setting_get_int_elem(myConf->config_setting, 1)); if (CONFIG_FALSE == config_write_file(&(myConf->config), filename)) { DEBUG("rlm_yubikey: Failed to write the file."); return RLM_MODULE_FAIL; } return RLM_MODULE_OK; } DEBUG("rlm_yubikey: fail"); } DEBUG("rlm_yubikey: Authenticating with password %s", request->password->vp_strvalue); return RLM_MODULE_REJECT; }
int ykp_write_config(const YKP_CONFIG *cfg, int (*writer)(const char *buf, size_t count, void *userdata), void *userdata) { if (cfg) { char buffer[256]; struct map_st *p; unsigned char t_flags; bool key_bits_in_uid = false; /* for OATH-HOTP and HMAC-SHA1 challenge response, there is four bytes * additional key data in the uid field */ key_bits_in_uid = (_get_supported_key_length(cfg) == 20); /* fixed: */ writer(str_fixed, strlen(str_fixed), userdata); writer(str_key_value_separator, strlen(str_key_value_separator), userdata); /* XXX print OATH-HOTP fixed differently based on oath-fixed-modhex etc. */ writer(str_modhex_prefix, strlen(str_key_value_separator), userdata); yubikey_modhex_encode(buffer, (char *)cfg->ykcore_config.fixed, cfg->ykcore_config.fixedSize); writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); /* uid: */ writer(str_uid, strlen(str_uid), userdata); writer(str_key_value_separator, strlen(str_key_value_separator), userdata); if (key_bits_in_uid) { writer("n/a", 3, userdata); } else { writer(str_hex_prefix, strlen(str_key_value_separator), userdata); yubikey_hex_encode(buffer, (char *)cfg->ykcore_config.uid, UID_SIZE); writer(buffer, strlen(buffer), userdata); } writer("\n", 1, userdata); /* key: */ writer(str_key, strlen(str_key), userdata); writer(str_key_value_separator, strlen(str_key_value_separator), userdata); writer(str_hex_prefix, strlen(str_key_value_separator), userdata); yubikey_hex_encode(buffer, (char *)cfg->ykcore_config.key, KEY_SIZE); if (key_bits_in_uid) { yubikey_hex_encode(buffer + KEY_SIZE * 2, (char *)cfg->ykcore_config.uid, 4); } writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); /* acc_code: */ writer(str_acc_code, strlen(str_acc_code), userdata); writer(str_key_value_separator, strlen(str_key_value_separator), userdata); writer(str_hex_prefix, strlen(str_key_value_separator), userdata); yubikey_hex_encode(buffer, (char *)cfg->ykcore_config.accCode, ACC_CODE_SIZE); writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); /* ticket_flags: */ buffer[0] = '\0'; for (p = ticket_flags_map; p->flag; p++) { if ((cfg->ykcore_config.tktFlags & p->flag) == p->flag && p->vcheck(cfg)) { if (*buffer) { strcat(buffer, str_flags_separator); strcat(buffer, p->flag_text); } else { strcpy(buffer, p->flag_text); } } } writer(str_ticket_flags, strlen(str_ticket_flags), userdata); writer(str_key_value_separator, strlen(str_key_value_separator), userdata); writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); /* config_flags: */ buffer[0] = '\0'; t_flags = cfg->ykcore_config.cfgFlags; for (p = config_flags_map; p->flag; p++) { if ((t_flags & p->flag) == p->flag && p->vcheck(cfg) && (cfg->ykcore_config.tktFlags & p->tkt_context) == p->tkt_context) { if (*buffer) { strcat(buffer, str_flags_separator); strcat(buffer, p->flag_text); } else { strcpy(buffer, p->flag_text); } /* make sure we don't show more than one cfgFlag per value - some cfgflags share value in different contexts */ t_flags -= p->flag; } } writer(str_config_flags, strlen(str_config_flags), userdata); writer(str_key_value_separator, strlen(str_key_value_separator), userdata); writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); /* extended_flags: */ buffer[0] = '\0'; for (p = extended_flags_map; p->flag; p++) { if ((cfg->ykcore_config.extFlags & p->flag) == p->flag && p->vcheck(cfg)) { if (*buffer) { strcat(buffer, str_flags_separator); strcat(buffer, p->flag_text); } else { strcpy(buffer, p->flag_text); } } } writer(str_extended_flags, strlen(str_extended_flags), userdata); writer(str_key_value_separator, strlen(str_key_value_separator), userdata); writer(buffer, strlen(buffer), userdata); writer("\n", 1, userdata); return 1; } return 0; }
static int _ykp_legacy_export_config(const YKP_CONFIG *cfg, char *buf, size_t len) { if (cfg) { char buffer[256]; struct map_st *p; unsigned char t_flags; bool key_bits_in_uid = false; YK_CONFIG ycfg = cfg->ykcore_config; int mode = MODE_OTP_YUBICO; int pos = 0; if((ycfg.tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP){ if((ycfg.cfgFlags & CFGFLAG_CHAL_HMAC) == CFGFLAG_CHAL_HMAC) { mode = MODE_CHAL_HMAC; } else if((ycfg.cfgFlags & CFGFLAG_CHAL_YUBICO) == CFGFLAG_CHAL_YUBICO) { mode = MODE_CHAL_YUBICO; } else { mode = MODE_OATH_HOTP; } } else if((ycfg.cfgFlags & CFGFLAG_STATIC_TICKET) == CFGFLAG_STATIC_TICKET) { mode = MODE_STATIC_TICKET; } /* for OATH-HOTP and HMAC-SHA1 challenge response, there is four bytes * additional key data in the uid field */ key_bits_in_uid = (_get_supported_key_length(cfg) == 20); /* fixed: or OATH id: */ if ((ycfg.tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP && ycfg.fixedSize) { /* First byte (vendor id) */ if ((ycfg.cfgFlags & CFGFLAG_OATH_FIXED_MODHEX1) == CFGFLAG_OATH_FIXED_MODHEX1 || (ycfg.cfgFlags & CFGFLAG_OATH_FIXED_MODHEX2) == CFGFLAG_OATH_FIXED_MODHEX2 || (ycfg.cfgFlags & CFGFLAG_OATH_FIXED_MODHEX) == CFGFLAG_OATH_FIXED_MODHEX) { yubikey_modhex_encode(buffer, (const char *)ycfg.fixed, 1); } else { yubikey_hex_encode(buffer, (const char *)ycfg.fixed, 1); } /* Second byte (token type) */ if ((ycfg.cfgFlags & CFGFLAG_OATH_FIXED_MODHEX2) == CFGFLAG_OATH_FIXED_MODHEX2 || (ycfg.cfgFlags & CFGFLAG_OATH_FIXED_MODHEX) == CFGFLAG_OATH_FIXED_MODHEX) { yubikey_modhex_encode(buffer + 2, (const char *)ycfg.fixed + 1, 1); } else { yubikey_hex_encode(buffer + 2, (const char *)ycfg.fixed + 1, 1); } /* bytes 3-12 - MUI */ if ((ycfg.cfgFlags & CFGFLAG_OATH_FIXED_MODHEX) == CFGFLAG_OATH_FIXED_MODHEX) { yubikey_modhex_encode(buffer + 4, (const char *)ycfg.fixed + 2, 8); } else { yubikey_hex_encode(buffer + 4, (const char *)ycfg.fixed + 2, 8); } buffer[12] = 0; pos += snprintf(buf, len - (size_t)pos, "%s%s%s\n", str_oath_id, str_key_value_separator, buffer); } else { yubikey_modhex_encode(buffer, (const char *)ycfg.fixed, ycfg.fixedSize); pos += snprintf(buf, len - (size_t)pos, "%s%s%s%s\n", str_fixed, str_key_value_separator, str_modhex_prefix, buffer); } /* uid: */ if (key_bits_in_uid) { strncpy(buffer, "n/a", 3); } else { yubikey_hex_encode(buffer, (const char *)ycfg.uid, UID_SIZE); } pos += snprintf(buf + pos, len - (size_t)pos, "%s%s%s\n", str_uid, str_key_value_separator, buffer); /* key: */ yubikey_hex_encode(buffer, (const char *)ycfg.key, KEY_SIZE); if (key_bits_in_uid) { yubikey_hex_encode(buffer + KEY_SIZE * 2, (const char *)ycfg.uid, 4); } pos += snprintf(buf + pos, len - (size_t)pos, "%s%s%s%s\n", str_key, str_key_value_separator, str_hex_prefix, buffer); /* acc_code: */ yubikey_hex_encode(buffer, (const char*)ycfg.accCode, ACC_CODE_SIZE); pos += snprintf(buf + pos, len - (size_t)pos, "%s%s%s%s\n", str_acc_code, str_key_value_separator, str_hex_prefix, buffer); /* OATH IMF: */ if ((ycfg.tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP && capability_has_oath_imf(cfg)) { pos += snprintf(buf + pos, len - (size_t)pos, "%s%s%s%lx\n", str_oath_imf, str_key_value_separator, str_hex_prefix, ykp_get_oath_imf(cfg)); } /* ticket_flags: */ buffer[0] = '\0'; for (p = _ticket_flags_map; p->flag; p++) { if ((ycfg.tktFlags & p->flag) == p->flag && p->capability(cfg) && (mode & p->mode) == mode) { if (*buffer) { strcat(buffer, str_flags_separator); strcat(buffer, p->flag_text); } else { strcpy(buffer, p->flag_text); } } } pos += snprintf(buf + pos, len - (size_t)pos, "%s%s%s\n", str_ticket_flags, str_key_value_separator, buffer); /* config_flags: */ buffer[0] = '\0'; t_flags = ycfg.cfgFlags; for (p = _config_flags_map; p->flag; p++) { if ((t_flags & p->flag) == p->flag && p->capability(cfg) && (mode & p->mode) == mode) { if (*buffer) { strcat(buffer, str_flags_separator); strcat(buffer, p->flag_text); } else { strcpy(buffer, p->flag_text); } /* make sure we don't show more than one cfgFlag per value - some cfgflags share value in different contexts */ t_flags -= p->flag; } } pos += snprintf(buf + pos, len - (size_t)pos, "%s%s%s\n", str_config_flags, str_key_value_separator, buffer); /* extended_flags: */ buffer[0] = '\0'; for (p = _extended_flags_map; p->flag; p++) { if ((ycfg.extFlags & p->flag) == p->flag && p->capability(cfg) && (mode & p->mode) == mode) { if (*buffer) { strcat(buffer, str_flags_separator); strcat(buffer, p->flag_text); } else { strcpy(buffer, p->flag_text); } } } pos += snprintf(buf + pos, len - (size_t)pos, "%s%s%s\n", str_extended_flags, str_key_value_separator, buffer); return pos; } return 0; }