From 31a00d664715fb4c7b90c1617a3b4c2580282d7b Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 10 Sep 2013 21:57:07 -0400 Subject: [PATCH] ISPATHSEP and ISTILDE macros; Windows portability Windows treats '\\' and '/' equivalently but we cannot control the form that will be used by end users. Introduce ISPATHSEP() macro which tests only for '/' on UNIX and both on Windows. Introduce ISTILDE() macro to test for '~'. When testing for '/' with strchr() or strrchr() add conditional checks for '\\' on Windows. Change-Id: Ia85e698fc88f15a6a71db649db5417f02ef7e5fe --- lib/krb5/cache.c | 2 +- lib/krb5/config_file.c | 2 +- lib/krb5/dcache.c | 10 +++++++--- lib/krb5/keytab.c | 2 +- lib/krb5/krb5_locl.h | 7 +++++++ lib/krb5/log.c | 11 ++++++++++- lib/krb5/plugin.c | 4 ++++ lib/krb5/verify_krb5_conf.c | 11 ++++++++++- 8 files changed, 41 insertions(+), 8 deletions(-) diff --git a/lib/krb5/cache.c b/lib/krb5/cache.c index 12e066715..815200e0e 100644 --- a/lib/krb5/cache.c +++ b/lib/krb5/cache.c @@ -979,7 +979,7 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix) if (prefix == NULL) return KRB5_DEFAULT_CCTYPE; - if (prefix[0] == '/') + if (ISPATHSEP(prefix[0])) return &krb5_fcc_ops; p = strdup(prefix); diff --git a/lib/krb5/config_file.c b/lib/krb5/config_file.c index c1f80e2bb..d7045272f 100644 --- a/lib/krb5/config_file.c +++ b/lib/krb5/config_file.c @@ -425,7 +425,7 @@ krb5_config_parse_file_multi (krb5_context context, * current users home directory. The behavior can be disabled and * enabled by calling krb5_set_home_dir_access(). */ - if (fname[0] == '~' && fname[1] == '/') { + if (ISTILDE(fname[0]) && ISPATHSEP(fname[1])) { #ifndef KRB5_USE_PATH_TOKENS const char *home = NULL; diff --git a/lib/krb5/dcache.c b/lib/krb5/dcache.c index 5711846c8..61a97a89d 100644 --- a/lib/krb5/dcache.c +++ b/lib/krb5/dcache.c @@ -256,8 +256,8 @@ dcc_resolve(krb5_context context, krb5_ccache *id, const char *res) p = res; do { - p = strstr(p, "/.."); - if (p && (p[3] == '/' || p[3] == '\0')) { + p = strstr(p, ".."); + if (p && (p == res || ISPATHSEP(p[-1])) && (ISPATHSEP(p[2]) || p[2] == '\0')) { krb5_set_error_message(context, KRB5_CC_FORMAT, N_("Path contains a .. component", "")); return KRB5_CC_FORMAT; @@ -278,6 +278,10 @@ dcc_resolve(krb5_context context, krb5_ccache *id, const char *res) char *q; dc->dir = strdup(&res[1]); +#ifdef _WIN32 + q = strrchr(dc->dir, '\\'); + if (q == NULL) +#endif q = strrchr(dc->dir, '/'); if (q) { *q++ = '\0'; @@ -318,7 +322,7 @@ dcc_resolve(krb5_context context, krb5_ccache *id, const char *res) len = strlen(dc->dir); - if (dc->dir[len - 1] == '/') + if (ISPATHSEP(dc->dir[len - 1])) dc->dir[len - 1] = '\0'; ret = verify_directory(context, dc->dir); diff --git a/lib/krb5/keytab.c b/lib/krb5/keytab.c index 3c2df10a7..9cebe8d70 100644 --- a/lib/krb5/keytab.c +++ b/lib/krb5/keytab.c @@ -170,7 +170,7 @@ keytab_name(const char *name, const char **type, size_t *type_len) residual = strchr(name, ':'); if (residual == NULL || - name[0] == '/' + ISPATHSEP(name[0]) #ifdef _WIN32 /* Avoid treating : as a keytab type * specification */ diff --git a/lib/krb5/krb5_locl.h b/lib/krb5/krb5_locl.h index 908d51358..7feeb0c72 100644 --- a/lib/krb5/krb5_locl.h +++ b/lib/krb5/krb5_locl.h @@ -375,4 +375,11 @@ enum krb5_pk_type { #endif /* PKINIT */ +#define ISTILDE(x) (x == '~') +#ifdef _WIN32 +# define ISPATHSEP(x) (x == '/' || x =='\\') +#else +# define ISPATHSEP(x) (x == '/') +#endif + #endif /* __KRB5_LOCL_H__ */ diff --git a/lib/krb5/log.c b/lib/krb5/log.c index e003a3c5c..2876096ec 100644 --- a/lib/krb5/log.c +++ b/lib/krb5/log.c @@ -271,10 +271,13 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) int min = 0, max = -1, n; char c; const char *p = orig; +#ifdef _WIN32 + const char *q; +#endif n = sscanf(p, "%d%c%d/", &min, &c, &max); if(n == 2){ - if(c == '/') { + if(ISPATHSEP(c)) { if(min < 0){ max = -min; min = 0; @@ -284,6 +287,12 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) } } if(n){ +#ifdef _WIN32 + q = strrchr(p, '\\'); + if (q != NULL) + p = q; + else +#endif p = strchr(p, '/'); if(p == NULL) { krb5_set_error_message(context, HEIM_ERR_LOG_PARSE, diff --git a/lib/krb5/plugin.c b/lib/krb5/plugin.c index 088ffb57c..f863ddb10 100644 --- a/lib/krb5/plugin.c +++ b/lib/krb5/plugin.c @@ -241,6 +241,10 @@ resolve_origin(const char *di) return strdup(LIBDIR "/plugin/krb5"); dname = dl_info.dli_fname; +#ifdef _WIN32 + p = strrchr(dname, '\\'); + if (p == NULL) +#endif p = strrchr(dname, '/'); if (p) *p = '\0'; diff --git a/lib/krb5/verify_krb5_conf.c b/lib/krb5/verify_krb5_conf.c index 68a0ef7d3..00952d782 100644 --- a/lib/krb5/verify_krb5_conf.c +++ b/lib/krb5/verify_krb5_conf.c @@ -289,10 +289,13 @@ check_log(krb5_context context, const char *path, char *data) int min = 0, max = -1, n; char c; const char *p = data; +#ifdef _WIN32 + const char *q; +#endif n = sscanf(p, "%d%c%d/", &min, &c, &max); if(n == 2){ - if(c == '/') { + if(ISPATHSEP(c)) { if(min < 0){ max = -min; min = 0; @@ -302,6 +305,12 @@ check_log(krb5_context context, const char *path, char *data) } } if(n){ +#ifdef _WIN32 + q = strrchr(p, '\\'); + if (q != NULL) + p = q; + else +#endif p = strchr(p, '/'); if(p == NULL) { krb5_warnx(context, "%s: failed to parse \"%s\"", path, data);