int main(int argc, char *argv[]) { CREATE_LOG("./"); auto desc = create_descriptions(); auto vm = parse_options(argc, argv, desc); if(vm.count("help")) { std::cout << desc << std::endl; return 1; } Botan::LibraryInitializer init; auto host = vm["host"].as<std::string>(); auto port = vm["port"].as<int>(); auto pass = vm.count("pass") ? vm["pass"].as<std::string>() : prompt_pass(); auto key = vm["key"].as<std::string>(); auto pkey = load_private_key(key, pass); CHECK(pkey); n::connection_manager con{POOL_SIZE, static_cast<n::port_type>(port)}; sc::encrypted_channels sec{*pkey}; user_info_map users; u::bytes data; while(true) try { n::endpoint ep; if(!con.receive(ep, data)) { u::sleep_thread(THREAD_SLEEP); continue; } //decrypt message auto sid = n::make_address_str(ep); sc::encryption_type et; data = sec.decrypt(sid, data, et); data = u::uncompress(data); //parse message m::message m; u::decode(data, m); if(m.meta.type == ms::GREET_REGISTER) { if(et != sc::encryption_type::asymmetric) continue; ms::greet_register r{m}; register_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_FIND_REQUEST) { if(et != sc::encryption_type::asymmetric) continue; ms::greet_find_request r{m}; find_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_KEY_REQUEST) { ms::greet_key_request r{m}; send_pub_key(con, sec, ep, r, users, *pkey); } } catch(std::exception& e) { LOG << "error parsing message: " << e.what() << std::endl; } catch(...) { LOG << "unknown error parsing message: " << std::endl; } }
char * hsm_prompt_pin(unsigned int id, const char *repository, unsigned int mode) { /* Shared memory */ int shmid; int semid; char *pins = NULL; int index = id * (HSM_MAX_PIN_LENGTH + 1); /* PIN from getpass */ char prompt[64]; char *prompt_pin = NULL; unsigned int size = 0; /* Check input data */ if (id >= HSM_MAX_SESSIONS) return NULL; if (repository == NULL) return NULL; if (mode != HSM_PIN_FIRST && mode != HSM_PIN_RETRY && mode != HSM_PIN_SAVE) return NULL; /* Create/get the semaphore */ semid = hsm_sem_open(); if (semid == -1) return NULL; /* Lock the semaphore */ if (hsm_sem_wait(semid) != 0) return NULL; /* Create/get the shared memory */ shmid = hsm_shm_open(); if (shmid == -1) { hsm_sem_post(semid); return NULL; } /* Attach to the shared memory */ pins = (char *)shmat(shmid, NULL, 0); if (pins == (char *)-1) { pins = NULL; hsm_sem_post(semid); return NULL; } /* Get the PIN */ if (mode != HSM_PIN_SAVE) { /* Do we have a PIN in the shared memory? */ if (mode == HSM_PIN_FIRST && pins[index] != '\0') { size = strlen(&pins[index]); if (size > HSM_MAX_PIN_LENGTH) size = HSM_MAX_PIN_LENGTH; memcpy(pin, &pins[index], size); pin[size] = '\0'; } else { /* Zeroize bad PIN in shared memory */ if (mode == HSM_PIN_RETRY && pins[index] != '\0') { memset(&pins[index], '\0', HSM_MAX_PIN_LENGTH+1); } /* Unlock the semaphore if someone would do Ctrl+C */ hsm_sem_post(semid); /* Get PIN */ snprintf(prompt, 64, "Enter PIN for token %s: ", repository); prompt_pin = prompt_pass(prompt); if (prompt_pin == NULL) { shmdt(pins); pins = NULL; return NULL; } /* Lock the semaphore */ hsm_sem_wait(semid); /* Remember PIN */ size = strlen(prompt_pin); if (size > HSM_MAX_PIN_LENGTH) size = HSM_MAX_PIN_LENGTH; memset(pin, '\0', HSM_MAX_PIN_LENGTH+1); memcpy(pin, prompt_pin, size); /* Zeroize the prompt_pass PIN */ memset(prompt_pin, '\0', strlen(prompt_pin)); } } else { /* Save the PIN */ memcpy(&pins[index], pin, HSM_MAX_PIN_LENGTH+1); /* Zeroize the PIN */ memset(pin, '\0', HSM_MAX_PIN_LENGTH+1); } /* Detach from the shared memory */ shmdt(pins); pins = NULL; /* Unlock the semaphore */ hsm_sem_post(semid); return pin; }
int main(int argc, char *argv[]) { CREATE_LOG("./"); auto desc = create_descriptions(); auto vm = parse_options(argc, argv, desc); if(vm.count("help")) { std::cout << desc << std::endl; return 1; } Botan::LibraryInitializer init; auto host = vm["host"].as<std::string>(); auto port = vm["port"].as<std::string>(); auto pass = vm.count("pass") ? vm["pass"].as<std::string>() : prompt_pass(); auto key = vm["key"].as<std::string>(); auto pkey = load_private_key(key, pass); CHECK(pkey); //it is important the tcp_connection manager is created before //the input tcp_connection is made. This is because tcp on //linux requires that binds to the same port are made before //a listen is made. n::connection_manager con{POOL_SIZE, port}; sc::session_library sec{*pkey}; user_info_map users; u::bytes data; while(true) try { n::endpoint ep; if(!con.receive(ep, data)) { u::sleep_thread(THREAD_SLEEP); continue; } //decrypt message auto sid = n::make_address_str(ep); data = sec.decrypt(sid, data); //parse message m::message m; u::decode(data, m); if(m.meta.type == ms::GREET_REGISTER) { ms::greet_register r{m}; register_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_FIND_REQUEST) { ms::greet_find_request r{m}; find_user(con, sec, ep, r, users); } else if(m.meta.type == ms::GREET_KEY_REQUEST) { ms::greet_key_request r{m}; send_pub_key(con, sec, ep, r, users, *pkey); } } catch(std::exception& e) { LOG << "error parsing message: " << e.what() << std::endl; LOG << "message: " << u::to_str(data) << std::endl; } catch(...) { LOG << "unknown error parsing message: " << std::endl; LOG << "message: " << u::to_str(data) << std::endl; } }