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