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