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