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:
parent
d7eda6d99c
commit
087adb167e
180
unix/uxstore.c
180
unix/uxstore.c
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user