From 95ea9ecfdedf52e5e11e9bbfa1931887b00be455 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 5 Jul 2013 01:31:30 +0200 Subject: [PATCH] feature #2054: Free encoded string in aes encryption. Move token path to history. Minor changes --- include/History.h | 1 + include/NebulaUtil.h | 9 +++- include/VirtualMachine.h | 17 ++++++- .../common/CloudAuth/OneGateCloudAuth.rb | 13 +++-- src/common/NebulaUtil.cc | 16 +++--- src/onegate/bin/onegate-server | 3 +- src/onegate/onegate-server.rb | 33 ++++++------- src/vm/History.cc | 5 ++ src/vm/VirtualMachine.cc | 49 ++++++++++++------- 9 files changed, 96 insertions(+), 50 deletions(-) diff --git a/include/History.h b/include/History.h index 5283d87cf2..52e9369e38 100644 --- a/include/History.h +++ b/include/History.h @@ -310,6 +310,7 @@ private: string transfer_file; string deployment_file; string context_file; + string token_file; // Remote paths string checkpoint_file; diff --git a/include/NebulaUtil.h b/include/NebulaUtil.h index b44b51a2bb..a832f7863e 100644 --- a/include/NebulaUtil.h +++ b/include/NebulaUtil.h @@ -52,7 +52,14 @@ namespace one_util */ std::string * base64_decode(const std::string& in); - std::string aes256cbc_encrypt(const std::string& in, const std::string password); + /** + * AES256 encryption + * @param in the string to encrypt + * @param password to encrypt data + * @return a pointer to the encrypted string (must be freed) or 0 in case of + * error + */ + std::string * aes256cbc_encrypt(const std::string& in, const std::string password); /** * Creates a random number, using time(0) as seed, and performs an sha1 hash diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 7a01dca4dd..38e943835a 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -557,7 +557,7 @@ public: * or, in case that OpenNebula is installed in root * /var/lib/one/vms/$VM_ID/deployment.$SEQ * The hasHistory() function MUST be called before this one. - * @return the deployment filename + * @return the deployment file path */ const string & get_deployment_file() const { @@ -570,13 +570,26 @@ public: * or, in case that OpenNebula is installed in root * /var/lib/one/vms/$VM_ID/context.sh * The hasHistory() function MUST be called before this one. - * @return the deployment filename + * @return the context file path */ const string & get_context_file() const { return history->context_file; } + /** + * Returns the token filename. The token file is in the form: + * $ONE_LOCATION/var/vms/$VM_ID/token.txt + * or, in case that OpenNebula is installed in root + * /var/lib/one/vms/$VM_ID/token.txt + * The hasHistory() function MUST be called before this one. + * @return the token file path + */ + const string & get_token_file() const + { + return history->token_file; + } + /** * Returns the remote deployment filename. The file is in the form: * $DS_LOCATION/$SYSTEM_DS/$VM_ID/deployment.$SEQ diff --git a/src/cloud/common/CloudAuth/OneGateCloudAuth.rb b/src/cloud/common/CloudAuth/OneGateCloudAuth.rb index aea5d3c19f..f36aca7cfc 100644 --- a/src/cloud/common/CloudAuth/OneGateCloudAuth.rb +++ b/src/cloud/common/CloudAuth/OneGateCloudAuth.rb @@ -30,6 +30,7 @@ module OneGateCloudAuth def do_auth(env, params={}) token = env['HTTP_X_ONEGATE_TOKEN'] + if token.nil? logger.error {"VMID:#{params[:id]} X_ONEGATE_TOKEN" \ " header not preset"} @@ -37,6 +38,7 @@ module OneGateCloudAuth else vm = VirtualMachine.new_with_id(params[:id], client) rc = vm.info + if OpenNebula.is_error?(rc) logger.error {"VMID:#{params[:id]} vm.info" \ " error: #{rc.message}"} @@ -44,6 +46,7 @@ module OneGateCloudAuth end user_id = vm['TEMPLATE/CREATED_BY'] + if user_id.nil? logger.error {"VMID:#{params[:id]} CREATED_BY not present" \ " in the VM TEMPLATE"} @@ -51,7 +54,8 @@ module OneGateCloudAuth end user = User.new_with_id(user_id, client) - rc = user.info + rc = user.info + if OpenNebula.is_error?(rc) logger.error {"VMID:#{params[:id]} user.info" \ " error: #{rc.message}"} @@ -59,6 +63,7 @@ module OneGateCloudAuth end token_password = user['TEMPLATE/TOKEN_PASSWORD'] + if token_password.nil? logger.error {"VMID:#{params[:id]} TOKEN_PASSWORD not present"\ " in the USER:#{user_id} TEMPLATE"} @@ -88,9 +93,9 @@ module OneGateCloudAuth private - def encrypt(data) + def encrypt(data, token_password) @cipher.encrypt - @cipher.key = @key + @cipher.key = token_password rc = @cipher.update(data) rc << @cipher.final @@ -107,4 +112,4 @@ module OneGateCloudAuth return rc end -end \ No newline at end of file +end diff --git a/src/common/NebulaUtil.cc b/src/common/NebulaUtil.cc index 7fb351718e..5b43e25483 100644 --- a/src/common/NebulaUtil.cc +++ b/src/common/NebulaUtil.cc @@ -176,12 +176,15 @@ string one_util::sha1_digest(const string& in) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -string one_util::aes256cbc_encrypt(const string& in, const string password) +string * one_util::aes256cbc_encrypt(const string& in, const string password) { EVP_CIPHER_CTX ctx; - const unsigned char *key = (unsigned char*)password.c_str(); - const unsigned char *in_data = (unsigned char*)in.c_str(); + + const unsigned char *key = (unsigned char*) password.c_str(); + const unsigned char *in_data = (unsigned char*) in.c_str(); + unsigned char out[in.length() + AES_BLOCK_SIZE]; + int outlen1, outlen2; EVP_EncryptInit(&ctx, EVP_aes_256_cbc(), key, NULL); @@ -190,10 +193,9 @@ string one_util::aes256cbc_encrypt(const string& in, const string password) EVP_CIPHER_CTX_cleanup(&ctx); - string encrypt = string((char*)out, (size_t)outlen1+outlen2); - string encrypt64 = *base64_encode(encrypt); + string encrypt((char*) out, (size_t)(outlen1+outlen2)); - return encrypt64; + return base64_encode(encrypt);; } /* -------------------------------------------------------------------------- */ @@ -201,7 +203,7 @@ string one_util::aes256cbc_encrypt(const string& in, const string password) string one_util::random_password() { - stringstream sstr; + ostringstream sstr; srand(time(0)); sstr << rand(); diff --git a/src/onegate/bin/onegate-server b/src/onegate/bin/onegate-server index 3551d60af4..43ce3bb3f3 100755 --- a/src/onegate/bin/onegate-server +++ b/src/onegate/bin/onegate-server @@ -59,7 +59,7 @@ start() # Start the onegate daemon touch $ONEGATE_LOCK_FILE - ruby -dw $ONEGATE_SERVER > $ONEGATE_LOG 2>$ONEGATE_LOG_ERROR & + ruby $ONEGATE_SERVER > $ONEGATE_LOG 2>$ONEGATE_LOG_ERROR & LASTPID=$! if [ $? -ne 0 ]; then @@ -87,7 +87,6 @@ start() # stop() { - if [ ! -f $ONEGATE_PID ]; then echo "Couldn't find onegate-server process pid." exit 1 diff --git a/src/onegate/onegate-server.rb b/src/onegate/onegate-server.rb index f58998167e..33fa62b0bc 100644 --- a/src/onegate/onegate-server.rb +++ b/src/onegate/onegate-server.rb @@ -96,24 +96,23 @@ end put '/vm/:id' do client = authenticate(request.env, params) - if client - vm = VirtualMachine.new_with_id(params[:id], client) - rc = vm.info - if OpenNebula.is_error?(rc) - logger.error {"VMID:#{params[:id]} vm.info error: #{rc.message}"} - halt 404, rc.message - else - rc = vm.update(request.body.read, true) - if OpenNebula.is_error?(rc) - logger.error {"VMID:#{params[:id]} vm.update \ - error: #{rc.message}"} - halt 500, rc.message - end - end + halt 401, "Not authorized" if client.nil? - [200, ""] - else - halt 401, "Not authorized" + vm = VirtualMachine.new_with_id(params[:id], client) + rc = vm.info + + if OpenNebula.is_error?(rc) + logger.error {"VMID:#{params[:id]} vm.info error: #{rc.message}"} + halt 404, rc.message end + + rc = vm.update(request.body.read, true) + + if OpenNebula.is_error?(rc) + logger.error {"VMID:#{params[:id]} vm.update error: #{rc.message}"} + halt 500, rc.message + end + + [200, ""] end diff --git a/src/vm/History.cc b/src/vm/History.cc index 5e2ba19dfe..0a53ffd56f 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -127,6 +127,11 @@ void History::non_persistent_data() context_file = os.str(); + os.str(""); + os << vm_lhome << "/token.txt"; + + token_file = os.str(); + // ----------- Remote Locations ------------ os.str(""); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index addb63cf8b..4c65d12cfb 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -2452,15 +2452,25 @@ int VirtualMachine::generate_context(string &files, int &disk_id, string& token_ } context->vector_value("TOKEN", token); + if (token) { + ofstream token_file; + ostringstream oss; + + string* encrypted; + string tk_error; + if (token_password.empty()) { + tk_error = "CONTEXT/TOKEN set, but TOKEN_PASSWORD is not defined" + " in the user template."; + file.close(); - string err = "CONTEXT/TOKEN set, but TOKEN_PASSWORD is not defined in the user template."; + + log("VM", Log::ERROR, tk_error.c_str()); + set_template_error_message(tk_error); - log("VM", Log::ERROR, err.c_str()); - set_template_error_message(err); return -1; } @@ -2468,26 +2478,31 @@ int VirtualMachine::generate_context(string &files, int &disk_id, string& token_ // We store this original owner in case a chown operation is performed. add_template_attribute("CREATED_BY", uid); - ofstream token_file; - ostringstream oss; - string token_path; + token_file.open(history->token_file.c_str(), ios::out); - oss << Nebula::instance().get_vms_location() << oid << "/token.txt"; - token_path = oss.str(); - - token_file.open(token_path.c_str(),ios::out); - - if (!token_file.fail()) + if (token_file.fail()) { - oss.str(""); - oss << oid << ':' << stime; + tk_error = "Cannot create token file"; - token_file << one_util::aes256cbc_encrypt(oss.str(), token_password) << endl; + file.close(); - token_file.close(); + log("VM", Log::ERROR, tk_error.c_str()); + set_template_error_message(tk_error); - files += (" " + token_path); + return -1; } + + oss << oid << ':' << stime; + + encrypted = one_util::aes256cbc_encrypt(oss.str(), token_password); + + token_file << *encrypted << endl; + + token_file.close(); + + delete encrypted; + + files += (" " + history->token_file); } const map values = context->value();