protected virtual void CheckPermissions(RPCRequestInfo ri, ActionInvokeDetails d) { string[] demand = d.PermissionDemand; if (info.Sector == "main" && (ri.ActionInfo.Flags & RPCActionFlags.NoAuth) == 0) { // non-noauth actions in the main sector get permission demands from DB demand = Ticket.GetActionPrivilegeDemand (ri.ActionInfo.Name); if (demand == null) throw new RPCException ("authz", "action not configured: {0}", ri.ActionInfo.Name); } ri.EffectiveTicket = Ticket.Verify (ri.RequestHeader ["ticket"].AsString (null)); if (demand != null) { if (ri.EffectiveTicket == null) throw new RPCException ("authn", "valid authn ticket required for accessing core services"); foreach (string p in demand) if (!ri.EffectiveTicket.HasPrivilege (p)) throw new RPCException ("authz", "access denied: need priv {0} for {1}", p, ri.ActionInfo.Name); } ri.TerminalToken = ri.RequestHeader ["terminal"].AsString (null); ri.RealTicket = Ticket.Verify (ri.RequestHeader ["identifying_token"].AsString (null)) ?? ri.EffectiveTicket; uint cid; if (ri.RealTicket != null && ri.RealTicket.ClientID != 0) { ri.ClientID = ri.RealTicket.ClientID; } else if ((cid = (uint)ri.RequestHeader["client_id"].AsNumber(0)) != 0) { ri.ClientID = cid; } }
protected virtual void Execute(RPCRequestInfo ri) { if (ri.RequestError != null) { throw new RPCException("transport", "Failed to receive request body: {0}", ri.RequestError); } string q = info.Sector + ':' + ri.RequestHeader["action"].AsString("") + '~' + ri.RequestHeader["version"].AsString("1"); ActionName acname; ActionName.TryParse(q, out acname); if (acname == null) { throw new RPCException("transport", "No valid action name in request"); } ActionInfo ai = info.LookupAction(acname); if (ai == null || ai.Name != acname) { throw new RPCException("transport", "No such action"); } ri.ActionInfo = ai; ActionInvokeDetails d = (ActionInvokeDetails)ai.Handler; JObject reqData = null; try { reqData = JSON.Parse(Encoding.UTF8.GetString(ri.RequestData, 0, ri.RequestDataLength)).AsObject(); } catch (Exception) { } if (reqData == null) { throw new RPCException("transport", "Failed to parse JSON request body"); } CheckPermissions(ri, d); Logger.LogInfo("Request {0}", ri.ActionInfo); JObject resData = d.Handler(ri, reqData); ri.ResponseData = Encoding.UTF8.GetBytes(JSON.Stringify(resData)); }
protected virtual void CheckPermissions(RPCRequestInfo ri, ActionInvokeDetails d) { string[] demand = d.PermissionDemand; if (info.Sector == "main" && (ri.ActionInfo.Flags & RPCActionFlags.NoAuth) == 0) { // non-noauth actions in the main sector get permission demands from DB demand = Ticket.GetActionPrivilegeDemand(ri.ActionInfo.Name); if (demand == null) { throw new RPCException("authz", "action not configured: {0}", ri.ActionInfo.Name); } } ri.EffectiveTicket = Ticket.Verify(ri.RequestHeader ["ticket"].AsString(null)); if (demand != null) { if (ri.EffectiveTicket == null) { throw new RPCException("authn", "valid authn ticket required for accessing core services"); } foreach (string p in demand) { if (!ri.EffectiveTicket.HasPrivilege(p)) { throw new RPCException("authz", "access denied: need priv {0} for {1}", p, ri.ActionInfo.Name); } } } ri.TerminalToken = ri.RequestHeader ["terminal"].AsString(null); ri.RealTicket = Ticket.Verify(ri.RequestHeader ["identifying_token"].AsString(null)) ?? ri.EffectiveTicket; uint cid; if (ri.RealTicket != null && ri.RealTicket.ClientID != 0) { ri.ClientID = ri.RealTicket.ClientID; } else if ((cid = (uint)ri.RequestHeader["client_id"].AsNumber(0)) != 0) { ri.ClientID = cid; } }
protected virtual void ScanType(List <ActionInfo> ail, Type type, List <Attribute> typePriv, string sector, string nspace, uint version) { foreach (var m in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { var action_meta = (RPCAttribute)Attribute.GetCustomAttribute(m, typeof(RPCAttribute)); if (action_meta == null) { continue; } var action_priv = new List <Attribute> (Attribute.GetCustomAttributes(m, typeof(RPCPrivilegeRequiredAttribute))); action_priv.AddRange(typePriv); List <string> privs = new List <string> (); foreach (var pra in action_priv) { privs.Add((pra as RPCPrivilegeRequiredAttribute).Privilege); } uint ver = action_meta.Version != 0 ? action_meta.Version : version; ActionName an = new ActionName(sector, nspace, action_meta.Name ?? m.Name, ver); ActionInvokeDetails d = new ActionInvokeDetails { PermissionDemand = privs.Count == 0 ? null : privs.ToArray(), }; var dg = (Func <RPCRequestInfo, JObject, JObject>) Delegate.CreateDelegate(typeof(Func <RPCRequestInfo, JObject, JObject>), m, false); if (dg != null) { d.Handler = dg; } else { throw new Exception(string.Format("Method {0}.{1} is marked as an RPC but does not have the correct signature", type, m)); } ail.Add(new ActionInfo(an, action_meta.Flags, action_meta.Timeout != 0 ? action_meta.Timeout : ActionInfo.DEFAULT_TIMEOUT, d)); } }
protected virtual void ScanType(List<ActionInfo> ail, Type type, List<Attribute> typePriv, string sector, string nspace, uint version) { foreach (var m in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) { var action_meta = (RPCAttribute)Attribute.GetCustomAttribute (m, typeof(RPCAttribute)); if (action_meta == null) continue; var action_priv = new List<Attribute> (Attribute.GetCustomAttributes (m, typeof(RPCPrivilegeRequiredAttribute))); action_priv.AddRange (typePriv); List<string> privs = new List<string> (); foreach (var pra in action_priv) privs.Add ((pra as RPCPrivilegeRequiredAttribute).Privilege); uint ver = action_meta.Version != 0 ? action_meta.Version : version; ActionName an = new ActionName (sector, nspace, action_meta.Name ?? m.Name, ver); ActionInvokeDetails d = new ActionInvokeDetails { PermissionDemand = privs.Count == 0 ? null : privs.ToArray (), }; var dg = (Func<RPCRequestInfo, JObject, JObject>) Delegate.CreateDelegate (typeof(Func<RPCRequestInfo, JObject, JObject>), m, false); if (dg != null) { d.Handler = dg; } else { throw new Exception (string.Format ("Method {0}.{1} is marked as an RPC but does not have the correct signature", type, m)); } ail.Add (new ActionInfo (an, action_meta.Flags, action_meta.Timeout != 0 ? action_meta.Timeout : ActionInfo.DEFAULT_TIMEOUT, d)); } }