mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
Allow registration of GAM names
This allows `app-loader' to register new names (which are then used by the loaded apps to claim tokens). At the moment this is restricted to apps that are pre-registered, i.e. included in the image.
This commit is contained in:
parent
9eeed0d284
commit
1e645a4b94
7 changed files with 58 additions and 21 deletions
|
|
@ -51,7 +51,7 @@ fn main() -> ! {
|
|||
let mut apps = Vec::new();
|
||||
|
||||
// start off by adding hello world
|
||||
let buf = Buffer::into_buf(LoadAppRequest { name: xous_ipc::String::from_str("hello") }).expect("Couldn't create buffer");
|
||||
let buf = Buffer::into_buf(LoadAppRequest { name: xous_ipc::String::from_str("Hello") }).expect("Couldn't create buffer");
|
||||
buf.send(self_conn,
|
||||
Opcode::LoadApp.to_u32().unwrap()).expect("Couldn't send message");
|
||||
|
||||
|
|
@ -76,6 +76,9 @@ fn main() -> ! {
|
|||
.unwrap();
|
||||
log::info!("Result of ping: {:?}", result);
|
||||
|
||||
// add its name to GAM
|
||||
gam.register_name(load_app_req.name.to_str(), auth).expect("Couldn't register name");
|
||||
|
||||
// load the app from the binary file
|
||||
let bin = include_bytes!("../../../target/riscv32imac-unknown-xous-elf/debug/hello");
|
||||
let bin_len = bin.len();
|
||||
|
|
|
|||
|
|
@ -52,4 +52,3 @@ tts = []
|
|||
# default = ["debugprint"] # "debugprint"
|
||||
default = []
|
||||
ditherpunk = []
|
||||
app_loader = []
|
||||
|
|
@ -110,6 +110,11 @@ pub struct UxRegistration {
|
|||
/// If the LayoutType is not an App, this field is ignored and does nothing
|
||||
pub focuschange_id: Option<u32>,
|
||||
}
|
||||
#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Copy, Clone)]
|
||||
pub struct NameRegistration {
|
||||
pub name: String::<128>,
|
||||
pub auth_token: [u32; 4],
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, num_derive::FromPrimitive, num_derive::ToPrimitive)]
|
||||
|
|
@ -211,6 +216,9 @@ pub(crate) enum Opcode {
|
|||
/// Allow main menu activation. Used by the PDDB to turn ungate the main menu once it is mounted.
|
||||
/// This resolves race conditions that depend upon the PDDB configurations.
|
||||
AllowMainMenu = 33,
|
||||
|
||||
/// Register a name that can aquire a token. This is only intended to be used with pre-registered apps
|
||||
RegisterName = 34,
|
||||
}
|
||||
|
||||
// small wart -- we have to reset the size of a modal to max size for resize computations
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ impl ContextManager {
|
|||
pub(crate) fn claim_token(&mut self, name: &str) -> Option<[u32; 4]> {
|
||||
self.tm.claim_token(name)
|
||||
}
|
||||
pub(crate) fn register_name(&mut self, name: &str, auth_token: &[u32; 4]) {
|
||||
self.tm.register_name(name, auth_token);
|
||||
}
|
||||
pub(crate) fn allow_untrusted_code(&self) -> bool {
|
||||
self.tm.allow_untrusted_code()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -309,6 +309,15 @@ impl Gam {
|
|||
|
||||
Ok(returned_claim.token)
|
||||
}
|
||||
pub fn register_name(&self, name: &str, auth_token: [u32; 4]) -> Result<(), xous::Error> {
|
||||
let name_registration = NameRegistration {
|
||||
name: String::<128>::from_str(name),
|
||||
auth_token
|
||||
};
|
||||
let buf = Buffer::into_buf(name_registration).or(Err(xous::Error::InternalError))?;
|
||||
buf.lend(self.conn, Opcode::RegisterName.to_u32().unwrap()).or(Err(xous::Error::InternalError))?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn set_predictor_api_token(&self, api_token: [u32; 4], gam_token: [u32; 4]) -> Result<(), xous::Error> {
|
||||
let at = ApiToken {
|
||||
gam_token,
|
||||
|
|
|
|||
|
|
@ -668,6 +668,11 @@ fn wrapped_main() -> ! {
|
|||
context_mgr.allow_mainmenu();
|
||||
xous::return_scalar(msg.sender, 0).ok();
|
||||
}
|
||||
Some(Opcode::RegisterName) => {
|
||||
let buffer = unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
|
||||
let registration = buffer.to_original::<NameRegistration, _>().unwrap();
|
||||
context_mgr.register_name(registration.name.to_str(), ®istration.auth_token);
|
||||
}
|
||||
Some(Opcode::Quit) => break,
|
||||
None => {log::error!("unhandled message {:?}", msg);}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#[cfg(not(feature = "app_loader"))]
|
||||
use gam::{EXPECTED_BOOT_CONTEXTS, EXPECTED_APP_CONTEXTS};
|
||||
|
||||
/*
|
||||
|
|
@ -19,21 +18,20 @@ pub(crate) struct NamedToken {
|
|||
}
|
||||
pub(crate) struct TokenManager {
|
||||
tokens: Vec::<NamedToken>,
|
||||
extra_names: Vec<String>,
|
||||
trng: trng::Trng,
|
||||
}
|
||||
impl<'a> TokenManager {
|
||||
pub(crate) fn new(xns: &xous_names::XousNames) -> TokenManager {
|
||||
TokenManager {
|
||||
tokens: Vec::new(),
|
||||
extra_names: Vec::new(),
|
||||
trng: trng::Trng::new(&xns).unwrap(),
|
||||
}
|
||||
}
|
||||
/// checks to see if all the slots have been occupied. We can't allow untrusted code to run until all slots have checked in
|
||||
pub(crate) fn allow_untrusted_code(&self) -> bool {
|
||||
#[cfg(feature = "app_loader")]
|
||||
return true;
|
||||
#[cfg(not(feature = "app_loader"))]
|
||||
if self.tokens.len() == (EXPECTED_BOOT_CONTEXTS.len() + EXPECTED_APP_CONTEXTS.len()) {
|
||||
if self.tokens.len() == (EXPECTED_BOOT_CONTEXTS.len() + EXPECTED_APP_CONTEXTS.len() + self.extra_names.len()) {
|
||||
true
|
||||
} else {
|
||||
// throw a bone to the dev who has to debug this error. This typically only triggers after a major
|
||||
|
|
@ -47,21 +45,21 @@ impl<'a> TokenManager {
|
|||
}
|
||||
pub(crate) fn claim_token(&mut self, name: &str) -> Option<[u32; 4]> {
|
||||
log::trace!("claiming token {}", name);
|
||||
// first check if the name is valid if the app loader isn't enabled
|
||||
#[cfg(not(feature = "app_loader"))]
|
||||
{
|
||||
let mut found = false;
|
||||
if EXPECTED_BOOT_CONTEXTS.iter().find(|&&context| context == name).is_some() {
|
||||
found = true;
|
||||
}
|
||||
if EXPECTED_APP_CONTEXTS.iter().find(|&&context| context == name).is_some() {
|
||||
found = true;
|
||||
}
|
||||
if !found {
|
||||
log::error!("Server {} is not pre-registered in gam/lib.rs/EXPECTED_BOOT_CONTEXTS or apps.rs/EXPECTED_APP_CONTEXTS. Did you forget to register it?", name);
|
||||
return None
|
||||
}
|
||||
// first check if the name is valid
|
||||
let mut found = false;
|
||||
if EXPECTED_BOOT_CONTEXTS.iter().find(|&&context| context == name).is_some() {
|
||||
found = true;
|
||||
}
|
||||
if EXPECTED_APP_CONTEXTS.iter().find(|&&context| context == name).is_some() {
|
||||
found = true;
|
||||
}
|
||||
if self.extra_names.iter().find(|&context| context == name).is_some() {
|
||||
found = true;
|
||||
}
|
||||
if !found {
|
||||
log::error!("Server {} is not pre-registered in gam/lib.rs/EXPECTED_BOOT_CONTEXTS or apps.rs/EXPECTED_APP_CONTEXTS. Did you forget to register it?", name);
|
||||
return None
|
||||
}
|
||||
// now check if it hasn't already been registered
|
||||
if self.tokens.iter().find(|&namedtoken| namedtoken.name == name).is_some() {
|
||||
log::error!("Attempt to re-register a UX context: {}", name);
|
||||
|
|
@ -97,4 +95,16 @@ impl<'a> TokenManager {
|
|||
}
|
||||
None
|
||||
}
|
||||
/// Register a new name that can then claim a token. Note that only pre-registered applications are allowed to do this.
|
||||
pub(crate) fn register_name(&mut self, name: &str, auth_token: &[u32; 4]) {
|
||||
if let Some(registrant) = self.lookup_name(auth_token) {
|
||||
if EXPECTED_BOOT_CONTEXTS.iter().find(|&&context| context == registrant).is_some() || EXPECTED_APP_CONTEXTS.iter().find(|&&context| context == registrant).is_some() {
|
||||
self.extra_names.push(name.to_string());
|
||||
} else {
|
||||
log::error!("`{}' does not have permission to register a new name because it is not pre-registered", registrant);
|
||||
}
|
||||
} else {
|
||||
log::error!("Token {:?} does not correspond with a name", auth_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue