void peer_connection::read_loop() { ilog( "read loop" ); try { auto one_time_key = fc::ecc::private_key::generate(); fc::ecc::public_key pub = one_time_key.get_public_key(); auto s = pub.serialize(); _socket.write( (char*)&s, sizeof(s) ); fc::ecc::public_key_data remote_one_time_key; _socket.read( (char*)&remote_one_time_key, sizeof(remote_one_time_key) ); _shared_secret = one_time_key.get_shared_secret( remote_one_time_key ); elog( "${ss}", ("ss",_shared_secret) ); if( _send_queue.size() && !_send_queue_complete.valid() ) _send_queue_complete = fc::async( [=](){ process_send_queue(); } ); message next_message; next_message.data.resize( BTS_NETWORK_MAX_MESSAGE_SIZE ); while( !_read_loop.canceled() ) { // read a message _socket.read( (char*)&next_message.size, sizeof(next_message.size) ); wlog( " read message of size ${s} ", ("s", next_message.size) ); if( next_message.size > BTS_NETWORK_MAX_MESSAGE_SIZE ) { send_message( goodbye_message( message_too_large() ) ); _socket.close(); FC_CAPTURE_AND_THROW( message_too_large, (next_message.size) ); } _socket.read( (char*)&next_message.type, sizeof(next_message.type) ); wlog( " read message of size ${s} type ${t}", ("s", next_message.size)("t",int(next_message.type)) ); _socket.read( next_message.data.data(), next_message.size ); wlog( "read body of message" ); received_message( shared_from_this(), next_message ); } } catch ( const fc::exception& e ) { ilog( "closed: ${e}", ("e", e.to_detail_string()) ); connection_closed( shared_from_this(), e ); return; } ilog( "closed!" ); connection_closed( shared_from_this(), optional<fc::exception>() ); }
/* This handles Digest Authentication. Returns a hash of the User, Realm and (Required) Password. Caller (Digest module) determines if the entered password was actually valid */ static authn_status ga_get_realm_hash(request_rec *r, const char *user, const char *realm, char **rethash) { /* Per Apache mod_auth.h: * Given a user and realm, expected to return AUTH_USER_FOUND if we * can find a md5 hash of 'user:realm:password' */ authn_google_config_rec *conf = ap_get_module_config(r->per_dir_config, &authn_google_module); char *sharedKey; char *ga_filename; char *static_pw; if (conf->debugLevel) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "**** DIGEST AUTH at T=%lu user \"%s\"",apr_time_now()/1000000,user); unsigned char *hash = apr_palloc(r->pool,APR_MD5_DIGESTSIZE); ga_filename = apr_psprintf(r->pool,"%s/%s",conf->pwfile,user); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "GetRealmHash called for sharedkey \"%s\"\n",ga_filename); sharedKey = getSharedKey(r,ga_filename,&static_pw); if (!sharedKey) return AUTH_USER_NOT_FOUND; int secretLen; uint8_t *secret = get_shared_secret(r,sharedKey,&secretLen); unsigned int truncatedHash = computeTimeCode(get_timestamp(),secret,secretLen); char *pwstr; if (static_pw) { pwstr = apr_psprintf(r->pool,"%s%6.6u",static_pw,truncatedHash); } else { pwstr = apr_psprintf(r->pool,"%6.6u",truncatedHash); } char *hashstr = apr_psprintf(r->pool,"%s:%s:%s",user,realm,pwstr); if (conf->debugLevel) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Password \"%s\" at modulus %lu",pwstr,(apr_time_now() / 1000000) % 30); apr_md5(hash ,hashstr,strlen(hashstr)); *rethash = hex_encode(r->pool,hash,APR_MD5_DIGESTSIZE); addCookie(r,secret,secretLen); return AUTH_USER_FOUND; }
/** * Encrypts the message using a random / newly generated one-time private * key. */ encrypted_message decrypted_message::encrypt(const fc::ecc::public_key& to)const { encrypted_message em; auto priv_dh_key = fc::ecc::private_key::generate(); em.dh_key = priv_dh_key.get_public_key(); auto aes_key = priv_dh_key.get_shared_secret( to ); em.data = aes_encrypt( aes_key, fc::raw::pack(*this) ); auto check_hash = fc::sha512::hash( aes_key ); fc::ripemd160::encoder enc; fc::raw::pack( enc, check_hash ); fc::raw::pack( enc, em.data ); em.check = enc.result(); return em; }
/** * \brief getUserSecret Based on the given username, get the users secret key * \param r Request * \param username Username * \param secret Secret key returned here. Must be allocated by caller * \return Pointer to secret key data on success, NULL on error **/ static uint8_t *getUserSecret(request_rec *r, const char *username, int *secretLen, char **static_pw) { authn_google_config_rec *conf = ap_get_module_config(r->per_dir_config, &authn_google_module); char *ga_filename = apr_psprintf(r->pool,"%s/%s",conf->pwfile,username); char *sharedKey; ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "getUserSecret with username \"%s\"\n",username); sharedKey = getSharedKey(r,ga_filename,static_pw); if (!sharedKey) return 0L; if (!sharedKey) return 0L; uint8_t *secret = get_shared_secret(r,sharedKey,secretLen); return secret; }
/** * Encrypts the message using a random / newly generated one-time private * key. */ encrypted_message decrypted_message::encrypt(const fc::ecc::public_key& to)const { encrypted_message em; auto priv_dh_key = fc::ecc::private_key::generate(); em.dh_key = priv_dh_key.get_public_key(); auto bf_key = priv_dh_key.get_shared_secret( to ); em.dh_check = fc::sha1::hash( bf_key )._hash[0]; fc::blowfish bf; bf.start( (unsigned char*)&bf_key, sizeof(bf_key) ); em.data = fc::raw::pack( *this ); // TODO: avoid extra dynamic memory alloc by pre-calc size int extra = 8 - em.data.size() % 8; em.data.resize( em.data.size() + extra ); bf.encrypt( (unsigned char*)em.data.data(), em.data.size() ); return em; }
static int googleauth_login(const char *username, const char *password) { uint8_t *secret = NULL; int secretLen = 0; int code = 0; char *endptr; Config config; if (read_cfg(username, &config)) { syslog(LOG_INFO, "user %s: error in user conf file", username); exit(EXIT_FAILURE); } long l = strtol(password, &endptr, 10); if (l < 0 || *endptr) { syslog(LOG_ERR, "user %s: failed to extract verification code", username); return (AUTH_FAILED); } code = (int)l; if ((secret = get_shared_secret(username, &secretLen))) { int advance = 0; if (check_scratch_codes(username, code)) { if (config.is_totp) { if (check_timebased_code(&config, secret, secretLen, code)) { #if 0 syslog(LOG_ERR, "user %s code %d: " "check_timebased_code != 0", username, code); #else syslog(LOG_ERR, "user %s: " "check_timebased_code != 0", username); #endif if (secret) { memset(secret, 0, secretLen); free(secret); } return (AUTH_FAILED); } } else { int hotp_counter = get_hotp_counter(username); if (check_counterbased_code(&config, secret, secretLen, code, hotp_counter, &advance)) { syslog(LOG_ERR, "user %s: check_counterbased_code != 0", username); if (secret) { memset(secret, 0, secretLen); free(secret); } return (AUTH_FAILED); } // If an hotp login attempt has been made, // the counter must always be advanced by at least one if (advance) { if (advance_counter_by(username, hotp_counter, advance)) { syslog(LOG_ERR, "user %s: failed to advance hotp counter", username); if (secret) { memset(secret, 0, secretLen); free(secret); } return (AUTH_FAILED); } } } } if (secret) { memset(secret, 0, secretLen); free(secret); } return (AUTH_OK); } return (AUTH_FAILED); }