Skip to content

Commit

Permalink
Add protobuf serialization for new login/logout events (#1380)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlw authored Jul 3, 2024
1 parent b6af5ad commit 688d560
Show file tree
Hide file tree
Showing 14 changed files with 954 additions and 11 deletions.
207 changes: 196 additions & 11 deletions Source/santad/Logs/EndpointSecurity/Serializers/Protobuf.mm
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ static inline void EncodeUserInfo(::pbv1::UserInfo *pb_user_info, uid_t uid,
}
}

static inline void EncodeUserInfo(std::function<::pbv1::UserInfo *()> lazy_f,
std::optional<uid_t> uid, const es_string_token_t &name) {
if (uid.has_value()) {
lazy_f()->set_uid(uid.value());
}
if (name.length > 0) {
lazy_f()->set_name(name.data, name.length);
}
}

static inline void EncodeGroupInfo(::pbv1::GroupInfo *pb_group_info, gid_t gid,
const std::optional<std::shared_ptr<std::string>> &name) {
pb_group_info->set_gid(gid);
Expand Down Expand Up @@ -757,47 +767,222 @@ void EncodeEntitlements(::pbv1::Execution *pb_exec, SNTCachedDecision *cd) {

#if HAVE_MACOS_13

::pbv1::SocketAddress::Type GetSocketAddressType(es_address_type_t type) {
switch (type) {
case ES_ADDRESS_TYPE_NONE: return ::pbv1::SocketAddress::TYPE_NONE;
case ES_ADDRESS_TYPE_IPV4: return ::pbv1::SocketAddress::TYPE_IPV4;
case ES_ADDRESS_TYPE_IPV6: return ::pbv1::SocketAddress::TYPE_IPV6;
case ES_ADDRESS_TYPE_NAMED_SOCKET: return ::pbv1::SocketAddress::TYPE_NAMED_SOCKET;
default: return ::pbv1::SocketAddress::TYPE_UNKNOWN;
}
}

::pbv1::OpenSSHLogin::Result GetOpenSSHLoginResultType(es_openssh_login_result_type_t type) {
switch (type) {
case ES_OPENSSH_LOGIN_EXCEED_MAXTRIES:
return ::pbv1::OpenSSHLogin::RESULT_LOGIN_EXCEED_MAXTRIES;
case ES_OPENSSH_LOGIN_ROOT_DENIED: return ::pbv1::OpenSSHLogin::RESULT_LOGIN_ROOT_DENIED;
case ES_OPENSSH_AUTH_SUCCESS: return ::pbv1::OpenSSHLogin::RESULT_AUTH_SUCCESS;
case ES_OPENSSH_AUTH_FAIL_NONE: return ::pbv1::OpenSSHLogin::RESULT_AUTH_FAIL_NONE;
case ES_OPENSSH_AUTH_FAIL_PASSWD: return ::pbv1::OpenSSHLogin::RESULT_AUTH_FAIL_PASSWD;
case ES_OPENSSH_AUTH_FAIL_KBDINT: return ::pbv1::OpenSSHLogin::RESULT_AUTH_FAIL_KBDINT;
case ES_OPENSSH_AUTH_FAIL_PUBKEY: return ::pbv1::OpenSSHLogin::RESULT_AUTH_FAIL_PUBKEY;
case ES_OPENSSH_AUTH_FAIL_HOSTBASED: return ::pbv1::OpenSSHLogin::RESULT_AUTH_FAIL_HOSTBASED;
case ES_OPENSSH_AUTH_FAIL_GSSAPI: return ::pbv1::OpenSSHLogin::RESULT_AUTH_FAIL_GSSAPI;
case ES_OPENSSH_INVALID_USER: return ::pbv1::OpenSSHLogin::RESULT_INVALID_USER;
default: return ::pbv1::OpenSSHLogin::RESULT_UNKNOWN;
}
}

static inline void EncodeSocketAddress(::pbv1::SocketAddress *pb_socket_addr, std::string_view addr,
es_address_type_t type) {
EncodeString([pb_socket_addr] { return pb_socket_addr->mutable_address(); }, addr);
pb_socket_addr->set_type(GetSocketAddressType(type));
}

static inline void EncodeUserInfo(std::function<::pbv1::UserInfo *()> lazy_f,
const es_string_token_t &name) {
EncodeUserInfo(lazy_f, std::nullopt, name);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedLoginWindowSessionLogin &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::LoginWindowSessionLogin *pb_lw_login =
santa_msg->mutable_login_window_session()->mutable_login();

EncodeProcessInfoLight(pb_lw_login->mutable_instigator(), msg);
EncodeUserInfo([pb_lw_login] { return pb_lw_login->mutable_user(); }, msg.UID(),
msg->event.lw_session_login->username);

pb_lw_login->mutable_graphical_session()->set_id(
msg->event.lw_session_login->graphical_session_id);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedLoginWindowSessionLogout &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::LoginWindowSessionLogout *pb_lw_logout =
santa_msg->mutable_login_window_session()->mutable_logout();

EncodeProcessInfoLight(pb_lw_logout->mutable_instigator(), msg);
EncodeUserInfo([pb_lw_logout] { return pb_lw_logout->mutable_user(); }, msg.UID(),
msg->event.lw_session_logout->username);

pb_lw_logout->mutable_graphical_session()->set_id(
msg->event.lw_session_logout->graphical_session_id);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedLoginWindowSessionLock &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::LoginWindowSessionLock *pb_lw_lock =
santa_msg->mutable_login_window_session()->mutable_lock();

EncodeProcessInfoLight(pb_lw_lock->mutable_instigator(), msg);
EncodeUserInfo([pb_lw_lock] { return pb_lw_lock->mutable_user(); }, msg.UID(),
msg->event.lw_session_lock->username);

pb_lw_lock->mutable_graphical_session()->set_id(msg->event.lw_session_lock->graphical_session_id);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedLoginWindowSessionUnlock &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::LoginWindowSessionUnlock *pb_lw_unlock =
santa_msg->mutable_login_window_session()->mutable_unlock();

EncodeProcessInfoLight(pb_lw_unlock->mutable_instigator(), msg);
EncodeUserInfo([pb_lw_unlock] { return pb_lw_unlock->mutable_user(); }, msg.UID(),
msg->event.lw_session_unlock->username);

pb_lw_unlock->mutable_graphical_session()->set_id(
msg->event.lw_session_unlock->graphical_session_id);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedScreenSharingAttach &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::ScreenSharingAttach *pb_attach = santa_msg->mutable_screen_sharing()->mutable_attach();

EncodeProcessInfoLight(pb_attach->mutable_instigator(), msg);

pb_attach->set_success(msg->event.screensharing_attach->success);

EncodeSocketAddress(pb_attach->mutable_source(),
StringTokenToStringView(msg->event.screensharing_attach->source_address),
msg->event.screensharing_attach->source_address_type);
EncodeString([pb_attach] { return pb_attach->mutable_viewer(); },
StringTokenToStringView(msg->event.screensharing_attach->viewer_appleid));
EncodeString([pb_attach] { return pb_attach->mutable_authentication_type(); },
StringTokenToStringView(msg->event.screensharing_attach->authentication_type));
EncodeUserInfo([pb_attach] { return pb_attach->mutable_authentication_user(); },
msg->event.screensharing_attach->authentication_username);
EncodeUserInfo([pb_attach] { return pb_attach->mutable_session_user(); },
msg->event.screensharing_attach->session_username);

pb_attach->set_existing_session(msg->event.screensharing_attach->existing_session);
pb_attach->mutable_graphical_session()->set_id(
msg->event.screensharing_attach->graphical_session_id);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedScreenSharingDetach &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::ScreenSharingDetach *pb_detach = santa_msg->mutable_screen_sharing()->mutable_detach();

EncodeProcessInfoLight(pb_detach->mutable_instigator(), msg);
EncodeSocketAddress(pb_detach->mutable_source(),
StringTokenToStringView(msg->event.screensharing_detach->source_address),
msg->event.screensharing_detach->source_address_type);
EncodeString([pb_detach] { return pb_detach->mutable_viewer(); },
StringTokenToStringView(msg->event.screensharing_detach->viewer_appleid));

pb_detach->mutable_graphical_session()->set_id(
msg->event.screensharing_detach->graphical_session_id);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedOpenSSHLogin &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::OpenSSHLogin *pb_ssh_login = santa_msg->mutable_open_ssh()->mutable_login();

EncodeProcessInfoLight(pb_ssh_login->mutable_instigator(), msg);

pb_ssh_login->set_result(GetOpenSSHLoginResultType(msg->event.openssh_login->result_type));

EncodeSocketAddress(pb_ssh_login->mutable_source(),
StringTokenToStringView(msg->event.openssh_login->source_address),
msg->event.openssh_login->source_address_type);
EncodeUserInfo([pb_ssh_login] { return pb_ssh_login->mutable_user(); },
msg->event.openssh_login->has_uid
? std::make_optional<uid_t>(msg->event.openssh_login->uid.uid)
: std::nullopt,
msg->event.openssh_login->username);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedOpenSSHLogout &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::OpenSSHLogout *pb_ssh_logout = santa_msg->mutable_open_ssh()->mutable_logout();

EncodeProcessInfoLight(pb_ssh_logout->mutable_instigator(), msg);

EncodeSocketAddress(pb_ssh_logout->mutable_source(),
StringTokenToStringView(msg->event.openssh_logout->source_address),
msg->event.openssh_logout->source_address_type);
EncodeUserInfo([pb_ssh_logout] { return pb_ssh_logout->mutable_user(); },
msg->event.openssh_logout->uid, msg->event.openssh_logout->username);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedLoginLogin &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::Login *pb_login = santa_msg->mutable_login_logout()->mutable_login();

EncodeProcessInfoLight(pb_login->mutable_instigator(), msg);
pb_login->set_success(msg->event.login_login->success);

EncodeString([pb_login] { return pb_login->mutable_failure_message(); },
StringTokenToStringView(msg->event.login_login->failure_message));
EncodeUserInfo([pb_login] { return pb_login->mutable_user(); },
msg->event.login_login->has_uid
? std::make_optional<uid_t>(msg->event.login_login->uid.uid)
: std::nullopt,
msg->event.login_login->username);

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedLoginLogout &msg) {
return {};
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);
::pbv1::Logout *pb_logout = santa_msg->mutable_login_logout()->mutable_logout();

EncodeProcessInfoLight(pb_logout->mutable_instigator(), msg);
EncodeUserInfo([pb_logout] { return pb_logout->mutable_user(); }, msg->event.login_logout->uid,
msg->event.login_logout->username);

return FinalizeProto(santa_msg);
}

#endif
#endif // HAVE_MACOS_13

std::vector<uint8_t> Protobuf::SerializeFileAccess(const std::string &policy_version,
const std::string &policy_name,
Expand Down
Loading

0 comments on commit 688d560

Please sign in to comment.