You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The primary async client. All API methods are async and return MispResult<T>.
use rustmisp::MispClient;#[tokio::main]asyncfnmain() -> rustmisp::MispResult<()>{// Simple constructorlet client = MispClient::new("https://misp.example.com","your-api-key",false,// ssl_verify)?;// Get the base URLprintln!("Connected to {}", client.base_url());Ok(())}
MispClientBuilder
Advanced configuration via the builder pattern.
use rustmisp::MispClientBuilder;use std::time::Duration;let client = MispClientBuilder::new("https://misp.example.com","your-api-key").ssl_verify(false).timeout(Duration::from_secs(120)).proxy("http://proxy.example.com:8080").header("X-Custom-Header","value").build()?;
Method
Description
ssl_verify(bool)
Enable/disable TLS certificate verification
timeout(Duration)
Set request timeout
proxy(impl Into<String>)
Set HTTP proxy URL
header(name, value)
Add a custom header to all requests
build()
Build the MispClient
MispClientBlocking
Synchronous wrapper (requires blocking feature). Same API, no async/.await.
[dependencies]
rustmisp = { version = "0.1", features = ["blocking"] }
// Get MISP versionlet version = client.misp_instance_version().await?;println!("MISP version: {}", version);// Alias for misp_instance_versionlet version = client.version().await?;// Get describe_types from the remote instancelet types = client.describe_types_remote().await?;// Get all server settingslet settings = client.server_settings().await?;// Get a specific settinglet setting = client.get_server_setting("MISP.baseurl").await?;// Set a server setting
client.set_server_setting("MISP.welcome_text_top","Hello").await?;// Check remote ACL (debug)let acl = client.remote_acl(Some("full")).await?;// Database schema diagnosticslet diag = client.db_schema_diagnostic().await?;
use rustmisp::MispAttribute;// List all attributeslet attrs = client.attributes().await?;// Get a single attributelet attr = client.get_attribute(123).await?;// Check if an attribute existslet exists = client.attribute_exists(123).await?;// Add an attribute to an eventlet attr = MispAttribute::new("ip-dst","Network activity","198.51.100.42");let created = client.add_attribute(event_id,&attr).await?;let attr_id = created.id.unwrap();// Update an attributeletmut updated = created;
updated.comment = Some("Updated via RustMISP".to_string());let updated = client.update_attribute(&updated).await?;// Soft-delete an attribute
client.delete_attribute(attr_id,false).await?;// Hard-delete an attribute
client.delete_attribute(attr_id,true).await?;// Restore a soft-deleted attribute
client.restore_attribute(attr_id).await?;// Enrich an attribute using expansion modules
client.enrich_attribute(attr_id,Some(&["dns"])).await?;
use rustmisp::MispTag;// List all tagslet tags = client.tags().await?;// Get a single taglet tag = client.get_tag(1).await?;// Create a tagletmut tag = MispTag::new("RustMISP:test");
tag.colour = Some("#ff0000".to_string());let created = client.add_tag(&tag).await?;let tag_id = created.id.unwrap();// Update a tagletmut updated = created;
updated.colour = Some("#00ff00".to_string());let updated = client.update_tag(&updated).await?;// Enable / disable a tag
client.disable_tag(tag_id).await?;
client.enable_tag(tag_id).await?;// Search tags by namelet results = client.search_tags("tlp:",false).await?;// substring matchlet results = client.search_tags("tlp:white",true).await?;// exact match// Attach a tag to an entity (event, attribute, etc.) by UUID
client.tag("550e8400-e29b-41d4-a716-446655440000","tlp:white",false).await?;// Attach as a local tag (not shared via sync)
client.tag("550e8400-e29b-41d4-a716-446655440000","tlp:white",true).await?;// Remove a tag from an entity
client.untag("550e8400-e29b-41d4-a716-446655440000","tlp:white").await?;// Delete a tag
client.delete_tag(tag_id).await?;
use rustmisp::MispObject;// Get a single objectlet obj = client.get_object(1).await?;// Check if an object existslet exists = client.object_exists(1).await?;// Create an object on an eventletmut obj = MispObject::new("domain-ip");// (Attributes are typically set via the object template)let created = client.add_object(event_id,&obj).await?;let obj_id = created.id.unwrap();// Update an objectletmut updated = created;
updated.comment = Some("Updated via RustMISP".to_string());let updated = client.update_object(&updated).await?;// Soft-delete an object
client.delete_object(obj_id,false).await?;// Hard-delete an object
client.delete_object(obj_id,true).await?;
use rustmisp::MispObjectReference;// Add a reference between two objectslet reference = MispObjectReference::new("550e8400-e29b-41d4-a716-446655440000",// referenced object UUID"related-to",// relationship type);let created = client.add_object_reference(source_object_id,&reference).await?;// Delete a reference
client.delete_object_reference(reference_id).await?;
// List all object templateslet templates = client.object_templates().await?;// Get a specific template by IDlet template = client.get_object_template(1).await?;// Get raw template JSON by UUID or namelet raw = client.get_raw_object_template("domain-ip").await?;// Update all templates from the MISP server
client.update_object_templates().await?;
Method
Signature
Returns
object_templates
() -> MispResult<Vec<MispObjectTemplate>>
All templates
get_object_template
(id: i64) -> MispResult<MispObjectTemplate>
Single template
get_raw_object_template
(uuid_or_name: &str) -> MispResult<Value>
Raw template JSON
update_object_templates
() -> MispResult<Value>
Update confirmation
Attribute Proposals (Shadow Attributes)
Proposals allow suggesting changes to attributes on events you don't own.
use rustmisp::MispShadowAttribute;// List proposals for an eventlet proposals = client.attribute_proposals(event_id).await?;// Get a single proposallet proposal = client.get_attribute_proposal(1).await?;// Propose a new attribute on an eventletmut proposal = MispShadowAttribute::default();
proposal.type_ = Some("ip-dst".to_string());
proposal.value = Some("198.51.100.1".to_string());
proposal.category = Some("Network activity".to_string());let created = client.add_attribute_proposal(event_id,&proposal).await?;// Propose a modification to an existing attributelet modified = client.update_attribute_proposal(attr_id,&proposal).await?;// Accept a proposal (event owner)
client.accept_attribute_proposal(proposal_id).await?;// Discard a proposal
client.discard_attribute_proposal(proposal_id).await?;// Delete a proposal (proposer only)
client.delete_attribute_proposal(proposal_id).await?;
use rustmisp::MispSighting;// List sightings for an attributelet sightings = client.sightings(attr_id).await?;// Add a sightinglet sighting = MispSighting::default();let created = client.add_sighting(&sighting,Some(attr_id)).await?;// Add a sighting by value (matches any attribute with that value)let sighting = MispSighting::default();let created = client.add_sighting(&sighting,None).await?;// Delete a sighting
client.delete_sighting(sighting_id).await?;
use rustmisp::MispEventReport;// Get a single event reportlet report = client.get_event_report(1).await?;// List all reports for an eventlet reports = client.get_event_reports(event_id).await?;// Create a reportlet report = MispEventReport::new("Incident Summary","# Analysis\n\nDetails here...");let created = client.add_event_report(event_id,&report).await?;let report_id = created.id.unwrap();// Update a reportletmut updated = created;
updated.content = Some("# Updated Analysis\n\nNew details...".to_string());let updated = client.update_event_report(&updated).await?;// Soft-delete a report
client.delete_event_report(report_id,false).await?;// Hard-delete a report
client.delete_event_report(report_id,true).await?;
use rustmisp::MispNote;// Get a notelet note = client.get_note(1).await?;// Add a note to any MISP object (event, attribute, etc.)letmut note = MispNote::new("This IP was seen in previous campaigns");
note.object_uuid = Some("550e8400-e29b-41d4-a716-446655440000".to_string());
note.object_type = Some("Attribute".to_string());let created = client.add_note(¬e).await?;// Update a noteletmut updated = created;
updated.note = "Updated: confirmed in 3 campaigns".to_string();let updated = client.update_note(&updated).await?;// Delete a note
client.delete_note(note_id).await?;
Opinions
use rustmisp::MispOpinion;// Get an opinionlet opinion = client.get_opinion(1).await?;// Add an opinionletmut opinion = MispOpinion::with_comment("Strongly agree with this assessment");
opinion.opinion = Some(100);// 0-100 scale
opinion.object_uuid = Some("550e8400-e29b-41d4-a716-446655440000".to_string());
opinion.object_type = Some("Event".to_string());let created = client.add_opinion(&opinion).await?;// Update an opinionletmut updated = created;
updated.opinion = Some(50);let updated = client.update_opinion(&updated).await?;// Delete an opinion
client.delete_opinion(opinion_id).await?;
Relationships
use rustmisp::MispRelationship;// Get a relationshiplet rel = client.get_relationship(1).await?;// Add a relationship between two objectsletmut rel = MispRelationship::new("related-to");
rel.object_uuid = Some("uuid-source".to_string());
rel.object_type = Some("Attribute".to_string());
rel.related_object_uuid = Some("uuid-target".to_string());
rel.related_object_type = Some("Attribute".to_string());let created = client.add_relationship(&rel).await?;// Update a relationshipletmut updated = created;
updated.relationship_type = "derived-from".to_string();let updated = client.update_relationship(&updated).await?;// Delete a relationship
client.delete_relationship(rel_id).await?;
Generic Analyst Data
use rustmisp::AnalystDataType;// Generic get/add/update/delete for any analyst data typelet data = client.get_analyst_data(AnalystDataType::Note,1).await?;let body = serde_json::json!({"note":"test","object_uuid":"...","object_type":"Event"});
client.add_analyst_data(AnalystDataType::Note,&body).await?;
client.update_analyst_data(AnalystDataType::Note,1,&body).await?;
client.delete_analyst_data(AnalystDataType::Note,1).await?;
// List all taxonomieslet taxonomies = client.taxonomies().await?;// Get a single taxonomy with predicates/entrieslet taxonomy = client.get_taxonomy(1).await?;// Enable a taxonomy
client.enable_taxonomy(1).await?;// Disable a taxonomy
client.disable_taxonomy(1).await?;// Enable all tags for a taxonomy
client.enable_taxonomy_tags(1).await?;// Disable all tags for a taxonomy
client.disable_taxonomy_tags(1).await?;// Set a taxonomy as required (enforced on events)
client.set_taxonomy_required(1,true).await?;
client.set_taxonomy_required(1,false).await?;// Update all taxonomies from the MISP server
client.update_taxonomies().await?;
Method
Signature
Returns
taxonomies
() -> MispResult<Vec<MispTaxonomy>>
All taxonomies
get_taxonomy
(id: i64) -> MispResult<MispTaxonomy>
Single taxonomy
enable_taxonomy
(id: i64) -> MispResult<Value>
Enable confirmation
disable_taxonomy
(id: i64) -> MispResult<Value>
Disable confirmation
enable_taxonomy_tags
(id: i64) -> MispResult<Value>
Enable tags
disable_taxonomy_tags
(id: i64) -> MispResult<Value>
Disable tags
set_taxonomy_required
(id: i64, required: bool) -> MispResult<Value>
Confirmation
update_taxonomies
() -> MispResult<Value>
Update confirmation
Warninglists
// List all warninglistslet warninglists = client.warninglists().await?;// Get a specific warninglistlet wl = client.get_warninglist(1).await?;// Enable a warninglist
client.enable_warninglist(1).await?;// Disable a warninglist
client.disable_warninglist(1).await?;// Toggle warninglists by ID(s) or name(s)
client.toggle_warninglist(Some(&[1,2,3]),// IDsNone,// namestrue,// enabled).await?;// Check if values are in any warninglistlet check = client.values_in_warninglist(&["8.8.8.8","1.1.1.1"]).await?;// Update all warninglists from the MISP server
client.update_warninglists().await?;
// List all noticelistslet noticelists = client.noticelists().await?;// Get a specific noticelistlet nl = client.get_noticelist(1).await?;// Enable a noticelist
client.enable_noticelist(1).await?;// Disable a noticelist
client.disable_noticelist(1).await?;// Update all noticelists from the MISP server
client.update_noticelists().await?;
Method
Signature
Returns
noticelists
() -> MispResult<Vec<MispNoticelist>>
All noticelists
get_noticelist
(id: i64) -> MispResult<MispNoticelist>
Single noticelist
enable_noticelist
(id: i64) -> MispResult<Value>
Enable confirmation
disable_noticelist
(id: i64) -> MispResult<Value>
Disable confirmation
update_noticelists
() -> MispResult<Value>
Update confirmation
Galaxies
// List all galaxies (optionally update first)let galaxies = client.galaxies(false).await?;let galaxies = client.galaxies(true).await?;// update then list// Search galaxies by keywordlet results = client.search_galaxy("mitre-attack").await?;// Get a single galaxy (with or without clusters)let galaxy = client.get_galaxy(1,false).await?;let galaxy = client.get_galaxy(1,true).await?;// include clusters// Search clusters within a specific galaxylet clusters = client.search_galaxy_clusters(1,// galaxy_id"apt",// search termNone,// context (optional)).await?;// Update all galaxies from the MISP server
client.update_galaxies().await?;// Attach a galaxy cluster to an event
client.attach_galaxy_cluster("42","123",false).await?;// Attach a galaxy cluster to an attribute
client.attach_galaxy_cluster_to("42","123","attribute",true).await?;
use rustmisp::MispGalaxyCluster;// Get a single clusterlet cluster = client.get_galaxy_cluster(1).await?;// Add a cluster to a galaxylet cluster = MispGalaxyCluster::new("My Custom Cluster");let created = client.add_galaxy_cluster(galaxy_id,&cluster).await?;// Update a clusterletmut updated = created;
updated.description = Some("Updated description".to_string());let updated = client.update_galaxy_cluster(&updated).await?;// Publish a cluster
client.publish_galaxy_cluster(cluster_id).await?;// Fork a cluster to your own galaxylet forked = client.fork_galaxy_cluster(galaxy_id,&cluster).await?;// Delete a cluster (soft or hard)
client.delete_galaxy_cluster(cluster_id,false).await?;
client.delete_galaxy_cluster(cluster_id,true).await?;
use rustmisp::MispGalaxyClusterRelation;// Add a relation between clusterslet relation = MispGalaxyClusterRelation::new("target-cluster-uuid","similar-to",);let created = client.add_galaxy_cluster_relation(cluster_id,&relation).await?;// Update a relationlet updated = client.update_galaxy_cluster_relation(&created).await?;// Delete a relation
client.delete_galaxy_cluster_relation(relation_id).await?;
// List all decaying modelslet models = client.decaying_models().await?;// Enable a model
client.enable_decaying_model(1).await?;// Disable a model
client.disable_decaying_model(1).await?;// Update all decaying models from the server
client.update_decaying_models().await?;
Method
Signature
Returns
decaying_models
() -> MispResult<Vec<MispDecayingModel>>
All models
enable_decaying_model
(id: i64) -> MispResult<Value>
Enable confirmation
disable_decaying_model
(id: i64) -> MispResult<Value>
Disable confirmation
update_decaying_models
() -> MispResult<Value>
Update confirmation
Correlation Exclusions
Exclude values from the automatic correlation engine.
use rustmisp::MispCorrelationExclusion;// List all exclusionslet exclusions = client.correlation_exclusions().await?;// Get a specific exclusionlet excl = client.get_correlation_exclusion(1).await?;// Add an exclusion (e.g., for a common benign value)let excl = MispCorrelationExclusion::new("8.8.8.8");let created = client.add_correlation_exclusion(&excl).await?;// Delete an exclusion
client.delete_correlation_exclusion(created.id.unwrap()).await?;// Clean all correlation exclusions
client.clean_correlation_exclusions().await?;
use rustmisp::MispUser;// List all users (with optional search)let users = client.users(None,None).await?;let users = client.users(Some("admin"),None).await?;// Get a single userlet user = client.get_user(1).await?;// Create a userletmut user = MispUser::new("analyst@example.com");
user.org_id = Some(1);
user.role_id = Some(3);// Org Admin
user.password = Some("SecurePassword123!".to_string());let created = client.add_user(&user).await?;let user_id = created.id.unwrap();// Update a userletmut updated = created;
updated.disabled = true;let updated = client.update_user(&updated).await?;// Generate a new API auth key for a userlet new_key = client.get_new_authkey(user_id).await?;// Change the current user's password
client.change_user_password("NewSecurePassword456!").await?;// Delete a user
client.delete_user(user_id).await?;
use rustmisp::MispRole;// List all roleslet roles = client.roles().await?;// Create a roleletmut role = MispRole::new("Custom Analyst");
role.perm_add = true;
role.perm_modify = true;
role.perm_modify_org = true;
role.perm_tagger = true;
role.perm_sighting = true;let created = client.add_role(&role).await?;// Update a roleletmut updated = created;
updated.perm_publish = true;let updated = client.update_role(&updated).await?;// Set a role as the default for new users
client.set_default_role(role_id).await?;// Delete a role
client.delete_role(role_id).await?;
Method
Signature
Returns
roles
() -> MispResult<Vec<MispRole>>
All roles
add_role
(role: &MispRole) -> MispResult<MispRole>
Created role
update_role
(role: &MispRole) -> MispResult<MispRole>
Updated role
set_default_role
(id: i64) -> MispResult<Value>
Confirmation
delete_role
(id: i64) -> MispResult<Value>
Deletion confirmation
Servers (Sync)
use rustmisp::MispServer;// List all sync serverslet servers = client.servers().await?;// Get the sync configuration for this instancelet config = client.get_sync_config().await?;// Import a server from sync config JSONlet config_json = serde_json::json!({...});
client.import_server(&config_json).await?;// Add a sync serverletmut server = MispServer::new("https://remote-misp.example.com","Remote MISP");
server.authkey = Some("remote-api-key".to_string());let created = client.add_server(&server).await?;let server_id = created.id.unwrap();// Update a serverletmut updated = created;
updated.push = Some(true);let updated = client.update_server(&updated).await?;// Test server connectivitylet test = client.test_server(server_id).await?;// Pull events from a remote server
client.server_pull(server_id,None).await?;// pull all
client.server_pull(server_id,Some(42)).await?;// pull specific event// Push events to a remote server
client.server_push(server_id,None).await?;// push all
client.server_push(server_id,Some(42)).await?;// push specific event// Delete a server
client.delete_server(server_id).await?;
// Update MISP instance
client.update_misp().await?;// Get worker statuslet workers = client.get_workers().await?;// Restart all workers
client.restart_workers().await?;// Restart only dead workers
client.restart_dead_workers().await?;// Start a specific worker type
client.start_worker("default").await?;// Stop a worker by PID
client.stop_worker_by_pid(12345).await?;// Kill all workers
client.kill_all_workers().await?;
Method
Signature
Returns
update_misp
() -> MispResult<Value>
Update status
get_workers
() -> MispResult<Value>
Worker status
restart_workers
() -> MispResult<Value>
Restart confirmation
restart_dead_workers
() -> MispResult<Value>
Restart confirmation
start_worker
(worker_type: &str) -> MispResult<Value>
Start confirmation
stop_worker_by_pid
(pid: i64) -> MispResult<Value>
Stop confirmation
kill_all_workers
() -> MispResult<Value>
Kill confirmation
Feeds
use rustmisp::MispFeed;// List all feedslet feeds = client.feeds().await?;// Get a specific feedlet feed = client.get_feed(1).await?;// Create a feedlet feed = MispFeed{name:"My Threat Feed".to_string(),url:"https://example.com/feed".to_string(),source_format:Some("freetext".to_string()),provider:Some("Example Provider".to_string()),distribution:Some(0),enabled:false,
..Default::default()};let created = client.add_feed(&feed).await?;let feed_id = created.id.unwrap();// Update a feedletmut updated = created;
updated.name = "Updated Feed Name".to_string();let updated = client.update_feed(&updated).await?;// Enable / disable a feed
client.enable_feed(feed_id).await?;
client.disable_feed(feed_id).await?;// Enable / disable feed caching
client.enable_feed_cache(feed_id).await?;
client.disable_feed_cache(feed_id).await?;// Fetch a feed (download and import data)
client.fetch_feed(feed_id).await?;// Cache operations
client.cache_feed(feed_id).await?;
client.cache_all_feeds().await?;
client.cache_freetext_feeds().await?;
client.cache_misp_feeds().await?;// Compare feedslet comparison = client.compare_feeds().await?;// Load default feeds
client.load_default_feeds().await?;// Delete a feed
client.delete_feed(feed_id).await?;
Method
Signature
Returns
feeds
() -> MispResult<Vec<MispFeed>>
All feeds
get_feed
(id: i64) -> MispResult<MispFeed>
Single feed
add_feed
(feed: &MispFeed) -> MispResult<MispFeed>
Created feed
update_feed
(feed: &MispFeed) -> MispResult<MispFeed>
Updated feed
delete_feed
(id: i64) -> MispResult<Value>
Deletion confirmation
enable_feed
(id: i64) -> MispResult<Value>
Enable confirmation
disable_feed
(id: i64) -> MispResult<Value>
Disable confirmation
enable_feed_cache
(id: i64) -> MispResult<Value>
Enable cache
disable_feed_cache
(id: i64) -> MispResult<Value>
Disable cache
fetch_feed
(id: i64) -> MispResult<Value>
Fetch results
cache_all_feeds
() -> MispResult<Value>
Cache all
cache_feed
(id: i64) -> MispResult<Value>
Cache single feed
cache_freetext_feeds
() -> MispResult<Value>
Cache freetext feeds
cache_misp_feeds
() -> MispResult<Value>
Cache MISP feeds
compare_feeds
() -> MispResult<Value>
Comparison results
load_default_feeds
() -> MispResult<Value>
Load defaults
Sharing Groups
use rustmisp::MispSharingGroup;// List all sharing groupslet groups = client.sharing_groups().await?;// Get a single sharing grouplet sg = client.get_sharing_group(1).await?;// Check if a sharing group existslet exists = client.sharing_group_exists(1).await?;// Create a sharing groupletmut sg = MispSharingGroup::new("Trusted Partners");
sg.description = Some("Sharing group for trusted partners".to_string());
sg.releasability = Some("Partners only".to_string());let created = client.add_sharing_group(&sg).await?;let sg_id = created.id.unwrap();// Update a sharing groupletmut updated = created;
updated.description = Some("Updated description".to_string());let updated = client.update_sharing_group(&updated).await?;// Add an organisation to the sharing group
client.add_org_to_sharing_group(sg_id, org_id).await?;// Remove an organisation from the sharing group
client.remove_org_from_sharing_group(sg_id, org_id).await?;// Add a server to the sharing group
client.add_server_to_sharing_group(sg_id, server_id).await?;// Remove a server from the sharing group
client.remove_server_from_sharing_group(sg_id, server_id).await?;// Delete a sharing group
client.delete_sharing_group(sg_id).await?;
use rustmisp::MispUserSetting;// List all user settingslet settings = client.user_settings().await?;// Get a specific setting (for current user or a specific user)let setting = client.get_user_setting("dashboard",None).await?;let setting = client.get_user_setting("dashboard",Some(42)).await?;// Set a user setting
client.set_user_setting("publish_alert_filter",&serde_json::json!({"tags":["tlp:white"]}),None,// current user).await?;// Set a setting for a specific user (admin only)
client.set_user_setting("dashboard",&serde_json::json!({"widgets":[]}),Some(42),).await?;// Delete a user setting
client.delete_user_setting("publish_alert_filter",None).await?;
let results = client.search_feeds("8.8.8.8").await?;
Freetext Import
Parse a block of text for IOCs and create attributes.
let result = client.freetext(
event_id,"Found indicators: 198.51.100.42, malware.exe, evil@example.com",Some(true),// adhere to warninglistsSome(0),// distributionNone,// sharing_group_id).await?;
Complex Queries
Build AND/OR/NOT queries for tags and values.
use rustmisp::build_complex_query;// ip-src OR ip-dstlet q = build_complex_query(Some(vec!["ip-src","ip-dst"]),None,None);// tag_a AND tag_blet q = build_complex_query(None,Some(vec!["tlp:white","osint"]),None);// tag_a AND NOT tag_blet q = build_complex_query(Some(vec!["tlp:white"]),None,Some(vec!["tlp:red"]));// Use with SearchBuilderlet params = SearchBuilder::new().tags_query(build_complex_query(Some(vec!["tlp:white"]),None,Some(vec!["tlp:red"]),)).build();
Relative timestamp parsing:
use rustmisp::parse_relative_timestamp;let ts = parse_relative_timestamp("5d")?;// 5 days ago as Unix timestamplet ts = parse_relative_timestamp("2h")?;// 2 hours agolet ts = parse_relative_timestamp("30m")?;// 30 minutes ago
use rustmisp::MispEventBlocklist;// List all event blocklistslet blocklists = client.event_blocklists().await?;// Add an event to the blocklistlet entry = client.add_event_blocklist("550e8400-e29b-41d4-a716-446655440000",Some("Spam event"),Some("Blocked by RustMISP"),Some("ACME Corp"),).await?;// Update a blocklist entry
client.update_event_blocklist(
entry_id,Some("Updated comment"),None,).await?;// Delete a blocklist entry
client.delete_event_blocklist(entry_id).await?;
Organisation Blocklists
use rustmisp::MispOrganisationBlocklist;// List all organisation blocklistslet blocklists = client.organisation_blocklists().await?;// Add an organisation to the blocklistlet entry = client.add_organisation_blocklist("org-uuid-here",Some("Known spammer"),Some("Blocked by admin"),Some("Spam Org"),).await?;// Update a blocklist entry
client.update_organisation_blocklist(
entry_id,Some("Updated comment"),None,).await?;// Delete a blocklist entry
client.delete_organisation_blocklist(entry_id).await?;
// List all communitieslet communities = client.communities().await?;// Get a specific communitylet community = client.get_community(1).await?;// Request access to a community
client.request_community_access(1,// community_idNone,// requesting_user_emailNone,// anonymiseNone,// org_nameNone,// org_uuidNone,// org_descriptionSome("Requesting access"),// messageSome(true),// syncNone,// org_typeNone,// mock (test mode)).await?;
// List all event delegationslet delegations = client.event_delegations().await?;// Delegate an event to another organisation
client.delegate_event(
event_id,
org_id,Some(1),// distributionSome("Please review this"),// message).await?;// Accept a delegation
client.accept_event_delegation(delegation_id).await?;// Discard a delegation
client.discard_event_delegation(delegation_id).await?;
// Upload a STIX 1.x file
client.upload_stix(stix_xml_content,1).await?;// Upload a STIX 2.x file
client.upload_stix(stix_json_content,2).await?;// Raw API call to any endpointlet result = client.direct_call("events/view/42",None).await?;// GETlet result = client.direct_call("events/index",Some(&body)).await?;// POST// Push an event to ZMQ
client.push_event_to_zmq(event_id).await?;// Change the sharing group on an entity
client.change_sharing_group_on_entity(
entity_id,"event",// entity_type
sharing_group_id,).await?;// Statisticslet attr_stats = client.attributes_statistics(None,None).await?;let attr_stats = client.attributes_statistics(Some("category"),Some(true)).await?;let tag_stats = client.tags_statistics(None,None).await?;let tag_stats = client.tags_statistics(Some("attribute"),Some(true)).await?;let user_stats = client.users_statistics(None).await?;
use rustmisp::register_user;let result = register_user("https://misp.example.com","newuser@example.com",None,// organisation (UUID or name)None,// org_idNone,// org_nameNone,// messageNone,// custom_permsfalse,// perm_syncfalse,// perm_publishfalse,// perm_adminfalse,// verify_ssl).await?;
register_user_blocking
Same signature, synchronous. Requires blocking feature.
use rustmisp::register_user_blocking;let result = register_user_blocking("https://misp.example.com","newuser@example.com",None,None,None,None,None,false,false,false,false,)?;
Enums
Distribution
use rustmisp::Distribution;Distribution::YourOrganisationOnly// 0Distribution::ThisCommunityOnly// 1Distribution::ConnectedCommunities// 2Distribution::AllCommunities// 3Distribution::SharingGroup// 4Distribution::Inherit// 5
ThreatLevel
use rustmisp::ThreatLevel;ThreatLevel::High// 1ThreatLevel::Medium// 2ThreatLevel::Low// 3ThreatLevel::Undefined// 4
Analysis
use rustmisp::Analysis;Analysis::Initial// 0Analysis::Ongoing// 1Analysis::Complete// 2
SearchController
use rustmisp::SearchController;SearchController::Events// /events/restSearchSearchController::Attributes// /attributes/restSearchSearchController::Objects// /objects/restSearch
ReturnFormat
use rustmisp::ReturnFormat;ReturnFormat::JsonReturnFormat::XmlReturnFormat::CsvReturnFormat::TextReturnFormat::StixReturnFormat::Stix2ReturnFormat::SuricataReturnFormat::SnortReturnFormat::YaraReturnFormat::RpzReturnFormat::OpenIoc
AnalystDataType
use rustmisp::AnalystDataType;AnalystDataType::NoteAnalystDataType::OpinionAnalystDataType::Relationship
Tools
Optional feature-gated modules for working with MISP data offline.
GenericObjectGenerator (tools-file or tools-all)
Build MISP objects programmatically.
use rustmisp::tools::generic_object::GenericObjectGenerator;let obj = GenericObjectGenerator::new("domain-ip").add_attribute("domain","domain","example.com").add_attribute("ip","ip-dst","198.51.100.42").add_attribute_full("text","text","Notes here",false,Some("analyst comment")).comment("Generated by RustMISP").generate()?;// obj is a MispObject ready to be added to an event
client.add_object(event_id,&obj).await?;
FileObject (tools-file)
Generate a MISP file object from a file path or bytes, including MD5/SHA1/SHA256 hashes.
use rustmisp::tools::file_object::FileObject;// From a file pathlet file_obj = FileObject::new("/path/to/malware.exe")?;let obj = file_obj.generate()?;
client.add_object(event_id,&obj).await?;// From byteslet file_obj = FileObject::from_bytes("sample.bin",&bytes).set_filename("renamed.bin");let obj = file_obj.generate()?;
CsvLoader (tools-csv)
Import attributes from CSV files.
use rustmisp::tools::csv_loader::CsvLoader;// From a filelet attrs = CsvLoader::from_file("/path/to/indicators.csv")?;for attr in&attrs {
client.add_attribute(event_id, attr).await?;}// From a stringlet csv = "type,value,category\nip-dst,198.51.100.42,Network activity\n";let attrs = CsvLoader::from_string(csv)?;
FeedGenerator (tools-feed)
Generate MISP feed metadata.
use rustmisp::tools::feed::FeedGenerator;letmut gen = FeedGenerator::new();
gen.add_event(&event);let manifest = gen.generate_manifest()?;let hashes = gen.generate_hashes();let uuids = gen.event_uuids();let json = gen.get_event_json("event-uuid-here");
OpenIOC Loader (tools-openioc)
Import indicators from OpenIOC XML files.
use rustmisp::tools::openioc::load_openioc_file;let attrs = load_openioc_file("/path/to/ioc.xml")?;for attr in&attrs {
client.add_attribute(event_id, attr).await?;}// From a stringuse rustmisp::tools::openioc::load_openioc;let attrs = load_openioc(xml_content)?;
Error Handling
All methods return MispResult<T>, which is Result<T, MispError>.