Skip to content

Commit

Permalink
jsonrpc: add JSONRPC.Authenticate to authenticate JSON-RPC clients
Browse files Browse the repository at this point in the history
  • Loading branch information
Montellese committed Feb 5, 2012
1 parent 7acc086 commit 9ee56e5
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
30 changes: 29 additions & 1 deletion xbmc/interfaces/json-rpc/JSONRPC.cpp
Expand Up @@ -26,7 +26,9 @@
#include "utils/log.h"
#include "utils/Variant.h"
#include <string.h>
#include <math.h>
#include "ServiceDescription.h"
#include "ClientAuthManager.h"

using namespace ANNOUNCEMENT;
using namespace JSONRPC;
Expand Down Expand Up @@ -72,6 +74,29 @@ JSON_STATUS CJSONRPC::Version(const CStdString &method, ITransportLayer *transpo
return OK;
}

JSON_STATUS CJSONRPC::Authenticate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
{
CStdString identification = parameterObject["identification"].asString();
CStdString name = parameterObject["name"].asString();

if (identification.empty() || name.empty())
return InvalidParams;

int permissionFlags = 0;
for (unsigned int index = 0; index < parameterObject["permissions"].size(); index++)
permissionFlags |= StringToPermission(parameterObject["permissions"][index].asString());

client->SetIdentification(identification);
client->SetName(name);

if (CClientAuthManager::Authenticate(client, permissionFlags))
result = "Accepted";
else
result = "Rejected";

return OK;
}

JSON_STATUS CJSONRPC::Permission(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
{
int flags = client->GetPermissionFlags();
Expand Down Expand Up @@ -263,7 +288,10 @@ inline void CJSONRPC::BuildResponse(const CVariant& request, JSON_STATUS code, c
break;
case BadPermission:
response["error"]["code"] = BadPermission;
response["error"]["message"] = "Bad client permission.";
if (result.isNull() || !result.isMember("message"))
response["error"]["message"] = "Bad client permission.";
else
response["error"]["message"] = result["message"];
break;
case FailedToExecute:
response["error"]["code"] = FailedToExecute;
Expand Down
1 change: 1 addition & 0 deletions xbmc/interfaces/json-rpc/JSONRPC.h
Expand Up @@ -65,6 +65,7 @@ namespace JSONRPC

static JSON_STATUS Introspect(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
static JSON_STATUS Version(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
static JSON_STATUS Authenticate(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
static JSON_STATUS Permission(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
static JSON_STATUS Ping(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
static JSON_STATUS GetConfiguration(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result);
Expand Down
14 changes: 12 additions & 2 deletions xbmc/interfaces/json-rpc/JSONServiceDescription.cpp
Expand Up @@ -34,6 +34,7 @@
#include "InputOperations.h"
#include "XBMCOperations.h"
#include "ApplicationOperations.h"
#include "settings/GUISettings.h"

using namespace std;
using namespace JSONRPC;
Expand Down Expand Up @@ -78,6 +79,7 @@ JsonRpcMethodMap CJSONServiceDescription::m_methodMaps[] = {
// JSON-RPC
{ "JSONRPC.Introspect", CJSONRPC::Introspect },
{ "JSONRPC.Version", CJSONRPC::Version },
{ "JSONRPC.Authenticate", CJSONRPC::Authenticate },
{ "JSONRPC.Permission", CJSONRPC::Permission },
{ "JSONRPC.Ping", CJSONRPC::Ping },
{ "JSONRPC.GetConfiguration", CJSONRPC::GetConfiguration },
Expand Down Expand Up @@ -503,7 +505,7 @@ JSON_STATUS CJSONServiceDescription::Print(CVariant &result, ITransportLayer *tr
if (printMetadata)
{
CVariant permissions(CVariant::VariantTypeArray);
for (int i = ReadData; i <= OPERATION_PERMISSION_ALL; i *= 2)
for (int i = PermissionReadData; i <= OPERATION_PERMISSION_ALL; i *= 2)
{
if ((methodIterator->second.permission & i) == i)
permissions.push_back(PermissionToString((OperationPermission)i));
Expand Down Expand Up @@ -544,7 +546,10 @@ JSON_STATUS CJSONServiceDescription::CheckCall(const char* const method, const C
{
if (transport != NULL && (transport->GetCapabilities() & iter->second.transportneed) == iter->second.transportneed)
{
if (client != NULL && (client->GetPermissionFlags() & iter->second.permission) == iter->second.permission && (!notification || (iter->second.permission & OPERATION_PERMISSION_NOTIFICATION) == iter->second.permission))
if (client != NULL &&
(!g_guiSettings.GetBool("services.clientauthentication") || client->IsAuthenticated() || (iter->second.permission & OPERATION_PERMISSION_UNAUTHENTICATED) != PermissionNone) &&
(client->GetPermissionFlags() & iter->second.permission) == iter->second.permission &&
(!notification || (iter->second.permission & OPERATION_PERMISSION_NOTIFICATION)))
{
methodCall = iter->second.method;

Expand Down Expand Up @@ -578,7 +583,12 @@ JSON_STATUS CJSONServiceDescription::CheckCall(const char* const method, const C
return OK;
}
else
{
if (g_guiSettings.GetBool("services.clientauthentication") && !client->IsAuthenticated() && (iter->second.permission & OPERATION_PERMISSION_UNAUTHENTICATED) == PermissionNone)
outputParameters["message"] = "Not authenticated";

return BadPermission;
}
}
}

Expand Down
19 changes: 19 additions & 0 deletions xbmc/interfaces/json-rpc/ServiceDescription.h
Expand Up @@ -803,6 +803,25 @@ namespace JSONRPC
"\"params\": [],"
"\"returns\": \"string\""
"}",
"\"JSONRPC.Authenticate\": {"
"\"type\": \"method\","
"\"description\": \"Authenticates a client\","
"\"transport\": \"Response\","
"\"permission\": \"Authentication\","
"\"statechanging\": false,"
"\"params\": ["
"{ \"name\": \"identification\", \"type\": \"string\", \"required\": true },"
"{ \"name\": \"name\", \"type\": \"string\", \"required\": true },"
"{ \"name\": \"permissions\", \"type\": \"array\", \"uniqueItems\": true, \"minItems\": 1, \"required\": true,"
"\"items\": { \"type\": \"string\","
"\"enum\": [ \"ControlPlayback\", \"ControlNotify\","
"\"ControlPower\", \"UpdateData\", \"RemoveData\","
"\"Navigate\", \"WriteFile\" ]"
"}"
"}"
"],"
"\"returns\": { \"type\": \"string\", \"enum\": [ \"Accepted\", \"Rejected\" ] }"
"}",
"\"JSONRPC.Permission\": {"
"\"type\": \"method\","
"\"description\": \"Retrieve the clients permissions\","
Expand Down
19 changes: 19 additions & 0 deletions xbmc/interfaces/json-rpc/methods.json
Expand Up @@ -26,6 +26,25 @@
"params": [],
"returns": "string"
},
"JSONRPC.Authenticate": {
"type": "method",
"description": "Authenticates a client",
"transport": "Response",
"permission": "Authentication",
"statechanging": false,
"params": [
{ "name": "identification", "type": "string", "required": true },
{ "name": "name", "type": "string", "required": true },
{ "name": "permissions", "type": "array", "uniqueItems": true, "minItems": 1, "required": true,
"items": { "type": "string",
"enum": [ "ControlPlayback", "ControlNotify",
"ControlPower", "UpdateData", "RemoveData",
"Navigate", "WriteFile" ]
}
}
],
"returns": { "type": "string", "enum": [ "Accepted", "Rejected" ] }
},
"JSONRPC.Permission": {
"type": "method",
"description": "Retrieve the clients permissions",
Expand Down

0 comments on commit 9ee56e5

Please sign in to comment.