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