]> diplodocus.org Git - nmh/blobdiff - sbr/credentials.c
configure.ac: Enable assert(3) by default.
[nmh] / sbr / credentials.c
index 9f3faa95eec3ee6c2efc872006167275436ab4cc..b34b967395949dbca85ec8ab742fbc9a8c339289 100644 (file)
@@ -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.
@@ -8,6 +9,12 @@
 #include <h/utils.h>
 #include <h/mts.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 () {
     if (credentials_file == NULL) {
@@ -17,9 +24,10 @@ 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 ((unsigned char) *filename)) ++filename;
 
@@ -31,30 +39,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")) {
-        if (sasl) {
-            /* This is what inc.c and msgchk.c used to contain. */
-            /* Only inc.c and msgchk.c do this.  smtp.c doesn't. */
-            creds->user = user == NULL  ?  getusername ()  :  user;
-            creds->password = getusername ();
-        }
-    } 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
@@ -63,12 +78,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;
+        creds->user = user == NULL ? NULL : mh_xstrdup(user);
     } else {
-        admonish (NULL, "unknown credentials style %s", cred_style);
-        return NOTOK;
+        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)
+{
+    mh_xfree(creds->host);
+    mh_xfree(creds->user);
+
+    if (creds->pass) {
+       memset(creds->pass, 0, strlen(creds->pass));
+       free(creds->pass);
     }
 
-    ruserpass (host, &creds->user, &creds->password);
-    return OK;
+    free(creds);
 }