Skip to content

Commit

Permalink
Merge branch 'pam_env' of github.com:CendioOssman/tigervnc
Browse files Browse the repository at this point in the history
  • Loading branch information
CendioOssman committed May 30, 2024
2 parents 37c9ced + a79c33d commit fb7b956
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 84 deletions.
34 changes: 34 additions & 0 deletions common/os/os.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <os/os.h>

#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

Expand All @@ -39,6 +40,7 @@
#include <wininet.h> /* MinGW needs it */
#include <shlobj.h>
#define stat _stat
#define mkdir(path, mode) mkdir(path)
#endif

static const char* getvncdir(bool userDir, const char *xdg_env, const char *xdg_def)
Expand Down Expand Up @@ -126,3 +128,35 @@ const char* os::getvncstatedir()
{
return getvncdir(false, "XDG_STATE_HOME", ".local/state");
}

int os::mkdir_p(const char *path_, mode_t mode)
{
char *path = strdup(path_);
char *p;

#ifdef WIN32
(void)mode;
#endif

for (p = path + 1; *p; p++) {
if (*p == '/') {
*p = '\0';
if (mkdir(path, mode) == -1) {
if (errno != EEXIST) {
free(path);
return -1;
}
}
*p = '/';
}
}

if (mkdir(path, mode) == -1) {
free(path);
return -1;
}

free(path);

return 0;
}
7 changes: 7 additions & 0 deletions common/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#ifndef OS_OS_H
#define OS_OS_H

#include <sys/stat.h>

namespace os {

/*
Expand Down Expand Up @@ -62,6 +64,11 @@ namespace os {
*/
const char* getvncstatedir();

/*
* Create directory recursively. Useful to create the nested directory
* structures needed for the above directories.
*/
int mkdir_p(const char *path, mode_t mode);
}

#endif /* OS_OS_H */
4 changes: 2 additions & 2 deletions common/rfb/CSecurityTLS.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,9 @@ void CSecurityTLS::checkSession()

/* Certificate has some user overridable problems, so TOFU time */

hostsDir = os::getvncdatadir();
hostsDir = os::getvncstatedir();
if (hostsDir == NULL) {
throw AuthFailureException("Could not obtain VNC data directory "
throw AuthFailureException("Could not obtain VNC state directory "
"path for known hosts storage");
}

Expand Down
4 changes: 2 additions & 2 deletions java/com/tigervnc/rfb/CSecurityTLS.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,12 @@ public void checkServerTrusted(X509Certificate[] chain, String authType)
"do you want to continue?"))
throw new AuthFailureException("server certificate has expired");
}
File vncDir = new File(FileUtils.getVncDataDir());
File vncDir = new File(FileUtils.getVncStateDir());
if (!vncDir.exists()) {
try {
vncDir.mkdir();
} catch(SecurityException e) {
throw new AuthFailureException("Could not obtain VNC data directory "+
throw new AuthFailureException("Could not obtain VNC state directory "+
"path for known hosts storage");
}
}
Expand Down
4 changes: 4 additions & 0 deletions java/com/tigervnc/vncviewer/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ public static String getVncDataDir() {
return getVncDir("XDG_DATA_HOME", ".local" + getFileSeparator() + "share");
}

public static String getVncStateDir() {
return getVncDir("XDG_STATE_HOME", ".local" + getFileSeparator() + "state");
}

public static String getFileSeparator() {
String separator = null;
try {
Expand Down
13 changes: 4 additions & 9 deletions unix/vncpasswd/vncpasswd.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <config.h>
#endif

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
Expand Down Expand Up @@ -161,16 +162,10 @@ int main(int argc, char** argv)
fprintf(stderr, "Can't obtain VNC config directory\n");
exit(1);
}
strcpy(fname, configDir);
char *p = NULL;
for (p = fname + 1; *p; p++) {
if (*p == '/') {
*p = '\0';
mkdir(fname, 0777);
*p = '/';
}
if (os::mkdir_p(configDir, 0777) == -1) {
fprintf(stderr, "Could not create VNC config directory: %s\n", strerror(errno));
exit(1);
}
mkdir(fname, 0777);
snprintf(fname, sizeof(fname), "%s/passwd", configDir);
}

Expand Down
4 changes: 4 additions & 0 deletions unix/vncserver/tigervnc.pam
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#%PAM-1.0

# THIS IS AN EXAMPLE CONFIGURATION
# MODIFY AS NEEDED FOR YOUR DISTRIBUTION

# pam_selinux.so close should be the first session rule
-session required pam_selinux.so close
session required pam_loginuid.so
Expand Down
99 changes: 62 additions & 37 deletions unix/vncserver/vncsession.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,19 @@ stop_pam(pam_handle_t * pamh, int pamret)
return pamret;
}

static char *
getenvp(const char *name, char **envp)
{
while (*envp) {
size_t varlen;
varlen = strcspn(*envp, "=");
if (strncmp(*envp, name, varlen) == 0)
return *envp + varlen + 1;
envp++;
}
return NULL;
}

static char **
prepare_environ(pam_handle_t * pamh)
{
Expand Down Expand Up @@ -345,49 +358,37 @@ switch_user(const char *username, uid_t uid, gid_t gid)
}
}

static void
mkvncdir(const char *dir)
static int
mkdir_p(const char *path_, mode_t mode)
{
if (mkdir(dir, 0755) == -1) {
if (errno != EEXIST) {
syslog(LOG_CRIT, "Failure creating \"%s\": %s", dir, strerror(errno));
_exit(EX_OSERR);
}

#ifdef HAVE_SELINUX
/* this is only needed to handle historical type changes for the legacy dir */
int result;
if (selinux_file_context_verify(dir, 0) == 0) {
result = selinux_restorecon(dir, SELINUX_RESTORECON_RECURSE);

if (result < 0) {
syslog(LOG_WARNING, "Failure restoring SELinux context for \"%s\": %s", dir, strerror(errno));
}
}
#endif
}
}
char *path = strdup(path_);
char *p;

static void
mkdirrecursive(const char *dir)
{
char *path = strdup(dir);
char *p;

for (p = path + 1; *p; p++) {
if (*p == '/') {
*p = '\0';
mkvncdir(path);
*p = '/';
for (p = path + 1; *p; p++) {
if (*p == '/') {
*p = '\0';
if (mkdir(path, mode) == -1) {
if (errno != EEXIST) {
free(path);
return -1;
}
}
*p = '/';
}
}

mkvncdir(path);
if (mkdir(path, mode) == -1) {
free(path);
return -1;
}

free(path);

return 0;
}

static void
redir_stdio(const char *homedir, const char *display)
redir_stdio(const char *homedir, const char *display, char **envp)
{
int fd;
long hostlen;
Expand All @@ -406,7 +407,7 @@ redir_stdio(const char *homedir, const char *display)
}
close(fd);

xdgstate = getenv("XDG_STATE_HOME");
xdgstate = getenvp("XDG_STATE_HOME", envp);
if (xdgstate != NULL && xdgstate[0] == '/')
snprintf(logfile, sizeof(logfile), "%s/tigervnc", xdgstate);
else
Expand All @@ -416,9 +417,26 @@ redir_stdio(const char *homedir, const char *display)
if (stat(logfile, &st) != 0 && stat(legacy, &st) == 0) {
syslog(LOG_WARNING, "~/.vnc is deprecated, please consult 'man vncsession' for paths to migrate to.");
strcpy(logfile, legacy);

#ifdef HAVE_SELINUX
/* this is only needed to handle historical type changes for the legacy dir */
int result;
if (selinux_file_context_verify(legacy, 0) == 0) {
result = selinux_restorecon(legacy, SELINUX_RESTORECON_RECURSE);

if (result < 0) {
syslog(LOG_WARNING, "Failure restoring SELinux context for \"%s\": %s", legacy, strerror(errno));
}
}
#endif
}

mkdirrecursive(logfile);
if (mkdir_p(logfile, 0755) == -1) {
if (errno != EEXIST) {
syslog(LOG_CRIT, "Failure creating \"%s\": %s", logfile, strerror(errno));
_exit(EX_OSERR);
}
}

hostlen = sysconf(_SC_HOST_NAME_MAX);
if (hostlen < 0) {
Expand Down Expand Up @@ -459,6 +477,10 @@ close_fds(void)
_exit(EX_OSERR);
}

// We'll close the file descriptor that the logging uses, so might
// as well do it cleanly
closelog();

while ((entry = readdir(dir)) != NULL) {
int fd;
fd = atoi(entry->d_name);
Expand Down Expand Up @@ -503,7 +525,7 @@ run_script(const char *username, const char *display, char **envp)

close_fds();

redir_stdio(pwent->pw_dir, display);
redir_stdio(pwent->pw_dir, display, envp);

// execvpe() is not POSIX and is missing from older glibc
// First clear out everything
Expand Down Expand Up @@ -532,9 +554,12 @@ run_script(const char *username, const char *display, char **envp)
child_argv[1] = display;
child_argv[2] = NULL;

closelog();

execvp(child_argv[0], (char*const*)child_argv);

// execvp failed
openlog("vncsession", LOG_PID, LOG_AUTH);
syslog(LOG_CRIT, "execvp: %s", strerror(errno));

_exit(EX_OSERR);
Expand Down
49 changes: 15 additions & 34 deletions vncviewer/vncviewer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#ifdef WIN32
#include <os/winerrno.h>
#include <direct.h>
#define mkdir(path, mode) _mkdir(path)
#endif

#ifdef __APPLE__
Expand Down Expand Up @@ -429,36 +428,6 @@ static void init_fltk()
#endif
}

static int mkvncdir(const char *dir)
{
int result = mkdir(dir, 0755);
if (result == -1 && errno != EEXIST) {
vlog.error(_("Could not create VNC directory %s: %s"), dir, strerror(errno));
return result;
}
return 0;
}

static void mkdirrecursive(const char *dir)
{
char *path = strdup(dir);
char *p;

for (p = path + 1; *p; p++) {
if (*p == '/') {
*p = '\0';
if (mkvncdir(path) != 0) {
free(path);
return;
}
*p = '/';
}
}

mkvncdir(path);
free(path);
}

static void usage(const char *programName)
{
#ifdef WIN32
Expand Down Expand Up @@ -755,9 +724,21 @@ int main(int argc, char** argv)
if (vncdir != NULL && strcmp(vncdir, "vnc") == 0)
vlog.info(_("%%APPDATA%%\\vnc is deprecated, please switch to the %%APPDATA%%\\TigerVNC location."));
#endif
mkdirrecursive(os::getvncconfigdir());
mkdirrecursive(os::getvncdatadir());
mkdirrecursive(os::getvncstatedir());

if (os::mkdir_p(os::getvncconfigdir(), 0755) == -1) {
if (errno != EEXIST)
vlog.error(_("Could not create VNC config directory: %s"), strerror(errno));
}

if (os::mkdir_p(os::getvncdatadir(), 0755) == -1) {
if (errno != EEXIST)
vlog.error(_("Could not create VNC data directory: %s"), strerror(errno));
}

if (os::mkdir_p(os::getvncstatedir(), 0755) == -1) {
if (errno != EEXIST)
vlog.error(_("Could not create VNC state directory: %s"), strerror(errno));
}

CSecurity::upg = &dlg;
#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE)
Expand Down

0 comments on commit fb7b956

Please sign in to comment.