@@ -2,8 +2,6 @@ | |||
*.mo | |||
*.la | |||
*.lo | |||
*.class | |||
*.jar | |||
.deps | |||
.libs | |||
@@ -12,18 +10,6 @@ CMakeCache.txt | |||
Makefile | |||
Makefile.in | |||
config.h | |||
*.xml | |||
*.man | |||
*.service | |||
cmake_install.cmake | |||
cmake_uninstall.cmake | |||
install_manifest.txt | |||
tests/unit/[a-z]* | |||
!tests/unit/[a-z]*\. | |||
timestamp | |||
vncserver | |||
!unix/vncserver | |||
vncsession | |||
vncsession-start |
@@ -24,6 +24,8 @@ | |||
#include <os/os.h> | |||
#include <assert.h> | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#ifndef WIN32 | |||
#include <pwd.h> | |||
@@ -31,18 +33,18 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#include <unistd.h> | |||
#else | |||
#include <windows.h> | |||
#include <wininet.h> /* MinGW needs it */ | |||
#include <shlobj.h> | |||
#define stat _stat | |||
#endif | |||
static const char* getvncdir(bool userDir, const char *xdg_env, const char *xdg_def) | |||
{ | |||
static char dir[PATH_MAX]; | |||
static char dir[PATH_MAX], legacy[PATH_MAX]; | |||
struct stat st; | |||
#ifndef WIN32 | |||
char *homedir, *xdgdir; | |||
@@ -67,23 +69,17 @@ static const char* getvncdir(bool userDir, const char *xdg_env, const char *xdg_ | |||
if (userDir) | |||
return homedir; | |||
// check if (deprecated) legacy path exists and use that if so | |||
snprintf(dir, sizeof(dir), "%s/.vnc", homedir); | |||
struct stat st; | |||
if (stat(dir, &st) == 0) | |||
return dir; | |||
if (xdg_def != NULL) { | |||
xdgdir = getenv(xdg_env); | |||
if (xdgdir != NULL) | |||
snprintf(dir, sizeof(dir), "%s/tigervnc", xdgdir); | |||
else | |||
snprintf(dir, sizeof(dir), "%s/%s/tigervnc", homedir, xdg_def); | |||
} | |||
xdgdir = getenv(xdg_env); | |||
if (xdgdir != NULL && xdgdir[0] == '/') | |||
snprintf(dir, sizeof(dir), "%s/tigervnc", xdgdir); | |||
else | |||
snprintf(dir, sizeof(dir), "%s/%s/tigervnc", homedir, xdg_def); | |||
return dir; | |||
snprintf(legacy, sizeof(legacy), "%s/.vnc", homedir); | |||
#else | |||
(void) xdg_def; | |||
(void) xdg_env; | |||
if (userDir) | |||
ret = SHGetSpecialFolderPath(NULL, dir, CSIDL_PROFILE, FALSE); | |||
else | |||
@@ -95,13 +91,20 @@ static const char* getvncdir(bool userDir, const char *xdg_env, const char *xdg_ | |||
if (userDir) | |||
return dir; | |||
if (strlen(dir) + strlen("\\vnc") >= sizeof(dir)) | |||
ret = SHGetSpecialFolderPath(NULL, legacy, CSIDL_APPDATA, FALSE); | |||
if (ret == FALSE) | |||
return NULL; | |||
strcat(dir, "\\vnc"); | |||
if (strlen(dir) + strlen("\\TigerVNC") >= sizeof(dir)) | |||
return NULL; | |||
if (strlen(legacy) + strlen("\\vnc") >= sizeof(legacy)) | |||
return NULL; | |||
return dir; | |||
strcat(dir, "\\TigerVNC"); | |||
strcat(legacy, "\\vnc"); | |||
#endif | |||
return (stat(dir, &st) != 0 && stat(legacy, &st) == 0) ? legacy : dir; | |||
} | |||
const char* os::getuserhomedir() | |||
@@ -114,13 +117,12 @@ const char* os::getvncconfigdir() | |||
return getvncdir(false, "XDG_CONFIG_HOME", ".config"); | |||
} | |||
const char* os::getvncstatedir() | |||
const char* os::getvncdatadir() | |||
{ | |||
return getvncdir(false, "XDG_STATE_HOME", ".local/state"); | |||
return getvncdir(false, "XDG_DATA_HOME", ".local/share"); | |||
} | |||
/* deprecated */ | |||
const char* os::getvnchomedir() | |||
const char* os::getvncstatedir() | |||
{ | |||
return getvncdir(false, NULL, NULL); | |||
return getvncdir(false, "XDG_STATE_HOME", ".local/state"); | |||
} |
@@ -35,32 +35,32 @@ namespace os { | |||
* Get VNC config directory. On Unix-like systems, this is either: | |||
* - $XDG_CONFIG_HOME/tigervnc | |||
* - $HOME/.config/tigervnc | |||
* On Windows, this is simply %APPDATA%/vnc/. | |||
* On Windows, this is simply %APPDATA%/TigerVNC/. | |||
* | |||
* Returns NULL on failure. | |||
*/ | |||
const char* getvncconfigdir(); | |||
/* | |||
* Get VNC state (logs) directory. On Unix-like systems, this is either: | |||
* - $XDG_STATE_HOME/tigervnc | |||
* - $HOME/.local/state/tigervnc | |||
* On Windows, this is simply %APPDATA%/vnc/. | |||
* Get VNC data directory used for X.509 known hosts. | |||
* On Unix-like systems, this is either: | |||
* - $XDG_DATA_HOME/tigervnc | |||
* - $HOME/.local/share/tigervnc | |||
* On Windows, this is simply %APPDATA%/TigerVNC/. | |||
* | |||
* Returns NULL on failure. | |||
*/ | |||
const char* getvncstatedir(); | |||
const char* getvncdatadir(); | |||
/* | |||
* Get legacy VNC home directory ($HOME/.vnc on Unix-likes). | |||
* If HOME environment variable is set then it is used. | |||
* Otherwise home directory is obtained via getpwuid function. | |||
* Get VNC state (logs) directory. On Unix-like systems, this is either: | |||
* - $XDG_STATE_HOME/tigervnc | |||
* - $HOME/.local/state/tigervnc | |||
* On Windows, this is simply %APPDATA%/TigerVNC/. | |||
* | |||
* Returns NULL on failure. | |||
* | |||
* Deprecated. | |||
*/ | |||
const char* getvnchomedir(); | |||
const char* getvncstatedir(); | |||
} | |||
@@ -79,7 +79,6 @@ static const char* configdirfn(const char* fn) | |||
return ""; | |||
snprintf(full_path, sizeof(full_path), "%s/%s", configdir, fn); | |||
return full_path; | |||
} | |||
@@ -308,7 +307,7 @@ void CSecurityTLS::checkSession() | |||
int err; | |||
bool hostname_match; | |||
const char *configDir; | |||
const char *hostsDir; | |||
gnutls_datum_t info; | |||
size_t len; | |||
@@ -385,14 +384,14 @@ void CSecurityTLS::checkSession() | |||
/* Certificate has some user overridable problems, so TOFU time */ | |||
configDir = os::getvncconfigdir(); | |||
if (configDir == NULL) { | |||
throw AuthFailureException("Could not obtain VNC config directory " | |||
hostsDir = os::getvncdatadir(); | |||
if (hostsDir == NULL) { | |||
throw AuthFailureException("Could not obtain VNC data directory " | |||
"path for known hosts storage"); | |||
} | |||
std::string dbPath; | |||
dbPath = (std::string)configDir + "/x509_known_hosts"; | |||
dbPath = (std::string)hostsDir + "/x509_known_hosts"; | |||
err = gnutls_verify_stored_pubkey(dbPath.c_str(), NULL, | |||
client->getServerName(), NULL, |
@@ -15,5 +15,5 @@ | |||
# Identifier "Screen0 | |||
# DefaultDepth 16 | |||
# Option "SecurityTypes" "VncAuth" | |||
# Option "PasswordFile" "/root/.vnc/passwd" | |||
# Option "PasswordFile" "/root/.config/tigervnc/passwd" | |||
#EndSection |
@@ -15,5 +15,5 @@ | |||
# Identifier "Screen0 | |||
# DefaultDepth 16 | |||
# Option "SecurityTypes" "VncAuth" | |||
# Option "PasswordFile" "/root/.vnc/passwd" | |||
# Option "PasswordFile" "/root/.config/tigervnc/passwd" | |||
#EndSection |
@@ -15,5 +15,5 @@ | |||
# Identifier "Screen0 | |||
# DefaultDepth 16 | |||
# Option "SecurityTypes" "VncAuth" | |||
# Option "PasswordFile" "/root/.vnc/passwd" | |||
# Option "PasswordFile" "/root/.config/tigervnc/passwd" | |||
#EndSection |
@@ -0,0 +1,4 @@ | |||
*.class | |||
*.jar | |||
.idea/ | |||
timestamp |
@@ -89,13 +89,13 @@ public class CSecurityTLS extends CSecurity { | |||
public static String getDefaultCA() { | |||
if (UserPreferences.get("viewer", "x509ca") != null) | |||
return UserPreferences.get("viewer", "x509ca"); | |||
return FileUtils.getVncHomeDir()+"x509_ca.pem"; | |||
return FileUtils.getVncConfigDir()+"x509_ca.pem"; | |||
} | |||
public static String getDefaultCRL() { | |||
if (UserPreferences.get("viewer", "x509crl") != null) | |||
return UserPreferences.get("viewer", "x509crl"); | |||
return FileUtils.getVncHomeDir()+"x509_crl.pem"; | |||
return FileUtils.getVncConfigDir()+"x509_crl.pem"; | |||
} | |||
public static void setDefaults() | |||
@@ -277,12 +277,12 @@ public class CSecurityTLS extends CSecurity { | |||
"do you want to continue?")) | |||
throw new AuthFailureException("server certificate has expired"); | |||
} | |||
File vncDir = new File(FileUtils.getVncHomeDir()); | |||
File vncDir = new File(FileUtils.getVncDataDir()); | |||
if (!vncDir.exists()) { | |||
try { | |||
vncDir.mkdir(); | |||
} catch(SecurityException e) { | |||
throw new AuthFailureException("Could not obtain VNC home directory "+ | |||
throw new AuthFailureException("Could not obtain VNC data directory "+ | |||
"path for known hosts storage"); | |||
} | |||
} | |||
@@ -356,7 +356,6 @@ public class CSecurityTLS extends CSecurity { | |||
private void store_pubkey(File dbPath, String serverName, String pk) | |||
{ | |||
ArrayList<String> lines = new ArrayList<String>(); | |||
File vncDir = new File(FileUtils.getVncHomeDir()); | |||
try { | |||
if (dbPath.exists()) { | |||
FileReader db = new FileReader(dbPath); |
@@ -22,9 +22,11 @@ import javax.swing.filechooser.FileSystemView; | |||
import com.tigervnc.rfb.LogWriter; | |||
import java.io.File; | |||
public class FileUtils { | |||
public static final String getHomeDir() { | |||
public static String getHomeDir() { | |||
String homeDir = null; | |||
try { | |||
String os = System.getProperty("os.name"); | |||
@@ -56,21 +58,47 @@ public class FileUtils { | |||
vlog.error("Cannot access os.name system property:"+e.getMessage()); | |||
} | |||
String separator = null; | |||
try { | |||
separator = Character.toString(java.io.File.separatorChar); | |||
} catch(java.security.AccessControlException e) { | |||
vlog.error("Cannot access file.separator system property:"+e.getMessage()); | |||
return homeDir + getFileSeparator(); | |||
} | |||
public static String getVncDir(String xdgEnv, String xdgDefault) { | |||
File legacyDir = new File(getHomeDir() + ".vnc" + getFileSeparator()); | |||
String os = System.getProperty("os.name"); | |||
if (os.startsWith("Windows")) { | |||
File newDir = new File(System.getenv("APPDATA") + getFileSeparator() + "TigerVNC" + getFileSeparator()); | |||
if (!newDir.exists()) { | |||
newDir.mkdirs(); | |||
} | |||
File[] existingFiles = legacyDir.listFiles(); | |||
if (existingFiles != null) { | |||
for (File file : existingFiles) { | |||
file.renameTo(new File(newDir.getPath() + file.getName())); | |||
} | |||
legacyDir.delete(); | |||
} | |||
return newDir.getPath(); | |||
} else { | |||
if (legacyDir.exists()) { | |||
vlog.info("WARNING: ~/.vnc is deprecated, please consult 'man vncviewer' for paths to migrate to."); | |||
return legacyDir.getPath(); | |||
} | |||
String xdgBaseDir = System.getenv(xdgEnv); | |||
return (xdgBaseDir != null && xdgBaseDir.startsWith("/")) | |||
? xdgBaseDir + getFileSeparator() + "tigervnc" + getFileSeparator() | |||
: getHomeDir() + xdgDefault + getFileSeparator() + "tigervnc" + getFileSeparator(); | |||
} | |||
} | |||
return homeDir + getFileSeparator(); | |||
public static String getVncConfigDir() { | |||
return getVncDir("XDG_CONFIG_HOME", ".config"); | |||
} | |||
public static final String getVncHomeDir() { | |||
return getHomeDir()+".vnc"+getFileSeparator(); | |||
public static String getVncDataDir() { | |||
return getVncDir("XDG_DATA_HOME", ".local" + getFileSeparator() + "share"); | |||
} | |||
public static final String getFileSeparator() { | |||
public static String getFileSeparator() { | |||
String separator = null; | |||
try { | |||
separator = Character.toString(java.io.File.separatorChar); |
@@ -325,13 +325,6 @@ public class Parameters { | |||
if (filename == null || filename.isEmpty()) { | |||
saveToReg(servername); | |||
return; | |||
/* | |||
String homeDir = FileUtils.getVncHomeDir(); | |||
if (homeDir == null) | |||
throw new Exception("Failed to read configuration file, "+ | |||
"can't obtain home directory path."); | |||
filepath = homeDir.concat("default.tigervnc"); | |||
*/ | |||
} else { | |||
filepath = filename; | |||
} | |||
@@ -385,16 +378,7 @@ public class Parameters { | |||
String filepath; | |||
if (filename == null) { | |||
return loadFromReg(); | |||
/* | |||
String homeDir = FileUtils.getVncHomeDir(); | |||
if (homeDir == null) | |||
throw new Exception("Failed to read configuration file, "+ | |||
"can't obtain home directory path."); | |||
filepath = homeDir.concat("default.tigervnc"); | |||
*/ | |||
return loadFromReg(); | |||
} else { | |||
filepath = filename; | |||
} |
@@ -235,7 +235,7 @@ class ServerDialog extends Dialog implements Runnable { | |||
private void handleLoad() { | |||
String title = "Select a TigerVNC configuration file"; | |||
File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc")); | |||
File dflt = new File(FileUtils.getVncConfigDir().concat("default.tigervnc")); | |||
FileNameExtensionFilter filter = | |||
new FileNameExtensionFilter("TigerVNC configuration (*.tigervnc)", "tigervnc"); | |||
File f = showChooser(title, dflt, filter); | |||
@@ -245,9 +245,9 @@ class ServerDialog extends Dialog implements Runnable { | |||
private void handleSaveAs() { | |||
String title = "Save the TigerVNC configuration to file"; | |||
File dflt = new File(FileUtils.getVncHomeDir().concat("default.tigervnc")); | |||
File dflt = new File(FileUtils.getVncConfigDir().concat("default.tigervnc")); | |||
if (!dflt.exists() || !dflt.isFile()) | |||
dflt = new File(FileUtils.getVncHomeDir()); | |||
dflt = new File(FileUtils.getVncConfigDir()); | |||
FileNameExtensionFilter filter = | |||
new FileNameExtensionFilter("TigerVNC configuration (*.tigervnc)", "tigervnc"); | |||
File f = showChooser(title, dflt, filter); |
@@ -1,6 +1,11 @@ | |||
conv | |||
convertlf | |||
convperf | |||
decperf | |||
emulatemb | |||
encperf | |||
fbperf | |||
gesturehandler | |||
hostport | |||
pixelformat | |||
unicode |
@@ -161,7 +161,16 @@ int main(int argc, char** argv) | |||
fprintf(stderr, "Can't obtain VNC config directory\n"); | |||
exit(1); | |||
} | |||
mkdir(configDir, 0777); | |||
strcpy(fname, configDir); | |||
char *p = NULL; | |||
for (p = fname + 1; *p; p++) { | |||
if (*p == '/') { | |||
*p = '\0'; | |||
mkdir(fname, 0777); | |||
*p = '/'; | |||
} | |||
} | |||
mkdir(fname, 0777); | |||
snprintf(fname, sizeof(fname), "%s/passwd", configDir); | |||
} | |||
@@ -9,11 +9,12 @@ vncpasswd \- change the VNC password | |||
.B vncpasswd | |||
allows you to set the password used to access VNC desktops. Its default | |||
behavior is to prompt for a VNC password and then store an obfuscated version | |||
of this password to \fIpasswd-file\fR (or to $HOME/.vnc/passwd if no password | |||
file is specified.) The \fBvncserver\fP script runs \fBvncpasswd\fP the first | |||
time you start a VNC desktop, and it invokes \fBXvnc\fP with the appropriate | |||
\fB\-rfbauth\fP option. \fBvncviewer\fP can also be given a password file to | |||
use via the \fB\-passwd\fP option. | |||
of this password to \fIpasswd-file\fR (or to | |||
\fI$XDG_CONFIG_HOME/tigervnc/passwd\fP if no passwordfile is specified.) The | |||
\fBvncserver\fP script runs \fBvncpasswd\fP the first time you start a VNC | |||
desktop, and it invokes \fBXvnc\fP with the appropriate \fB\-rfbauth\fP option. | |||
\fBvncviewer\fP can also be given a password file to use via the \fB\-passwd\fP | |||
option. | |||
The password must be at least six characters long (unless the \fB\-f\fR | |||
command-line option is used-- see below), and only the first eight | |||
@@ -38,7 +39,9 @@ character. | |||
.SH FILES | |||
.TP | |||
$HOME/.vnc/passwd | |||
\fI$XDG_CONFIG_HOME/tigervnc/passwd\fP | |||
.TQ | |||
\fI$HOME/.config/tigervnc/passwd\fP | |||
Default location of the VNC password file. | |||
.SH SEE ALSO |
@@ -0,0 +1,5 @@ | |||
vncserver | |||
vncserver@.service | |||
vncsession | |||
vncsession-start | |||
vncsession.man |
@@ -30,7 +30,8 @@ To configure Xvnc parameters, you need to go to the same directory where | |||
you did the user mapping and open `vncserver-config-defaults` | |||
configuration file. This file is for the default Xvnc configuration and | |||
will be applied to every user unless any of the following applies: | |||
* The user has its own configuration in `$HOME/.vnc/config`. | |||
* The user has its own configuration in `$XDG_CONFIG_HOME/tigervnc/config` | |||
or `$HOME/.config/tigervnc/config`. | |||
* The same option with different value is configured in | |||
`vncserver-config-mandatory` configuration file, which replaces the | |||
default configuration and has even a higher priority than the per-user | |||
@@ -74,10 +75,10 @@ You need to run it as the user who will run the server. | |||
### Note: | |||
If you used TigerVNC before with your user and you already created a | |||
password, then you have to make sure the `$HOME/.vnc` folder created by | |||
`vncpasswd` have the correct *SELinux* context. You either can delete | |||
this folder and recreate it again by creating the password one more | |||
time, or alternatively you can run: | |||
password, then you have to make sure the (legacy, if used) `$HOME/.vnc` | |||
folder created by `vncpasswd` has the correct *SELinux* context. You | |||
either can delete this folder and recreate it again by creating the | |||
password one more time, or alternatively you can run: | |||
``` | |||
$ restorecon -RFv /home/<USER>/.vnc | |||
``` |
@@ -19,6 +19,12 @@ | |||
HOME_DIR/\.vnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
/root/\.vnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
HOME_DIR/\.config/tigervnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
/root/\.config/tigervnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
HOME_DIR/\.local/share/tigervnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
/root/\.local/share/tigervnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
HOME_DIR/\.local/state/tigervnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
/root/\.local/state/tigervnc(/.*)? gen_context(system_u:object_r:vnc_home_t,s0) | |||
/usr/sbin/vncsession -- gen_context(system_u:object_r:vnc_session_exec_t,s0) | |||
/usr/libexec/vncsession-start -- gen_context(system_u:object_r:vnc_session_exec_t,s0) |
@@ -37,6 +37,18 @@ allow vnc_session_t self:fifo_file rw_fifo_file_perms; | |||
allow vnc_session_t vnc_session_var_run_t:file manage_file_perms; | |||
files_pid_filetrans(vnc_session_t, vnc_session_var_run_t, file) | |||
# Allowed to create ~/.local | |||
optional_policy(` | |||
gnome_filetrans_home_content(vnc_session_t) | |||
') | |||
optional_policy(` | |||
gen_require(` | |||
type gconf_home_t; | |||
') | |||
create_dirs_pattern(vnc_session_t, gconf_home_t, gconf_home_t) | |||
') | |||
# Manage TigerVNC files (mainly ~/.local/state/*.log) | |||
create_dirs_pattern(vnc_session_t, vnc_home_t, vnc_home_t) | |||
manage_files_pattern(vnc_session_t, vnc_home_t, vnc_home_t) | |||
manage_fifo_files_pattern(vnc_session_t, vnc_home_t, vnc_home_t) | |||
@@ -72,13 +84,16 @@ optional_policy(` | |||
userdom_spec_domtrans_all_users(vnc_session_t) | |||
userdom_signal_all_users(vnc_session_t) | |||
userdom_user_home_dir_filetrans(vnc_session_t, vnc_home_t, dir, ".vnc") | |||
userdom_admin_home_dir_filetrans(vnc_session_t, vnc_home_t, dir, ".vnc") | |||
# This also affects other tools, e.g. vncpasswd | |||
# Make sure legacy path has correct type | |||
gen_require(` | |||
attribute userdomain; | |||
type gconf_home_t; | |||
') | |||
userdom_admin_home_dir_filetrans(userdomain, vnc_home_t, dir, ".vnc") | |||
userdom_user_home_dir_filetrans(userdomain, vnc_home_t, dir, ".vnc") | |||
gnome_config_filetrans(userdomain, vnc_home_t, dir, "tigervnc") | |||
gnome_data_filetrans(userdomain, vnc_home_t, dir, "tigervnc") | |||
filetrans_pattern(userdomain, gconf_home_t, vnc_home_t, dir, "tigervnc") | |||
filetrans_pattern(vnc_session_t, gconf_home_t, vnc_home_t, dir, "tigervnc") | |||
') |
@@ -1,7 +1,7 @@ | |||
## Default settings for VNC servers started by the vncserver service | |||
# | |||
# Any settings given here will override the builtin defaults, but can | |||
# also be overriden by ~/.vnc/config and vncserver-config-mandatory. | |||
# also be overriden by ~/.config/tigervnc/config and vncserver-config-mandatory. | |||
# | |||
# See HOWTO.md and the following manpages for more details: | |||
# vncsession(8) Xvnc(1) |
@@ -1,7 +1,7 @@ | |||
## Mandatory settings for VNC servers started by the vncserver service | |||
# | |||
# Any settings given here will override the builtin defaults and | |||
# settings specified in ~/.vnc/config or vnc-config-defaults. | |||
# settings specified in ~/.config/tigervnc/config or vnc-config-defaults. | |||
# | |||
# See HOWTO.md and the following manpages for more details: | |||
# vncsession(8) Xvnc(1) |
@@ -35,13 +35,13 @@ | |||
# your site | |||
# | |||
# Start with legacy ~/.vnc user dir | |||
$vncUserDir = "$ENV{HOME}/.vnc"; | |||
if (stat($vncUserDir)) { | |||
warn "~/.vnc is deprecated, please migrate to XDGBDS-compliant paths!"; | |||
} else { | |||
# Legacy path doesn't exist, start using new XDG-alike path | |||
$vncUserDir = "$ENV{HOME}/.config/tigervnc"; | |||
$vncUserDir = rindex("$ENV{XDG_CONFIG_HOME}", "/", 0) == 0 | |||
? "$ENV{XDG_CONFIG_HOME}/tigervnc" | |||
: "$ENV{HOME}/.config/tigervnc"; | |||
$vncLegacyDir = "$ENV{HOME}/.vnc"; | |||
if (!stat($vncUserDir) && stat($vncLegacyDir)) { | |||
warn "~/.vnc is deprecated, please consult 'man vncsession' for paths to migrate to."; | |||
$vncUserDir = $vncLegacyDir; | |||
} | |||
$vncUserConfig = "$vncUserDir/config"; | |||
@@ -119,8 +119,8 @@ $default_opts{pn} = undef; | |||
# Load user-overrideable system defaults | |||
LoadConfig($vncSystemConfigDefaultsFile); | |||
# Then the user's settings (location overrideable by previous system defaults) | |||
LoadConfig($config{'userconfig'} || $vncUserConfig); | |||
# Then the user's settings | |||
LoadConfig($vncUserConfig); | |||
# And then override anything set above if mandatory settings exist. | |||
# WARNING: "Mandatory" is used loosely here! As the man page says, |
@@ -345,13 +345,55 @@ switch_user(const char *username, uid_t uid, gid_t gid) | |||
} | |||
} | |||
static void | |||
mkvncdir(const char *dir) | |||
{ | |||
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 | |||
} | |||
} | |||
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 = '/'; | |||
} | |||
} | |||
mkvncdir(path); | |||
free(path); | |||
} | |||
static void | |||
redir_stdio(const char *homedir, const char *display) | |||
{ | |||
int fd; | |||
long hostlen; | |||
char* hostname = NULL; | |||
char logfile[PATH_MAX]; | |||
char* hostname = NULL, *xdgstate; | |||
char logfile[PATH_MAX], legacy[PATH_MAX]; | |||
struct stat st; | |||
fd = open("/dev/null", O_RDONLY); | |||
if (fd == -1) { | |||
@@ -364,25 +406,20 @@ redir_stdio(const char *homedir, const char *display) | |||
} | |||
close(fd); | |||
snprintf(logfile, sizeof(logfile), "%s/.vnc", homedir); | |||
if (mkdir(logfile, 0755) == -1) { | |||
if (errno != EEXIST) { | |||
syslog(LOG_CRIT, "Failure creating \"%s\": %s", logfile, strerror(errno)); | |||
_exit(EX_OSERR); | |||
} | |||
xdgstate = getenv("XDG_STATE_HOME"); | |||
if (xdgstate != NULL && xdgstate[0] == '/') | |||
snprintf(logfile, sizeof(logfile), "%s/tigervnc", xdgstate); | |||
else | |||
snprintf(logfile, sizeof(logfile), "%s/.local/state/tigervnc", homedir); | |||
#ifdef HAVE_SELINUX | |||
int result; | |||
if (selinux_file_context_verify(logfile, 0) == 0) { | |||
result = selinux_restorecon(logfile, SELINUX_RESTORECON_RECURSE); | |||
if (result < 0) { | |||
syslog(LOG_WARNING, "Failure restoring SELinux context for \"%s\": %s", logfile, strerror(errno)); | |||
} | |||
} | |||
#endif | |||
snprintf(legacy, sizeof(legacy), "%s/.vnc", homedir); | |||
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); | |||
} | |||
mkdirrecursive(logfile); | |||
hostlen = sysconf(_SC_HOST_NAME_MAX); | |||
if (hostlen < 0) { | |||
syslog(LOG_CRIT, "sysconf(_SC_HOST_NAME_MAX): %s", strerror(errno)); | |||
@@ -395,8 +432,8 @@ redir_stdio(const char *homedir, const char *display) | |||
_exit(EX_OSERR); | |||
} | |||
snprintf(logfile, sizeof(logfile), "%s/.vnc/%s%s.log", | |||
homedir, hostname, display); | |||
snprintf(logfile + strlen(logfile), sizeof(logfile) - strlen(logfile), "/%s%s.log", | |||
hostname, display); | |||
free(hostname); | |||
fd = open(logfile, O_CREAT | O_WRONLY | O_TRUNC, 0644); | |||
if (fd == -1) { |
@@ -27,27 +27,33 @@ debugging in a login shell from a terminal or for running | |||
from a terminal as an ordinary user. | |||
.SH FILES | |||
Several VNC-related files are found in the directory $HOME/.vnc: | |||
Several VNC-related files are found in the directory \fI$HOME/.config/tigervnc\fP: | |||
.TP | |||
@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-defaults | |||
The optional system-wide equivalent of $HOME/.vnc/config. If this file exists | |||
and defines options to be passed to Xvnc, they will be used as defaults for | |||
users. The user's $HOME/.vnc/config overrides settings configured in this file. | |||
The overall configuration file load order is: this file, $HOME/.vnc/config, | |||
and then @CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-mandatory. None are required to exist. | |||
\fI@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-defaults\fP | |||
The optional system-wide equivalent of \fI$HOME/.config/tigervnc/config\fP. | |||
If this file exists and defines options to be passed to Xvnc, they will be used | |||
as defaults for users. The user's \fI$HOME/.config/tigervnc/config\fP overrides | |||
settings configured in this file. The overall configuration file load order is: | |||
this file, \fI$HOME/.config/tigervnc/config\fP, and then | |||
\fI@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-mandatory\fP. | |||
None are required to exist. | |||
.TP | |||
@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-mandatory | |||
The optional system-wide equivalent of $HOME/.vnc/config. If this file exists | |||
and defines options to be passed to Xvnc, they will override any of the same | |||
options defined in a user's $HOME/.vnc/config. This file offers a mechanism | |||
to establish some basic form of system-wide policy. WARNING! There is | |||
nothing stopping users from constructing their own vncsession-like script | |||
that calls Xvnc directly to bypass any options defined in | |||
@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-mandatory. The overall configuration file load | |||
order is: @CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then | |||
this file. None are required to exist. | |||
\fI@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-mandatory\fP | |||
The optional system-wide equivalent of \fI$HOME/.config/tigervnc/config\fP. | |||
If this file exists and defines options to be passed to Xvnc, they will override | |||
any of the same options defined in a user's \fI$HOME/.config/tigervnc/config\fP. | |||
This file offers a mechanism to establish some basic form of system-wide policy. | |||
WARNING! There is nothing stopping users from constructing their own | |||
vncsession-like script that calls Xvnc directly to bypass any options defined in | |||
\fI@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-mandatory\fP. The | |||
overall configuration file load order is: | |||
\fI@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver-config-defaults\fP, | |||
\fI$HOME/.config/tigervnc/config\fP, and then this file. None are required to | |||
exist. | |||
.TP | |||
$HOME/.vnc/config | |||
\fI$XDG_CONFIG_HOME/tigervnc/config\fP | |||
.TQ | |||
\fI$HOME/.config/tigervnc/config\fP | |||
An optional server config file wherein options to be passed to Xvnc are listed | |||
to avoid hard-coding them to the physical invocation. List options in this file | |||
one per line. For those requiring an argument, simply separate the option from | |||
@@ -61,10 +67,14 @@ can be used to control which session type will be started. This should match | |||
one of the files in \fI/usr/share/xsessions\fP. E.g. if there is a file called | |||
"gnome.desktop", then "session=gnome" would be set to use that session type. | |||
.TP | |||
$HOME/.vnc/passwd | |||
\fI$XDG_CONFIG_HOME/tigervnc/passwd\fP | |||
.TQ | |||
\fI$HOME/.config/tigervnc/passwd\fP | |||
The VNC password file. | |||
.TP | |||
$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log | |||
\fI$XDG_STATE_HOME/tigervnc/\fIBhost\fI:\fIBdisplay#\fI.log\fP | |||
.TQ | |||
\fI$HOME/.local/state/tigervnc/\fIBhost\fI:\fIBdisplay#\fI.log\fP | |||
The log file for Xvnc and the session. | |||
.SH SEE ALSO |
@@ -367,7 +367,7 @@ and -once, the Xvnc and associated X clients will die when the user logs out of | |||
the X session in the normal way. It is important to use a VNC password in this | |||
case. A typical entry in inetd.conf might be: | |||
5951 stream tcp wait james /usr/local/bin/Xvnc Xvnc -inetd -query localhost -once passwordFile=/home/james/.vnc/passwd | |||
5951 stream tcp wait james /usr/local/bin/Xvnc Xvnc -inetd -query localhost -once passwordFile=/home/james/.config/tigervnc/passwd | |||
In fact typically, you would have one entry for each user who uses VNC | |||
regularly, each of whom has their own dedicated TCP port which they use. In |
@@ -1,3 +1,4 @@ | |||
vncviewer | |||
vncviewer.desktop.in | |||
vncviewer.desktop | |||
org.tigervnc.vncviewer.metainfo.xml |
@@ -745,13 +745,18 @@ int main(int argc, char** argv) | |||
migrateDeprecatedOptions(); | |||
char *confdir = strdup(os::getvncconfigdir()); | |||
#ifndef WIN32 | |||
// Check if config and state dirs are both the same legacy ~/.vnc dir | |||
struct stat st; | |||
if (stat(os::getvnchomedir(), &st) == 0) | |||
vlog.info(_("~/.vnc is deprecated, please migrate to XDGBDS-compliant paths!")); | |||
char *dotdir = strrchr(confdir, '.'); | |||
if (dotdir != NULL && strcmp(dotdir, ".vnc") == 0) | |||
vlog.info(_("~/.vnc is deprecated, please consult 'man vncviewer' for paths to migrate to.")); | |||
#else | |||
char *vncdir = strrchr(confdir, '\\'); | |||
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()); | |||
CSecurity::upg = &dlg; |
@@ -147,19 +147,22 @@ every supported scheme. | |||
.B \-passwd, \-PasswordFile \fIpassword-file\fP | |||
If you are on a filesystem which gives you access to the password file used by | |||
the server, you can specify it here to avoid typing it in. It will usually be | |||
"~/.vnc/passwd". | |||
\fI$XDG_CONFIG_HOME/tigervnc/passwd\fP, or \fI~/.config/tigervnc/passwd\fP | |||
if the former is unset. | |||
. | |||
.TP | |||
.B \-X509CA \fIpath\fP | |||
Path to CA certificate to use when authenticating remote servers using any | |||
of the X509 security schemes (X509None, X509Vnc, etc.). Must be in PEM | |||
format. Default is \fB$HOME/.vnc/x509_ca.pem\fP. | |||
format. Default is \fI$XDG_CONFIG_HOME/tigervnc/x509_ca.pem\fP, or | |||
\fI~/.config/tigervnc/x509_ca.pem\fP. | |||
. | |||
.TP | |||
.B \-X509CRL \fIpath\fP | |||
Path to certificate revocation list to use in conjunction with | |||
\fB-X509CA\fP. Must also be in PEM format. Default is | |||
\fB$HOME/.vnc/x509_crl.pem\fP. | |||
\fI$XDG_CONFIG_HOME/tigervnc/x509_crl.pem\fP, or | |||
\fI~/.config/tigervnc/x509_crl.pem\fP. | |||
. | |||
.TP | |||
.B \-Shared | |||
@@ -338,17 +341,33 @@ re-connect will be offered. Default is on. | |||
.SH FILES | |||
.TP | |||
$HOME/.vnc/default.tigervnc | |||
\fI$XDG_CONFIG_HOME/tigervnc/default.tigervnc\fP | |||
.TQ | |||
\fI$HOME/.config/tigervnc/default.tigervnc\fP | |||
Default configuration options. This file must have a "magic" first line of | |||
"TigerVNC Configuration file Version 1.0" (without quotes), followed by simple | |||
<setting>=<value> pairs of your choosing. The available settings are those | |||
shown in this man page. | |||
.TP | |||
$HOME/.vnc/x509_ca.pem | |||
\fI$XDG_CONFIG_HOME/tigervnc/x509_ca.pem\fP | |||
.TQ | |||
\fI$HOME/.config/tigervnc/x509_ca.pem\fP | |||
Default CA certificate for authenticating servers. | |||
.TP | |||
$HOME/.vnc/x509_crl.pem | |||
\fI$XDG_CONFIG_HOME/tigervnc/x509_crl.pem\fP | |||
.TQ | |||
\fI$HOME/.config/tigervnc/x509_crl.pem\fP | |||
Default certificate revocation list. | |||
.TP | |||
\fI$XDG_DATA_HOME/tigervnc/x509_known_hosts\fP | |||
.TQ | |||
\fI$HOME/.local/share/tigervnc/x509_known_hosts\fP | |||
Known hosts database for certificate-based authentication. | |||
.TP | |||
\fI$XDG_STATE_HOME/tigervnc/tigervnc.history\fP | |||
.TQ | |||
\fI$HOME/.local/state/tigervnc/tigervnc.history\fP | |||
History file for hostnames that have been recently connected to. | |||
.SH SEE ALSO | |||
.BR Xvnc (1), |