diff --git a/src/server/AuthorizationManager.cpp b/src/server/AuthorizationManager.cpp index 070beb4..fd21cb2 100644 --- a/src/server/AuthorizationManager.cpp +++ b/src/server/AuthorizationManager.cpp @@ -90,8 +90,7 @@ bool AuthorizationManager::RevokeCertificate(QString token, QString key, QString return true; } -QJsonObject AuthorizationManager::ListCertificates(QString token){ - QJsonObject obj; +void AuthorizationManager::ListCertificates(QString token, QJsonObject *out){ QStringList keys; //Format: "RegisteredCerts//" if( hasFullAccess(token) ){ //Read all user's certs @@ -106,14 +105,12 @@ QJsonObject AuthorizationManager::ListCertificates(QString token){ QJsonObject user; QString username; for(int i=0; iinsert(username, user); user = QJsonObject(); } //save the current info to the output username = keys[i].section("/",1,1); //save the new username for later } user.insert(keys[i].section("/",2,3000), CONFIG->value(keys[i]).toString() ); //just in case the key has additional "/" in it } - if(!user.isEmpty() && !username.isEmpty()){ obj.insert(username, user); } - - return obj; + if(!user.isEmpty() && !username.isEmpty()){ out->insert(username, user); } } //Generic functions diff --git a/src/server/AuthorizationManager.h b/src/server/AuthorizationManager.h index db96752..5242b4b 100644 --- a/src/server/AuthorizationManager.h +++ b/src/server/AuthorizationManager.h @@ -19,10 +19,10 @@ public: bool checkAuth(QString token); //see if the given token is valid bool hasFullAccess(QString token); //see if the token is associated with a full-access account - //SSL Certificate register/revoke/list + //SSL Certificate register/revoke/list (should only run if the current token is valid) bool RegisterCertificate(QString token, QSslCertificate cert); //if token is valid, register the given cert for future logins bool 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 - QJsonObject ListCertificates(QString token); + void ListCertificates(QString token, QJsonObject *out); int checkAuthTimeoutSecs(QString token); //Return the number of seconds that a token is valid for diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index fced59c..494aeca 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -31,7 +31,9 @@ RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(bool allaccess, QJsonO : , } */ - + // - server settings (always available) + out->insert("sysadm/settings","read/write"); + // - syscache if(QFile::exists("/var/run/syscache.pipe")){ out->insert("rpc/syscache","read"); //no write to syscache - only reads @@ -95,7 +97,9 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(const RestInputStru } //Go through and forward this request to the appropriate sub-system - if(namesp=="rpc" && name=="dispatcher"){ + if(namesp=="sysadm" && name=="settings"){ + return EvaluateSysadmSettingsRequest(IN.args, out); + }else if(namesp=="rpc" && name=="dispatcher"){ return EvaluateDispatcherRequest(IN.fullaccess, IN.args, out); }else if(namesp=="sysadm" && name=="beadm"){ return EvaluateSysadmBEADMRequest(IN.args, out); @@ -119,6 +123,40 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(const RestInputStru } +// === SYSADM SETTINGS === +RestOutputStruct::ExitCode WebSocket::EvaluateSysadmSettingsRequest(const QJsonValue in_args, QJsonObject *out){ + if(!in_args.isObject()){ return RestOutputStruct::BADREQUEST; } + QJsonObject argsO = in_args.toObject(); + QStringList keys = argsO.keys(); + if(!keys.contains("action")){ return RestOutputStruct::BADREQUEST; } + QString act = argsO.value("action").toString(); + bool ok = false; + if(act=="register_ssl_cert" && keys.contains("pub_key")){ + //Additional arguments: "pub_key" (String), and the cert with that key must already be loaded into the connection + QString pub_key = argsO.value("pub_key").toString();\ + //Now find the currently-loaded certificate with the given public key + QList certs; + if(SOCKET!=0){ certs = SOCKET->sslConfiguration().peerCertificateChain(); } + else if(TSOCKET!=0){ certs = TSOCKET->peerCertificateChain(); } + for(int i=0; iRegisterCertificate(SockAuthToken, certs[i]); + } + } + }else if(act=="list_ssl_certs"){ + AUTHSYSTEM->ListCertificates(SockAuthToken, out); + ok = true; //always works for current user (even if nothing found) + }else if(act=="revoke_ssl_cert" && keys.contains("pub_key") ){ + //Additional arguments: "user" (optional), "pub_key" (String) + QString user; if(keys.contains("user")){ user = argsO.value("user").toString(); } + ok = AUTHSYSTEM->RevokeCertificate(SockAuthToken,argsO.value("pub_key").toString(), user); + } + + if(ok){ return RestOutputStruct::OK; } + else{ return RestOutputStruct::BADREQUEST; } +} + //==== SYSCACHE ==== RestOutputStruct::ExitCode WebSocket::EvaluateSyscacheRequest(const QJsonValue in_args, QJsonObject *out){ //syscache only needs a list of sub-commands at the moment (might change later) diff --git a/src/server/WebSocket.h b/src/server/WebSocket.h index 4547a69..b30d837 100644 --- a/src/server/WebSocket.h +++ b/src/server/WebSocket.h @@ -43,8 +43,14 @@ private: RestOutputStruct::ExitCode AvailableSubsystems(bool fullaccess, QJsonObject *out); // -- Main subsystem parser RestOutputStruct::ExitCode EvaluateBackendRequest(const RestInputStruct&, QJsonObject *out); + + // -- Individual subsystems + // -- Server Settings Modification API + RestOutputStruct::ExitCode EvaluateSysadmSettingsRequest(const QJsonValue in_args, QJsonObject *out); + // -- rpc syscache API RestOutputStruct::ExitCode EvaluateSyscacheRequest(const QJsonValue in_args, QJsonObject *out); + // -- rpc dispatcher API RestOutputStruct::ExitCode EvaluateDispatcherRequest(bool allaccess, const QJsonValue in_args, QJsonObject *out); // -- sysadm beadm API RestOutputStruct::ExitCode EvaluateSysadmBEADMRequest(const QJsonValue in_args, QJsonObject *out);