int TStartsReferee::isAbleToStart( TKeyClient& keyClient, bool& afCanStart) { afCanStart = false; THash vHash; int nResult = hashID(keyClient.getInstId(), vHash); if(nResult) { __L_BADH(m_pLog, "Error in hashID", nResult); return nResult; } TCSLockGuard lock(g_csWantToStart); // check for unique bool fIsUnique = false; TCompIdMap::const_iterator iUnique = m_uniqueProcIds.find( keyClient.getInstId().m_processHashSum); if(iUnique != m_uniqueProcIds.end()) { if(!iUnique->second.isEqual(keyClient.getInstId().getComputerId())) { __L_TRK(m_pLog, "Unique application on not valid computer"); return 0; } fIsUnique = true; } // check for error (trying connect with not unique PID) if(isAlreadyStarted(vHash, keyClient) && fIsUnique) { __L_TRK(m_pLog, "Client with same compid is already connected"); return 0; } nResult = keyClient.waitToStart(); if(nResult) { __L_BADH(m_pLog, "Cannot wait to start", nResult); return nResult; } // all is good, add to started table m_connectedClients[vHash] = &keyClient; if(fIsUnique) m_connectedUnique.push_back(vHash); // delete pointer from queue nResult = forgive(keyClient, false); if(nResult) { __L_BADH(m_pLog, "Cannot delete pointer from queue", nResult); return nResult; } afCanStart = true; return 0; }
static RefNode * newCommonRef(JNIEnv *env, jobject ref) { RefNode *node; jint slot; node = createNode(env, ref); /* * Add to reference hashtable */ slot = hashRef(ref); node->nextByRef = objectsByRef[slot]; node->refSlot = slot; objectsByRef[slot] = node; /* * Add to id hashtable */ slot = hashID((jlong)node->seqNum); node->nextByID = objectsByID[slot]; objectsByID[slot] = node; return node; }
// == Token Interaction functions == void AuthorizationManager::clearAuth(QString token){ if(token.isEmpty() || token.length() < TOKENLENGTH){ return; } //not a valid token //clear an authorization token QString id = hashID(token); //qDebug() << "Clear Auth:" << id; if(!id.isEmpty()){ HASH.remove(id); } }
//SSL Certificate register/revoke/list bool AuthorizationManager::RegisterCertificate(QString token, QString pubkey, QString nickname, QString email){ if(!checkAuth(token)){ return false; } QString user = hashID(token).section("::::",2,2); //get the user name from the currently-valid token //NOTE: The public key should be a base64 encoded string CONFIG->setValue("RegisteredCerts/"+user+"/"+pubkey, "Nickname: "+nickname+"\nEmail: "+email+"\nDate Registered: "+QDateTime::currentDateTime().toString(Qt::ISODate) ); return true; }
void AuthorizationManager::ListCertificates(QString token, QJsonObject *out){ QStringList keys; //Format: "RegisteredCerts/<user>/<key>" if( hasFullAccess(token) ){ //Read all user's certs keys = CONFIG->allKeys().filter("RegisteredCerts/"); //qDebug() << "Found SSL Keys to List:" << keys; }else{ //Only list certs for current user QString cuser = hashID(token).section("::::",2,2); keys = CONFIG->allKeys().filter("RegisteredCerts/"+cuser+"/"); //qDebug() << "Found SSL Keys to List:" << keys; } keys.sort(); //Now put the known keys into the output structure arranged by username/key QJsonObject user; QString username; for(int i=0; i<keys.length(); i++){ if(username!=keys[i].section("/",1,1)){ if(!user.isEmpty()){ out->insert(username, user); user = QJsonObject(); } //save the current info to the output username = keys[i].section("/",1,1); //save the new username for later } QString info = CONFIG->value(keys[i]).toString(); QString key = keys[i].section("/",2,-1);//just in case the key has additional "/" in it user.insert(key,info); } if(!user.isEmpty() && !username.isEmpty()){ out->insert(username, user); } }
bool HttpTrans::sendData(const int& pageid, const char* id, const char* url, const char* proxy, const char* data, const bool& post, const char* header, const unsigned int timeout) { //std::unique_lock<std::mutex> lock(lock_); SendParm* parm = new SendParm; parm->id = hashID(pageid, id); parm->sUrl = url; parm->sProxy = proxy ? proxy : ""; parm->sData = data ? data : ""; parm->post = post; parm->header = header ? header : ""; parm->uiTimeout = timeout; parm->chunk = nullptr; parm->rcb = boost::bind(&HttpTrans::recvData, this, _1, _2, _3, _4); std::shared_ptr<send_context_> sp(new send_context_); sp->pageid_ = pageid; sp->req_id_ = id; std::pair<std::map<unsigned int, std::shared_ptr<send_context_>>::iterator, bool> ret; ret = TransMap_.insert(std::make_pair(parm->id, sp)); if ( ret.second ) { HANDLE ht = (HANDLE)_beginthreadex(nullptr, 0, sendDataThread, parm, 0, 0); CloseHandle(ht); } else{ delete parm; } return ret.second; }
int TStartsReferee::forgive( TKeyClient& keyClient, bool afForever) { TCSLockGuard lock(g_csWantToStart); TKeyClient* pFound = NULL; for(TStartQueue::const_iterator i=m_wantToStart.begin(); i != m_wantToStart.end(); ++i) { if(*i == &keyClient) { pFound = *i; m_wantToStart.erase(i); break; } } if(!afForever) return 0; // if found and need to delete if(pFound) { delete pFound; return 0; } THash vHash; int nResult = hashID(keyClient.getInstId(), vHash); if(nResult) { __L_BADH(m_pLog, "Error in hashID", nResult); return nResult; } // find in connected TKeyClientMap::const_iterator iCC = m_connectedClients.find(vHash); if(iCC != m_connectedClients.end()) { delete iCC->second; m_connectedClients.erase(iCC); } // find in unique connected for(TArrayOfHash::const_iterator i=m_connectedUnique.begin(); i != m_connectedUnique.end(); ++i) { if(*i == vHash) { m_connectedUnique.erase(i); break; } } return 0; }
QString AuthorizationManager::userForToken(QString token){ QString id = hashID(token); if(!id.isEmpty()){ return id.section("::::",2,2); }else{ return ""; } }
void HttpTrans::abort(const int& pageid, const char* id) { unsigned int hash = hashID(pageid, id); std::map<unsigned int, std::shared_ptr<send_context_>>::iterator it = TransMap_.find(hash); if (it != TransMap_.end()) { TransMap_.erase(it); } }
bool AuthorizationManager::hasFullAccess(QString token){ bool ok = false; QString id = hashID(token); if(!id.isEmpty()){ //Also verify that the token has not timed out if( HASH[id] > QDateTime::currentDateTime() ){ ok = id.section("::::",1,1)=="operator"; } } return ok; }
bool AuthorizationManager::checkAuth(QString token){ //see if the given token is valid bool ok = false; QString id = hashID(token); if(!id.isEmpty()){ //Also verify that the token has not timed out ok = (HASH[id] > QDateTime::currentDateTime()); if(ok){ HASH.insert(id, QDateTime::currentDateTime().addSecs(TIMEOUTSECS)); } //valid - bump the timestamp } return ok; }
bool AuthorizationManager::RevokeCertificate(QString token, QString key, QString user){ //user will be the current user if not empty - cannot touch other user's certs without full perms on current session QString cuser = hashID(token).section("::::",2,2); if(user.isEmpty()){ user = cuser; } //only probe current user if(user !=cuser){ //Check permissions for this cross-user action if(!hasFullAccess(token)){ return false; } } //Check that the given cert exists first if( !CONFIG->contains("RegisteredCerts/"+user+"/"+key) ){ return false; } CONFIG->remove("RegisteredCerts/"+user+"/"+key); return true; }
// ========================= // PRIVATE // ========================= QString AuthorizationManager::generateNewToken(bool isOp, QString user){ QString tok; for(int i=0; i<TOKENLENGTH; i++){ tok.append( AUTHCHARS.at( qrand() % AUTHCHARS.length() ) ); } if( !hashID(tok).isEmpty() ){ //Just in case the randomizer came up with something identical - re-run it tok = generateNewToken(isOp, user); }else{ //unique token created - add it to the hash with the current time (+timeout) QString id = tok + "::::"+(isOp ? "operator" : "user")+"::::"+user; //append operator status to auth key HASH.insert(id, QDateTime::currentDateTime().addSecs(TIMEOUTSECS) ); //qDebug() << "Current HASH Contents:" << HASH.keys(); } return tok; }
/* * Returns the node stored in the object hash table for the given object * id. The id should be a value previously returned by * commonRef_refToID. */ static RefNode * findNodeByID(JNIEnv *env, jlong id) { jint slot = hashID(id); RefNode *node = objectsByID[slot]; while (node != NULL) { /* * Use this opportunity to clean up any nodes for weak * references that have been garbage collected. */ if (isSameObject(env, node->ref, NULL)) { jlong collectedID = OBJECT_ID(node); node = node->nextByID; deleteNodeByID(env, collectedID, ALL_REFS); } else if (id == OBJECT_ID(node)) { break; /* found it */ } else { node = node->nextByID; } } return node; }
static void deleteNodeByID(JNIEnv *env, jlong id, jint refCount) { jint slot = hashID(id); RefNode *node = objectsByID[slot]; RefNode *prev = NULL; while (node != NULL) { if (id == OBJECT_ID(node)) { if (refCount != ALL_REFS) { node->count -= refCount; } else { node->count = 0; } if (node->count <= 0) { detachIDNode(env, slot, prev, node); deleteNode(env, node); } break; } prev = node; node = node->nextByID; } }