Skip to content

Commit

Permalink
Don't throw fatal errors from create_temp_file()
Browse files Browse the repository at this point in the history
This function is called in response to connecting clients, and can fail
when I/O fails for some (possibly temporary) reason.  In such cases we
should not exit the process, but just reject the connecting client.

This commit changes the function to actually return NULL on errors, and
(where needed) changes the callers to check for and handle errors.

Since the tls-crypt-v2 metadata code also calls create_temp_file() when
clients connect, I consider this a prerequisite for tls-crypt-v2.

Signed-off-by: Steffan Karger <[email protected]>
Acked-by: Antonio Quartulli <[email protected]>
Message-Id: <[email protected]>
URL: https://www.mail-archive.com/[email protected]/msg15701.html
Signed-off-by: Gert Doering <[email protected]>
(cherry picked from commit 3e0fd2b)
  • Loading branch information
syzzer authored and cron2 committed Feb 28, 2018
1 parent e5ee512 commit 77a0bdb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
6 changes: 3 additions & 3 deletions src/openvpn/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
retfname = gen_path(directory, BSTR(&fname), gc);
if (!retfname)
{
msg(M_FATAL, "Failed to create temporary filename and path");
msg(M_WARN, "Failed to create temporary filename and path");
return NULL;
}

Expand All @@ -755,14 +755,14 @@ create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
else if (fd == -1 && errno != EEXIST)
{
/* Something else went wrong, no need to retry. */
msg(M_FATAL | M_ERRNO, "Could not create temporary file '%s'",
msg(M_WARN | M_ERRNO, "Could not create temporary file '%s'",
retfname);
return NULL;
}
}
while (attempts < 6);

msg(M_FATAL, "Failed to create temporary file after %i attempts", attempts);
msg(M_WARN, "Failed to create temporary file after %i attempts", attempts);
return NULL;
}

Expand Down
32 changes: 21 additions & 11 deletions src/openvpn/ssl_verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,14 @@ verify_cert_export_cert(openvpn_x509_cert_t *peercert, const char *tmp_dir, stru
FILE *peercert_file;
const char *peercert_filename = "";

if (!tmp_dir)
/* create tmp file to store peer cert */
if (!tmp_dir
|| !(peercert_filename = create_temp_file(tmp_dir, "pcf", gc)))
{
msg (M_WARN, "Failed to create peer cert file");
return NULL;
}

/* create tmp file to store peer cert */
peercert_filename = create_temp_file(tmp_dir, "pcf", gc);

/* write peer-cert in tmp-file */
peercert_file = fopen(peercert_filename, "w+");
if (!peercert_file)
Expand Down Expand Up @@ -589,10 +589,13 @@ verify_cert_call_command(const char *verify_command, struct env_set *es,

if (verify_export_cert)
{
if ((tmp_file = verify_cert_export_cert(cert, verify_export_cert, &gc)))
tmp_file = verify_cert_export_cert(cert, verify_export_cert, &gc);
if (!tmp_file)
{
setenv_str(es, "peer_cert", tmp_file);
ret = false;
goto cleanup;
}
setenv_str(es, "peer_cert", tmp_file);
}

argv_parse_cmd(&argv, verify_command);
Expand All @@ -609,6 +612,7 @@ verify_cert_call_command(const char *verify_command, struct env_set *es,
}
}

cleanup:
gc_free(&gc);
argv_reset(&argv);

Expand Down Expand Up @@ -879,21 +883,21 @@ key_state_rm_auth_control_file(struct key_state *ks)
}
}

static void
static bool
key_state_gen_auth_control_file(struct key_state *ks, const struct tls_options *opt)
{
struct gc_arena gc = gc_new();
const char *acf;

key_state_rm_auth_control_file(ks);
acf = create_temp_file(opt->tmp_dir, "acf", &gc);
const char *acf = create_temp_file(opt->tmp_dir, "acf", &gc);
if (acf)
{
ks->auth_control_file = string_alloc(acf, NULL);
setenv_str(opt->es, "auth_control_file", ks->auth_control_file);
} /* FIXME: Should have better error handling? */
}

gc_free(&gc);
return acf;
}

static unsigned int
Expand Down Expand Up @@ -1184,7 +1188,12 @@ verify_user_pass_plugin(struct tls_session *session, const struct user_pass *up,

#ifdef PLUGIN_DEF_AUTH
/* generate filename for deferred auth control file */
key_state_gen_auth_control_file(ks, session->opt);
if (!key_state_gen_auth_control_file(ks, session->opt))
{
msg (D_TLS_ERRORS, "TLS Auth Error (%s): "
"could not create deferred auth control file", __func__);
goto cleanup;
}
#endif

/* call command */
Expand All @@ -1209,6 +1218,7 @@ verify_user_pass_plugin(struct tls_session *session, const struct user_pass *up,
msg(D_TLS_ERRORS, "TLS Auth Error (verify_user_pass_plugin): peer provided a blank username");
}

cleanup:
return retval;
}

Expand Down

0 comments on commit 77a0bdb

Please sign in to comment.