1 // Functions which allow the client to remember usernames and passwords for various sites.
3 // Copyright (c) 1987-2023 by the citadel.org team
5 // This program is open source software. Use, duplication, or disclosure is subject to the GNU General Public License version 3.
7 #include "textclient.h"
9 #define PWFILENAME "%s/.citadel.passwords"
11 void determine_pwfilename(char *pwfile, size_t n) {
14 p = getpwuid(getuid());
17 snprintf(pwfile, n, PWFILENAME, p->pw_dir);
21 // Check the password file for a host/port match; if found, stuff the user
22 // name and password into the user/pass buffers
23 void get_stored_password(char *host, char *port, char *username, char *password) {
25 char pwfile[PATH_MAX];
29 char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
34 determine_pwfilename(pwfile, sizeof pwfile);
35 if (IsEmptyStr(pwfile))
38 fp = fopen(pwfile, "r");
42 while (fgets(buf64, sizeof buf64, fp) != NULL) {
43 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
44 extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
45 extract_token(portbuf, buf, 1, '|', sizeof portbuf);
46 extract_token(ubuf, buf, 2, '|', sizeof ubuf);
47 extract_token(pbuf, buf, 3, '|', sizeof pbuf);
49 if (!strcasecmp(hostbuf, host)) {
50 if (!strcasecmp(portbuf, port)) {
51 strcpy(username, ubuf);
52 strcpy(password, pbuf);
60 // Set (or clear) stored passwords.
61 void set_stored_password(char *host, char *port, char *username, char *password) {
63 char pwfile[PATH_MAX];
67 char hostbuf[256], portbuf[256], ubuf[256], pbuf[256];
69 determine_pwfilename(pwfile, sizeof pwfile);
70 if (IsEmptyStr(pwfile))
73 oldfp = fopen(pwfile, "r");
75 oldfp = fopen("/dev/null", "r");
78 fp = fopen(pwfile, "w");
80 fp = fopen("/dev/null", "w");
82 while (fgets(buf64, sizeof buf64, oldfp) != NULL) {
83 CtdlDecodeBase64(buf, buf64, sizeof(buf64));
84 extract_token(hostbuf, buf, 0, '|', sizeof hostbuf);
85 extract_token(portbuf, buf, 1, '|', sizeof portbuf);
86 extract_token(ubuf, buf, 2, '|', sizeof ubuf);
87 extract_token(pbuf, buf, 3, '|', sizeof pbuf);
89 if ((strcasecmp(hostbuf, host)) || (strcasecmp(portbuf, port))) {
90 snprintf(buf, sizeof buf, "%s|%s|%s|%s|", hostbuf, portbuf, ubuf, pbuf);
91 CtdlEncodeBase64(buf64, buf, strlen(buf), BASE64_NO_LINEBREAKS);
92 fprintf(fp, "%s\n", buf64);
95 if (!IsEmptyStr(username)) {
96 snprintf(buf, sizeof buf, "%s|%s|%s|%s|", host, port, username, password);
97 CtdlEncodeBase64(buf64, buf, strlen(buf), BASE64_NO_LINEBREAKS);
98 fprintf(fp, "%s\n", buf64);
106 // Set the password if the user wants to, clear it otherwise
107 void offer_to_remember_password(CtdlIPC * ipc, char *host, char *port, char *username, char *password) {
109 if (rc_remember_passwords) {
110 if (boolprompt("Remember username/password for this site", 0)) {
111 set_stored_password(host, port, username, password);
114 set_stored_password(host, port, "", "");