X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=unix%2Fuxmisc.c;h=daa61a0193665909755938231c0d10a84ce703ba;hb=095072fa46b2d7b8beafaddb2f873d2f500a1e10;hp=b7727cb21cad41e74d98b9d45f7094b3cfa4dea4;hpb=5c76a93a44bdd0d6d15e644176a0257d9ce7bf9b;p=PuTTY.git diff --git a/unix/uxmisc.c b/unix/uxmisc.c index b7727cb2..daa61a01 100644 --- a/unix/uxmisc.c +++ b/unix/uxmisc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "putty.h" @@ -104,7 +105,7 @@ char filename_char_sanitise(char c) #ifdef DEBUG static FILE *debug_fp = NULL; -void dputs(char *buf) +void dputs(const char *buf) { if (!debug_fp) { debug_fp = fopen("debug.log", "w"); @@ -290,3 +291,61 @@ FontSpec *fontspec_deserialise(void *vdata, int maxsize, int *used) *used = end - data + 1; return fontspec_new(data); } + +char *make_dir_and_check_ours(const char *dirname) +{ + struct stat st; + + /* + * Create the directory. We might have created it before, so + * EEXIST is an OK error; but anything else is doom. + */ + if (mkdir(dirname, 0700) < 0 && errno != EEXIST) + return dupprintf("%s: mkdir: %s", dirname, strerror(errno)); + + /* + * Now check that that directory is _owned by us_ and not writable + * by anybody else. This protects us against somebody else + * previously having created the directory in a way that's + * writable to us, and thus manipulating us into creating the + * actual socket in a directory they can see so that they can + * connect to it and use our authenticated SSH sessions. + */ + if (stat(dirname, &st) < 0) + return dupprintf("%s: stat: %s", dirname, strerror(errno)); + if (st.st_uid != getuid()) + return dupprintf("%s: directory owned by uid %d, not by us", + dirname, st.st_uid); + if ((st.st_mode & 077) != 0) + return dupprintf("%s: directory has overgenerous permissions %03o" + " (expected 700)", dirname, st.st_mode & 0777); + + return NULL; +} + +char *make_dir_path(const char *path, mode_t mode) +{ + int pos = 0; + char *prefix; + + while (1) { + pos += strcspn(path + pos, "/"); + + if (pos > 0) { + prefix = dupprintf("%.*s", pos, path); + + if (mkdir(prefix, mode) < 0 && errno != EEXIST) { + char *ret = dupprintf("%s: mkdir: %s", + prefix, strerror(errno)); + sfree(prefix); + return ret; + } + + sfree(prefix); + } + + if (!path[pos]) + return NULL; + pos += strspn(path + pos, "/"); + } +}