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