static void copyFromUtf8(Array& arr, uint8_t const* data) { if (data) { size_t user_len = UTF8Len(data); arr.init(user_len * 2); UTF8toUTF16({data, strlen(char_ptr_cast(data))}, arr.get_data(), user_len * 2); } else { arr.init(0); } }
void set_server_redirection_target(Inifile& ini, ReportMessageApi& reporter) { // SET new target in ini RedirectionInfo const& redir_info = ini.get<cfg::mod_rdp::redir_info>(); const char * host = char_ptr_cast(redir_info.host); const char * password = char_ptr_cast(redir_info.password); const char * username = char_ptr_cast(redir_info.username); const char * change_user = ""; if (redir_info.dont_store_username && username[0] != 0) { LOG(LOG_INFO, "SrvRedir: Change target username to '%s'", username); ini.set_acl<cfg::globals::target_user>(username); change_user = username; } if (password[0] != 0) { LOG(LOG_INFO, "SrvRedir: Change target password"); ini.set_acl<cfg::context::target_password>(password); } LOG(LOG_INFO, "SrvRedir: Change target host to '%s'", host); ini.set_acl<cfg::context::target_host>(host); char message[770]; sprintf(message, "%s@%s", change_user, host); reporter.report("SERVER_REDIRECTION", message); }
void SetKrbAuthIdentity(const uint8_t * user, const uint8_t * pass) { auto copy = [](char (&arr)[256], uint8_t const* data){ if (data) { const char * p = char_ptr_cast(data); const size_t length = p ? strnlen(p, 255) : 0; memcpy(arr, data, length); arr[length] = 0; } }; copy(this->princname, user); copy(this->princpass, pass); }
// Called on the worker thread. bool BackgroundFileSaver::CheckCompletion() { nsresult rv; MOZ_ASSERT(!mAsyncCopyContext, "Should not be copying when checking completion conditions."); bool failed = true; { MutexAutoLock lock(mLock); if (mComplete) { return true; } // If an error occurred, we don't need to do the checks in this code block, // and the operation can be completed immediately with a failure code. if (NS_SUCCEEDED(mStatus)) { failed = false; // We did not incur in an error, so we must determine if we can stop now. // If the Finish method has not been called, we can just continue now. if (!mFinishRequested) { return false; } // We can only stop when all the operations requested by the control // thread have been processed. First, we check whether we have processed // the first SetTarget call, if any. Then, we check whether we have // processed any rename requested by subsequent SetTarget calls. if ((mInitialTarget && !mActualTarget) || (mRenamedTarget && mRenamedTarget != mActualTarget)) { return false; } // If we still have data to write to the output file, allow the copy // operation to resume. The Available getter may return an error if one // of the pipe's streams has been already closed. uint64_t available; rv = mPipeInputStream->Available(&available); if (NS_SUCCEEDED(rv) && available != 0) { return false; } } mComplete = true; } // Ensure we notify completion now that the operation finished. // Do a best-effort attempt to remove the file if required. if (failed && mActualTarget && !mActualTargetKeepPartial) { (void)mActualTarget->Remove(false); } // Finish computing the hash if (!failed && mDigestContext) { nsNSSShutDownPreventionLock lock; if (!isAlreadyShutDown()) { Digest d; rv = d.End(SEC_OID_SHA256, mDigestContext); if (NS_SUCCEEDED(rv)) { MutexAutoLock lock(mLock); mSha256 = nsDependentCSubstring(char_ptr_cast(d.get().data), d.get().len); } } } // Compute the signature of the binary. ExtractSignatureInfo doesn't do // anything on non-Windows platforms except return an empty nsIArray. if (!failed && mActualTarget) { nsString filePath; mActualTarget->GetTarget(filePath); nsresult rv = ExtractSignatureInfo(filePath); if (NS_FAILED(rv)) { LOG(("Unable to extract signature information [this = %p].", this)); } else { LOG(("Signature extraction success! [this = %p]", this)); } } // Post an event to notify that the operation completed. if (NS_FAILED(mControlThread->Dispatch(NewRunnableMethod(this, &BackgroundFileSaver::NotifySaveComplete), NS_DISPATCH_NORMAL))) { NS_WARNING("Unable to post completion event to the control thread."); } return true; }
bool check(MMApi & mm, time_t now, BackEvent_t & signal) { //LOG(LOG_INFO, "================> ACL check: now=%u, signal=%u", // (unsigned)now, static_cast<unsigned>(signal)); if (signal == BACK_EVENT_STOP) { // here, mm.last_module should be false only when we are in login box mm.mod->get_event().reset(); return false; } if (mm.last_module) { // at a close box (mm.last_module is true), // we are only waiting for a stop signal // and Authentifier should not exist anymore. return true; } const uint32_t enddate = this->ini.get<cfg::context::end_date_cnx>(); if (enddate != 0 && (static_cast<uint32_t>(now) > enddate)) { LOG(LOG_INFO, "Session is out of allowed timeframe : closing"); const char * message = TR("session_out_time", language(this->ini)); mm.invoke_close_box(message, signal, now); return true; } // Close by rejeted message received if (!this->ini.get<cfg::context::rejected>().empty()) { this->ini.set<cfg::context::auth_error_message>(this->ini.get<cfg::context::rejected>()); LOG(LOG_INFO, "Close by Rejected message received : %s", this->ini.get<cfg::context::rejected>().c_str()); this->ini.set_acl<cfg::context::rejected>(""); mm.invoke_close_box(nullptr, signal, now); return true; } // Keep Alive if (this->keepalive.check(now, this->ini)) { mm.invoke_close_box(TR("miss_keepalive", language(this->ini)), signal, now); return true; } // Inactivity management if (this->inactivity.check(now)) { mm.invoke_close_box(TR("close_inactivity", language(this->ini)), signal, now); return true; } // Manage module (refresh or next) if (this->ini.changed_field_size()) { if (mm.connected) { // send message to acl with changed values when connected to // a module (rdp, vnc, xup ...) and something changed. // used for authchannel and keepalive. this->ask_acl(); } else if (signal == BACK_EVENT_REFRESH || signal == BACK_EVENT_NEXT) { this->remote_answer = false; this->ask_acl(); } } else if (this->remote_answer || (signal == BACK_EVENT_RETRY_CURRENT)) { this->remote_answer = false; if (signal == BACK_EVENT_REFRESH) { LOG(LOG_INFO, "===========> MODULE_REFRESH"); signal = BACK_EVENT_NONE; // TODO signal management (refresh/next) should go to ModuleManager, it's basically the same behavior. It could be implemented by closing module then opening another one of the same kind mm.mod->refresh_context(this->ini); mm.mod->get_event().signal = BACK_EVENT_NONE; mm.mod->get_event().set(); } else if ((signal == BACK_EVENT_NEXT) || (signal == BACK_EVENT_RETRY_CURRENT)) { if (signal == BACK_EVENT_NEXT) { LOG(LOG_INFO, "===========> MODULE_NEXT"); } else { REDASSERT(signal == BACK_EVENT_RETRY_CURRENT); LOG(LOG_INFO, "===========> MODULE_RETRY_CURRENT"); } int next_state = ((signal == BACK_EVENT_NEXT) ? mm.next_module() : MODULE_RDP); if (next_state == MODULE_TRANSITORY) { this->remote_answer = false; return true; } signal = BACK_EVENT_NONE; if (next_state == MODULE_INTERNAL_CLOSE) { mm.invoke_close_box(nullptr, signal, now); return true; } if (next_state == MODULE_INTERNAL_CLOSE_BACK) { this->keepalive.stop(); } mm.remove_mod(); try { mm.new_mod(next_state, now, this); } catch (Error & e) { if (e.id == ERR_SOCKET_CONNECT_FAILED) { this->ini.set_acl<cfg::context::module>(STRMODULE_TRANSITORY); signal = BACK_EVENT_NEXT; this->remote_answer = false; this->report("CONNECTION_FAILED", "Failed to connect to remote TCP host."); return true; } else if (e.id == ERR_RDP_SERVER_REDIR) { // SET new target in ini const char * host = char_ptr_cast( this->ini.get<cfg::mod_rdp::redir_info>().host); const char * password = char_ptr_cast( this->ini.get<cfg::mod_rdp::redir_info>().password); const char * username = char_ptr_cast( this->ini.get<cfg::mod_rdp::redir_info>().username); const char * change_user = ""; if (this->ini.get<cfg::mod_rdp::redir_info>().dont_store_username && (username[0] != 0)) { LOG(LOG_INFO, "SrvRedir: Change target username to '%s'", username); this->ini.set_acl<cfg::globals::target_user>(username); change_user = username; } if (password[0] != 0) { LOG(LOG_INFO, "SrvRedir: Change target password"); this->ini.set_acl<cfg::context::target_password>(password); } LOG(LOG_INFO, "SrvRedir: Change target host to '%s'", host); this->ini.set_acl<cfg::context::target_host>(host); char message[768] = {}; sprintf(message, "%s@%s", change_user, host); this->report("SERVER_REDIRECTION", message); this->remote_answer = true; signal = BACK_EVENT_NEXT; return true; } else { throw; } } if (!this->keepalive.is_started() && mm.connected) { this->keepalive.start(now); } } else { if (!this->ini.get<cfg::context::disconnect_reason>().empty()) { this->ini.set<cfg::context::manager_disconnect_reason>( this->ini.get<cfg::context::disconnect_reason>().c_str()); this->ini.get_ref<cfg::context::disconnect_reason>().clear(); this->ini.set_acl<cfg::context::disconnect_reason_ack>(true); } } } // LOG(LOG_INFO, "connect=%s ini.check=%s", this->connected?"Y":"N", this->ini.check()?"Y":"N"); // AuthCHANNEL CHECK // if an answer has been received, send it to // rdp serveur via mod (should be rdp module) // TODO Check if this->mod is RDP MODULE if (mm.connected && this->ini.get<cfg::mod_rdp::auth_channel>()[0]) { // Get sesman answer to AUTHCHANNEL_TARGET if (!this->ini.get<cfg::context::auth_channel_answer>().empty()) { // If set, transmit to auth_channel channel mm.mod->send_auth_channel_data(this->ini.get<cfg::context::auth_channel_answer>().c_str()); // Erase the context variable this->ini.get_ref<cfg::context::auth_channel_answer>().clear(); } } return true; }
// Called on the worker thread. bool BackgroundFileSaver::CheckCompletion() { nsresult rv; MOZ_ASSERT(!mAsyncCopyContext, "Should not be copying when checking completion conditions."); bool failed = true; { MutexAutoLock lock(mLock); if (mComplete) { return true; } // If an error occurred, we don't need to do the checks in this code block, // and the operation can be completed immediately with a failure code. if (NS_SUCCEEDED(mStatus)) { failed = false; // On success, if there is a pending rename operation, we must process it // before finishing. Otherwise, we can finish now if requested. if ((mAssignedTarget && mAssignedTarget != mActualTarget) || !mFinishRequested) { return false; } // If completion was requested, but we still have data to write to the // output file, allow the copy operation to resume. The Available getter // may return an error if one of the pipe's streams has been already closed. uint64_t available; rv = mPipeInputStream->Available(&available); if (NS_SUCCEEDED(rv) && available != 0) { return false; } } mComplete = true; } // Ensure we notify completion now that the operation finished. // Do a best-effort attempt to remove the file if required. if (failed && mActualTarget && !mActualTargetKeepPartial) { (void)mActualTarget->Remove(false); } // Finish computing the hash if (!failed && mDigestContext) { nsNSSShutDownPreventionLock lock; if (!isAlreadyShutDown()) { Digest d; rv = d.End(SEC_OID_SHA256, mDigestContext); if (NS_SUCCEEDED(rv)) { MutexAutoLock lock(mLock); mSha256 = nsDependentCSubstring(char_ptr_cast(d.get().data), d.get().len); } } } // Post an event to notify that the operation completed. nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &BackgroundFileSaver::NotifySaveComplete); if (!event || NS_FAILED(mControlThread->Dispatch(event, NS_DISPATCH_NORMAL))) { NS_WARNING("Unable to post completion event to the control thread."); } return true; }