1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

For convenience of debugging, and perhaps some real convenience at

some point too: introduce a bunch of environment variables which can
override Unix PuTTY's usual idea of where to find its dotfiles.
Setting PUTTYDIR moves the entire ~/.putty directory; setting
PUTTYSESSIONS, PUTTYSSHHOSTKEYS or PUTTYRANDOMSEED move specific
things within that directory.

While I'm here, also be prepared to fall back to password file
lookups if $HOME is undefined (though we still use $HOME in
preference when it is defined, because that's polite and useful).
Also, on general principles, tweak the make_filename() function
prototype so it doesn't rely on fixed-size buffers.

[originally from svn r7934]
This commit is contained in:
Simon Tatham 2008-03-22 12:01:16 +00:00
parent d7eda6d99c
commit 087adb167e

View File

@ -15,6 +15,7 @@
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include "putty.h"
#include "storage.h"
#include "tree234.h"
@ -87,36 +88,78 @@ static char *unmungestr(const char *in)
return ret;
}
static void make_filename(char *filename, int index, const char *subname)
static char *make_filename(int index, const char *subname)
{
char *home;
int len;
home = getenv("HOME");
if (!home)
home="/";
strncpy(filename, home, FNLEN);
len = strlen(filename);
char *env, *tmp, *ret;
/*
* Allow override of the PuTTY configuration location, and of
* specific subparts of it, by means of environment variables.
*/
if (index == INDEX_DIR) {
struct passwd *pwd;
env = getenv("PUTTYDIR");
if (env)
return dupstr(env);
env = getenv("HOME");
if (env)
return dupprintf("%s/.putty", env);
pwd = getpwuid(getuid());
if (pwd && pwd->pw_dir)
return dupprintf("%s/.putty", pwd->pw_dir);
return dupstr("/.putty");
}
if (index == INDEX_SESSIONDIR) {
env = getenv("PUTTYSESSIONS");
if (env)
return dupstr(env);
tmp = make_filename(INDEX_DIR, NULL);
ret = dupprintf("%s/sessions", tmp);
sfree(tmp);
return ret;
}
if (index == INDEX_SESSION) {
char *munged = mungestr(subname);
char *fn = dupprintf("/.putty/sessions/%s", munged);
strncpy(filename + len, fn, FNLEN - len);
sfree(fn);
sfree(munged);
} else {
strncpy(filename + len,
index == INDEX_DIR ? "/.putty" :
index == INDEX_SESSIONDIR ? "/.putty/sessions" :
index == INDEX_HOSTKEYS ? "/.putty/sshhostkeys" :
index == INDEX_HOSTKEYS_TMP ? "/.putty/sshhostkeys.tmp" :
index == INDEX_RANDSEED ? "/.putty/randomseed" :
"/.putty/ERROR", FNLEN - len);
tmp = make_filename(INDEX_SESSIONDIR, NULL);
ret = dupprintf("%s/%s", tmp, munged);
sfree(tmp);
sfree(munged);
return ret;
}
filename[FNLEN-1] = '\0';
if (index == INDEX_HOSTKEYS) {
env = getenv("PUTTYSSHHOSTKEYS");
if (env)
return dupstr(env);
tmp = make_filename(INDEX_DIR, NULL);
ret = dupprintf("%s/sshhostkeys", tmp);
sfree(tmp);
return ret;
}
if (index == INDEX_HOSTKEYS_TMP) {
tmp = make_filename(INDEX_HOSTKEYS, NULL);
ret = dupprintf("%s.tmp", tmp);
sfree(tmp);
return ret;
}
if (index == INDEX_RANDSEED) {
env = getenv("PUTTYRANDOMSEED");
if (env)
return dupstr(env);
tmp = make_filename(INDEX_DIR, NULL);
ret = dupprintf("%s/randomseed", tmp);
sfree(tmp);
return ret;
}
tmp = make_filename(INDEX_DIR, NULL);
ret = dupprintf("%s/ERROR", tmp);
sfree(tmp);
return ret;
}
void *open_settings_w(const char *sessionname, char **errmsg)
{
char filename[FNLEN];
char *filename;
FILE *fp;
*errmsg = NULL;
@ -128,18 +171,24 @@ void *open_settings_w(const char *sessionname, char **errmsg)
* other error will trip us up later on so there's no real need
* to catch it now.
*/
make_filename(filename, INDEX_DIR, sessionname);
mkdir(filename, 0700);
make_filename(filename, INDEX_SESSIONDIR, sessionname);
mkdir(filename, 0700);
filename = make_filename(INDEX_SESSIONDIR, NULL);
if (!mkdir(filename, 0700)) {
char *filename2 = make_filename(INDEX_DIR, NULL);
mkdir(filename2, 0700);
sfree(filename2);
mkdir(filename, 0700);
}
sfree(filename);
make_filename(filename, INDEX_SESSION, sessionname);
filename = make_filename(INDEX_SESSION, sessionname);
fp = fopen(filename, "w");
if (!fp) {
*errmsg = dupprintf("Unable to create %s: %s",
filename, strerror(errno));
sfree(filename);
return NULL; /* can't open */
}
sfree(filename);
return fp;
}
@ -233,13 +282,14 @@ const char *get_setting(const char *key)
void *open_settings_r(const char *sessionname)
{
char filename[FNLEN];
char *filename;
FILE *fp;
char *line;
tree234 *ret;
make_filename(filename, INDEX_SESSION, sessionname);
filename = make_filename(INDEX_SESSION, sessionname);
fp = fopen(filename, "r");
sfree(filename);
if (!fp)
return NULL; /* can't open */
@ -348,18 +398,20 @@ void close_settings_r(void *handle)
void del_settings(const char *sessionname)
{
char filename[FNLEN];
make_filename(filename, INDEX_SESSION, sessionname);
char *filename;
filename = make_filename(INDEX_SESSION, sessionname);
unlink(filename);
sfree(filename);
}
void *enum_settings_start(void)
{
DIR *dp;
char filename[FNLEN];
char *filename;
make_filename(filename, INDEX_SESSIONDIR, NULL);
filename = make_filename(INDEX_SESSIONDIR, NULL);
dp = opendir(filename);
sfree(filename);
return dp;
}
@ -369,19 +421,22 @@ char *enum_settings_next(void *handle, char *buffer, int buflen)
DIR *dp = (DIR *)handle;
struct dirent *de;
struct stat st;
char fullpath[FNLEN];
int len;
char *fullpath;
int maxlen, thislen, len;
char *unmunged;
make_filename(fullpath, INDEX_SESSIONDIR, NULL);
len = strlen(fullpath);
fullpath = make_filename(INDEX_SESSIONDIR, NULL);
maxlen = len = strlen(fullpath);
while ( (de = readdir(dp)) != NULL ) {
if (len < FNLEN) {
fullpath[len] = '/';
strncpy(fullpath+len+1, de->d_name, FNLEN-(len+1));
fullpath[FNLEN-1] = '\0';
}
thislen = len + 1 + strlen(de->d_name);
if (maxlen < thislen) {
maxlen = thislen;
fullpath = sresize(fullpath, maxlen+1, char);
}
fullpath[len] = '/';
strncpy(fullpath+len+1, de->d_name, thislen - (len+1));
fullpath[thislen] = '\0';
if (stat(fullpath, &st) < 0 || !S_ISREG(st.st_mode))
continue; /* try another one */
@ -390,9 +445,11 @@ char *enum_settings_next(void *handle, char *buffer, int buflen)
strncpy(buffer, unmunged, buflen);
buffer[buflen-1] = '\0';
sfree(unmunged);
sfree(fullpath);
return buffer;
}
sfree(fullpath);
return NULL;
}
@ -415,12 +472,13 @@ int verify_host_key(const char *hostname, int port,
const char *keytype, const char *key)
{
FILE *fp;
char filename[FNLEN];
char *filename;
char *line;
int ret;
make_filename(filename, INDEX_HOSTKEYS, NULL);
filename = make_filename(INDEX_HOSTKEYS, NULL);
fp = fopen(filename, "r");
sfree(filename);
if (!fp)
return 1; /* key does not exist */
@ -485,7 +543,7 @@ void store_host_key(const char *hostname, int port,
FILE *rfp, *wfp;
char *newtext, *line;
int headerlen;
char filename[FNLEN], tmpfilename[FNLEN];
char *filename, *tmpfilename;
newtext = dupprintf("%s@%d:%s %s\n", keytype, port, hostname, key);
headerlen = 1 + strcspn(newtext, " "); /* count the space too */
@ -493,18 +551,22 @@ void store_host_key(const char *hostname, int port,
/*
* Open both the old file and a new file.
*/
make_filename(tmpfilename, INDEX_HOSTKEYS_TMP, NULL);
tmpfilename = make_filename(INDEX_HOSTKEYS_TMP, NULL);
wfp = fopen(tmpfilename, "w");
if (!wfp) {
char dir[FNLEN];
char *dir;
make_filename(dir, INDEX_DIR, NULL);
dir = make_filename(INDEX_DIR, NULL);
mkdir(dir, 0700);
sfree(dir);
wfp = fopen(tmpfilename, "w");
}
if (!wfp)
if (!wfp) {
sfree(tmpfilename);
return;
make_filename(filename, INDEX_HOSTKEYS, NULL);
}
filename = make_filename(INDEX_HOSTKEYS, NULL);
rfp = fopen(filename, "r");
/*
@ -528,16 +590,19 @@ void store_host_key(const char *hostname, int port,
rename(tmpfilename, filename);
sfree(tmpfilename);
sfree(filename);
sfree(newtext);
}
void read_random_seed(noise_consumer_t consumer)
{
int fd;
char fname[FNLEN];
char *fname;
make_filename(fname, INDEX_RANDSEED, NULL);
fname = make_filename(INDEX_RANDSEED, NULL);
fd = open(fname, O_RDONLY);
sfree(fname);
if (fd) {
char buf[512];
int ret;
@ -550,9 +615,9 @@ void read_random_seed(noise_consumer_t consumer)
void write_random_seed(void *data, int len)
{
int fd;
char fname[FNLEN];
char *fname;
make_filename(fname, INDEX_RANDSEED, NULL);
fname = make_filename(INDEX_RANDSEED, NULL);
/*
* Don't truncate the random seed file if it already exists; if
* something goes wrong half way through writing it, it would
@ -560,10 +625,12 @@ void write_random_seed(void *data, int len)
*/
fd = open(fname, O_CREAT | O_WRONLY, 0600);
if (fd < 0) {
char dir[FNLEN];
char *dir;
make_filename(dir, INDEX_DIR, NULL);
dir = make_filename(INDEX_DIR, NULL);
mkdir(dir, 0700);
sfree(dir);
fd = open(fname, O_CREAT | O_WRONLY, 0600);
}
@ -575,6 +642,7 @@ void write_random_seed(void *data, int len)
}
close(fd);
sfree(fname);
}
void cleanup_all(void)