bool allow_fd_passing_output:1;
bool output_buffer_sensitive:1; /* whether to erase the output buffer after writing it to the socket */
+ bool input_sensitive:1; /* Whether incoming messages might be sensitive */
int af; /* address family if socket; AF_UNSPEC if not socket; negative if not known */
varlink_clear_current(v);
- v->input_buffer = mfree(v->input_buffer);
+ v->input_buffer = v->input_sensitive ? erase_and_free(v->input_buffer) : mfree(v->input_buffer);
v->output_buffer = v->output_buffer_sensitive ? erase_and_free(v->output_buffer) : mfree(v->output_buffer);
v->input_control_buffer = mfree(v->input_control_buffer);
}
static int varlink_parse_message(Varlink *v) {
- const char *e, *begin;
+ const char *e;
+ char *begin;
size_t sz;
int r;
sz = e - begin + 1;
r = json_parse(begin, 0, &v->current, NULL, NULL);
+ if (v->input_sensitive)
+ explicit_bzero_safe(begin, sz);
if (r < 0) {
/* If we encounter a parse failure flush all data. We cannot possibly recover from this,
* hence drop all buffered data now. */
return varlink_log_errno(v, r, "Failed to parse JSON: %m");
}
+ if (v->input_sensitive) {
+ /* Mark the parameters subfield as sensitive right-away, if that's requested */
+ JsonVariant *parameters = json_variant_by_key(v->current, "parameters");
+ if (parameters)
+ json_variant_sensitive(parameters);
+ }
+
v->input_buffer_size -= sz;
if (v->input_buffer_size == 0)
return 0;
}
+int varlink_set_input_sensitive(Varlink *v) {
+ assert_return(v, -EINVAL);
+
+ v->input_sensitive = true;
+ return 0;
+}
+
int varlink_server_new(VarlinkServer **ret, VarlinkServerFlags flags) {
_cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
int r;
TAKE_FD(cfd);
+ if (FLAGS_SET(ss->server->flags, VARLINK_SERVER_INPUT_SENSITIVE))
+ varlink_set_input_sensitive(v);
+
if (ss->server->connect_callback) {
r = ss->server->connect_callback(ss->server, v, ss->server->userdata);
if (r < 0) {