Skip to content

Commit

Permalink
Implement XDG Base Directory paths, deprecate ~/.vnc
Browse files Browse the repository at this point in the history
  • Loading branch information
62832 committed Apr 26, 2024
1 parent 119a5ff commit 337c136
Show file tree
Hide file tree
Showing 28 changed files with 292 additions and 174 deletions.
14 changes: 0 additions & 14 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
*.mo
*.la
*.lo
*.class
*.jar
.deps
.libs

Expand All @@ -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
54 changes: 28 additions & 26 deletions common/os/os.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,27 @@
#include <os/os.h>

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

#ifndef WIN32
#include <pwd.h>
#include <limits.h>
#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;
Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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");
}
24 changes: 12 additions & 12 deletions common/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

}

Expand Down
11 changes: 5 additions & 6 deletions common/rfb/CSecurityTLS.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion contrib/packages/rpm/el7/SOURCES/10-libvnc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
# Identifier "Screen0
# DefaultDepth 16
# Option "SecurityTypes" "VncAuth"
# Option "PasswordFile" "/root/.vnc/passwd"
# Option "PasswordFile" "/root/.config/tigervnc/passwd"
#EndSection
2 changes: 1 addition & 1 deletion contrib/packages/rpm/el8/SOURCES/10-libvnc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
# Identifier "Screen0
# DefaultDepth 16
# Option "SecurityTypes" "VncAuth"
# Option "PasswordFile" "/root/.vnc/passwd"
# Option "PasswordFile" "/root/.config/tigervnc/passwd"
#EndSection
2 changes: 1 addition & 1 deletion contrib/packages/rpm/el9/SOURCES/10-libvnc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
# Identifier "Screen0
# DefaultDepth 16
# Option "SecurityTypes" "VncAuth"
# Option "PasswordFile" "/root/.vnc/passwd"
# Option "PasswordFile" "/root/.config/tigervnc/passwd"
#EndSection
4 changes: 4 additions & 0 deletions java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.class
*.jar
.idea/
timestamp
9 changes: 4 additions & 5 deletions java/com/tigervnc/rfb/CSecurityTLS.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ public CSecurityTLS(boolean _anon)
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()
Expand Down 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.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");
}
}
Expand Down Expand Up @@ -356,7 +356,6 @@ public void checkServerTrusted(X509Certificate[] chain, String authType)
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);
Expand Down
48 changes: 38 additions & 10 deletions java/com/tigervnc/vncviewer/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

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");
Expand Down Expand Up @@ -56,21 +58,47 @@ public static final String getHomeDir() {
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);
Expand Down
18 changes: 1 addition & 17 deletions java/com/tigervnc/vncviewer/Parameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,6 @@ public static void saveViewerParameters(String filename, String servername) {
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;
}
Expand Down Expand Up @@ -385,16 +378,7 @@ public static String loadViewerParameters(String filename) throws Exception {

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;
}
Expand Down
Loading

0 comments on commit 337c136

Please sign in to comment.