X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/52a236230220232fd632b5aa88eb9bb31dba346e..94187a80bd60baab4b9c4b949ad820d730578123:/sbr/credentials.c diff --git a/sbr/credentials.c b/sbr/credentials.c index 9d4e41c2..b610b2b9 100644 --- a/sbr/credentials.c +++ b/sbr/credentials.c @@ -1,4 +1,5 @@ -/* +/* credentials.c -- wrap configurable access to .netrc or similar files. + * * This code is Copyright (c) 2013, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for * complete copyright information. @@ -7,9 +8,16 @@ #include #include #include +#include "m_maildir.h" + +struct nmh_creds { + char *host; /* Hostname corresponding to credentials */ + char *user; /* Username corresponding to credentials */ + char *pass; /* (Optional) password used by credentials */ +}; void -init_credentials_file () { +init_credentials_file(void) { if (credentials_file == NULL) { char *cred_style = context_find ("credentials"); @@ -17,11 +25,13 @@ init_credentials_file () { char *hdir = getenv ("HOME"); credentials_file = concat (hdir ? hdir : ".", "/.netrc", NULL); - } else if (! strncasecmp (cred_style, "file:", 5)) { + } else if (! strncasecmp (cred_style, "file:", 5) || + ! strncasecmp (cred_style, "file-nopermcheck:", 17)) { struct stat st; - char *filename = cred_style + 5; + char *filename = strchr(cred_style, ':') + 1; - while (*filename && isspace ((int) *filename)) ++filename; + while (isspace((unsigned char)*filename)) + filename++; if (*filename == '/') { credentials_file = filename; @@ -31,33 +41,37 @@ init_credentials_file () { credentials_file = concat (mypath ? mypath : ".", "/", filename, NULL); if (stat (credentials_file, &st) != OK) { - admonish (NULL, "unable to find credentials file %s", + inform("unable to find credentials file %s, continuing...", filename); } } } + + if (! strncasecmp (cred_style, "file-nopermcheck:", 17)) + credentials_no_perm_check = 1; } } } -int -nmh_get_credentials (char *host, char *user, int sasl, nmh_creds_t creds) { +nmh_creds_t +nmh_get_credentials (const char *host, const char *user) +{ + nmh_creds_t creds; + char *cred_style = context_find ("credentials"); init_credentials_file (); - creds->host = host; + + creds = mh_xmalloc(sizeof(*creds)); + + creds->host = mh_xstrdup(host); + creds->user = NULL; + creds->pass = NULL; if (cred_style == NULL || ! strcmp (cred_style, "legacy")) { - /* This is what inc.c and msgchk.c used to contain. */ - if (user == NULL) { - creds->user = getusername (); - } - if (sasl) { - creds->password = getusername (); - } else { - ruserpass (host, &creds->user, &creds->password); - } - } else if (! strncasecmp (cred_style, "file:", 5)) { + creds->user = user == NULL ? mh_xstrdup(getusername ()) : mh_xstrdup(user); + } else if (! strncasecmp (cred_style, "file:", 5) || + ! strncasecmp (cred_style, "file-nopermcheck:", 17)) { /* * Determine user using the first of: * 1) -user switch @@ -66,9 +80,61 @@ nmh_get_credentials (char *host, char *user, int sasl, nmh_creds_t creds) { * 3) interactively request from user (as long as the * credentials file didn't have a "default" token) */ - creds->user = user; - ruserpass (host, &creds->user, &creds->password); + creds->user = user == NULL ? NULL : mh_xstrdup(user); + } else { + inform("unknown credentials style %s, continuing...", cred_style); + return NULL; + } + + ruserpass(creds->host, &creds->user, &creds->pass, + RUSERPASS_NO_PROMPT_USER | RUSERPASS_NO_PROMPT_PASSWORD); + + return creds; +} + +/* + * Retrieve the username + */ + +const char * +nmh_cred_get_user(nmh_creds_t creds) +{ + if (! creds->user) { + ruserpass(creds->host, &creds->user, &creds->pass, + RUSERPASS_NO_PROMPT_PASSWORD); + } + + return creds->user; +} + +/* + * Retrieve the password + */ + +const char * +nmh_cred_get_password(nmh_creds_t creds) +{ + if (! creds->pass) { + ruserpass(creds->host, &creds->user, &creds->pass, 0); + } + + return creds->pass; +} + +/* + * Free our credentials + */ + +void +nmh_credentials_free(nmh_creds_t creds) +{ + free(creds->host); + free(creds->user); + + if (creds->pass) { + memset(creds->pass, 0, strlen(creds->pass)); + free(creds->pass); } - return OK; + free(creds); }