]> diplodocus.org Git - nmh/blob - sbr/credentials.c
mhbuildsbr.c: Flip logic, moving goto to then-block; no need for else.
[nmh] / sbr / credentials.c
1 /* credentials.c -- wrap configurable access to .netrc or similar files.
2 *
3 * This code is Copyright (c) 2013, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h>
9 #include <h/utils.h>
10 #include <h/mts.h>
11 #include "m_maildir.h"
12
13 struct nmh_creds {
14 char *host; /* Hostname corresponding to credentials */
15 char *user; /* Username corresponding to credentials */
16 char *pass; /* (Optional) password used by credentials */
17 };
18
19 void
20 init_credentials_file(void) {
21 if (credentials_file == NULL) {
22 char *cred_style = context_find ("credentials");
23
24 if (cred_style == NULL || ! strcmp (cred_style, "legacy")) {
25 char *hdir = getenv ("HOME");
26
27 credentials_file = concat (hdir ? hdir : ".", "/.netrc", NULL);
28 } else if (! strncasecmp (cred_style, "file:", 5) ||
29 ! strncasecmp (cred_style, "file-nopermcheck:", 17)) {
30 struct stat st;
31 char *filename = strchr(cred_style, ':') + 1;
32
33 while (*filename && isspace ((unsigned char) *filename)) ++filename;
34
35 if (*filename == '/') {
36 credentials_file = filename;
37 } else {
38 credentials_file = m_maildir (filename);
39 if (stat (credentials_file, &st) != OK) {
40 credentials_file =
41 concat (mypath ? mypath : ".", "/", filename, NULL);
42 if (stat (credentials_file, &st) != OK) {
43 inform("unable to find credentials file %s, continuing...",
44 filename);
45 }
46 }
47 }
48
49 if (! strncasecmp (cred_style, "file-nopermcheck:", 17))
50 credentials_no_perm_check = 1;
51 }
52 }
53 }
54
55 nmh_creds_t
56 nmh_get_credentials (const char *host, const char *user)
57 {
58 nmh_creds_t creds;
59
60 char *cred_style = context_find ("credentials");
61
62 init_credentials_file ();
63
64 creds = mh_xmalloc(sizeof(*creds));
65
66 creds->host = mh_xstrdup(host);
67 creds->user = NULL;
68 creds->pass = NULL;
69
70 if (cred_style == NULL || ! strcmp (cred_style, "legacy")) {
71 creds->user = user == NULL ? mh_xstrdup(getusername ()) : mh_xstrdup(user);
72 } else if (! strncasecmp (cred_style, "file:", 5) ||
73 ! strncasecmp (cred_style, "file-nopermcheck:", 17)) {
74 /*
75 * Determine user using the first of:
76 * 1) -user switch
77 * 2) matching host entry with login in a credentials file
78 * such as ~/.netrc
79 * 3) interactively request from user (as long as the
80 * credentials file didn't have a "default" token)
81 */
82 creds->user = user == NULL ? NULL : mh_xstrdup(user);
83 } else {
84 inform("unknown credentials style %s, continuing...", cred_style);
85 return NULL;
86 }
87
88 ruserpass(creds->host, &creds->user, &creds->pass,
89 RUSERPASS_NO_PROMPT_USER | RUSERPASS_NO_PROMPT_PASSWORD);
90
91 return creds;
92 }
93
94 /*
95 * Retrieve the username
96 */
97
98 const char *
99 nmh_cred_get_user(nmh_creds_t creds)
100 {
101 if (! creds->user) {
102 ruserpass(creds->host, &creds->user, &creds->pass,
103 RUSERPASS_NO_PROMPT_PASSWORD);
104 }
105
106 return creds->user;
107 }
108
109 /*
110 * Retrieve the password
111 */
112
113 const char *
114 nmh_cred_get_password(nmh_creds_t creds)
115 {
116 if (! creds->pass) {
117 ruserpass(creds->host, &creds->user, &creds->pass, 0);
118 }
119
120 return creds->pass;
121 }
122
123 /*
124 * Free our credentials
125 */
126
127 void
128 nmh_credentials_free(nmh_creds_t creds)
129 {
130 mh_xfree(creds->host);
131 mh_xfree(creds->user);
132
133 if (creds->pass) {
134 memset(creds->pass, 0, strlen(creds->pass));
135 free(creds->pass);
136 }
137
138 free(creds);
139 }