Updated the boilerplate on each file
[citadel.git] / textclient / client_passwords.c
1 // Functions which allow the client to remember usernames and passwords for
2 // various sites.
3 //
4 // Copyright (c) 1987-2016 by the citadel.org team
5 //
6 // This program is open source software.  Use, duplication, and/or
7 // disclosure are subject to the GNU General Purpose License version 3.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13
14 #include "textclient.h"
15
16 #define PWFILENAME "%s/.citadel.passwords"
17
18 void determine_pwfilename(char *pwfile, size_t n)
19 {
20         struct passwd *p;
21
22         p = getpwuid(getuid());
23         if (p == NULL)
24                 strcpy(pwfile, "");
25         snprintf(pwfile, n, PWFILENAME, p->pw_dir);
26 }
27
28
29 /*
30  * Check the password file for a host/port match; if found, stuff the user
31  * name and password into the user/pass buffers
32  */
33 void get_stored_password(char *host, char *port, char *username, char *password)
34 {
35
36         char pwfile[PATH_MAX];
37         FILE *fp;
38         char buf[SIZ];
39         char buf64[SIZ];
40         char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
41
42         strcpy(username, "");
43         strcpy(password, "");
44
45         determine_pwfilename(pwfile, sizeof pwfile);
46         if (IsEmptyStr(pwfile))
47                 return;
48
49         fp = fopen(pwfile, "r");
50         if (fp == NULL)
51                 return;
52         while (fgets(buf64, sizeof buf64, fp) != NULL) {
53                 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
54                 extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
55                 extract_token(portbuf, buf, 1, '|', sizeof portbuf);
56                 extract_token(ubuf, buf, 2, '|', sizeof ubuf);
57                 extract_token(pbuf, buf, 3, '|', sizeof pbuf);
58
59                 if (!strcasecmp(hostbuf, host)) {
60                         if (!strcasecmp(portbuf, port)) {
61                                 strcpy(username, ubuf);
62                                 strcpy(password, pbuf);
63                         }
64                 }
65         }
66         fclose(fp);
67 }
68
69
70 /*
71  * Set (or clear) stored passwords.
72  */
73 void set_stored_password(char *host, char *port, char *username, char *password)
74 {
75
76         char pwfile[PATH_MAX];
77         FILE *fp, *oldfp;
78         char buf[SIZ];
79         char buf64[SIZ];
80         char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
81
82         determine_pwfilename(pwfile, sizeof pwfile);
83         if (IsEmptyStr(pwfile))
84                 return;
85
86         oldfp = fopen(pwfile, "r");
87         if (oldfp == NULL)
88                 oldfp = fopen("/dev/null", "r");
89         unlink(pwfile);
90         fp = fopen(pwfile, "w");
91         if (fp == NULL)
92                 fp = fopen("/dev/null", "w");
93         while (fgets(buf64, sizeof buf64, oldfp) != NULL) {
94                 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
95                 extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
96                 extract_token(portbuf, buf, 1, '|', sizeof portbuf);
97                 extract_token(ubuf, buf, 2, '|', sizeof ubuf);
98                 extract_token(pbuf, buf, 3, '|', sizeof pbuf);
99
100                 if ((strcasecmp(hostbuf, host))
101                     || (strcasecmp(portbuf, port))) {
102                         snprintf(buf, sizeof buf, "%s|%s|%s|%s|", hostbuf, portbuf, ubuf, pbuf);
103                         CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
104                         fprintf(fp, "%s\n", buf64);
105                 }
106         }
107         if (!IsEmptyStr(username)) {
108                 snprintf(buf, sizeof buf, "%s|%s|%s|%s|", host, port, username, password);
109                 CtdlEncodeBase64(buf64, buf, strlen(buf), 0);
110                 fprintf(fp, "%s\n", buf64);
111         }
112         fclose(oldfp);
113         fclose(fp);
114         chmod(pwfile, 0600);
115 }
116
117
118 /*
119  * Set the password if the user wants to, clear it otherwise 
120  */
121 void offer_to_remember_password(CtdlIPC * ipc, char *host, char *port, char *username, char *password)
122 {
123
124         if (rc_remember_passwords) {
125                 if (boolprompt("Remember username/password for this site", 0)) {
126                         set_stored_password(host, port, username, password);
127                 } else {
128                         set_stored_password(host, port, "", "");
129                 }
130         }
131 }