Skip to content

Commit 030c350

Browse files
committed
pppd: Check that secrets files can't be tampered with by non-root processes
Check that files containing secrets used by a remote system to authenticate itself to this system could not be changed by a non-root process, that is, that the file and all directories in the real path to it are owned by root and not writable by group or other. The files that are checked in this way are: /etc/ppp/pap-secrets (or alternate location set by pap-secrets option) /etc/ppp/chap-secrets (ditto for chap-secrets option) /etc/ppp/srp-secrets /etc/ppp/eaptls-server /etc/ppp/eaptls-client Files specified using @/file syntax in a secrets file Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
1 parent 60392cf commit 030c350

File tree

1 file changed

+54
-15
lines changed

1 file changed

+54
-15
lines changed

pppd/auth.c

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,8 @@ check_passwd(int unit,
15451545
* Open the file of pap secrets and scan for a suitable secret
15461546
* for authenticating this user.
15471547
*/
1548-
filename = path_upapfile;
1548+
if (!ppp_check_access(path_upapfile, &filename, 0, 0))
1549+
return UPAP_AUTHNAK;
15491550
addrs = opts = NULL;
15501551
ret = UPAP_AUTHNAK;
15511552
f = fopen(filename, "r");
@@ -1587,6 +1588,7 @@ check_passwd(int unit,
15871588
}
15881589
fclose(f);
15891590
}
1591+
free(filename);
15901592

15911593
if (ret == UPAP_AUTHNAK) {
15921594
if (**msg == 0)
@@ -1646,17 +1648,21 @@ null_login(int unit)
16461648
* Open the file of pap secrets and scan for a suitable secret.
16471649
*/
16481650
if (ret <= 0) {
1649-
filename = path_upapfile;
1651+
if (!ppp_check_access(path_upapfile, &filename, 0, 0))
1652+
return 0;
16501653
addrs = NULL;
16511654
f = fopen(filename, "r");
1652-
if (f == NULL)
1655+
if (f == NULL) {
1656+
free(filename);
16531657
return 0;
1658+
}
16541659
check_access(f, filename);
16551660

16561661
i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0);
16571662
ret = i >= 0 && secret[0] == 0;
16581663
BZERO(secret, sizeof(secret));
16591664
fclose(f);
1665+
free(filename);
16601666
}
16611667

16621668
if (ret)
@@ -1730,14 +1736,18 @@ have_pap_secret(int *lacks_ipp)
17301736
return ret;
17311737
}
17321738

1733-
filename = path_upapfile;
1739+
if (!ppp_check_access(path_upapfile, &filename, 0, 0))
1740+
return 0;
17341741
f = fopen(filename, "r");
1735-
if (f == NULL)
1742+
if (f == NULL) {
1743+
free(filename);
17361744
return 0;
1745+
}
17371746

17381747
ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name,
17391748
NULL, &addrs, NULL, filename, 0);
17401749
fclose(f);
1750+
free(filename);
17411751
if (ret >= 0 && !some_ip_ok(addrs)) {
17421752
if (lacks_ipp != 0)
17431753
*lacks_ipp = 1;
@@ -1772,10 +1782,13 @@ have_chap_secret(char *client, char *server,
17721782
}
17731783
}
17741784

1775-
filename = path_chapfile;
1785+
if (!ppp_check_access(path_chapfile, &filename, 0, 0))
1786+
return 0;
17761787
f = fopen(filename, "r");
1777-
if (f == NULL)
1788+
if (f == NULL) {
1789+
free(filename);
17781790
return 0;
1791+
}
17791792

17801793
if (client != NULL && client[0] == 0)
17811794
client = NULL;
@@ -1784,6 +1797,7 @@ have_chap_secret(char *client, char *server,
17841797

17851798
ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
17861799
fclose(f);
1800+
free(filename);
17871801
if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
17881802
if (lacks_ipp != 0)
17891803
*lacks_ipp = 1;
@@ -1810,10 +1824,13 @@ have_srp_secret(char *client, char *server, int need_ip, int *lacks_ipp)
18101824
char *filename;
18111825
struct wordlist *addrs;
18121826

1813-
filename = PPP_PATH_SRPFILE;
1827+
if (!ppp_check_access(PPP_PATH_SRPFILE, &filename, 0, 0))
1828+
return 0;
18141829
f = fopen(filename, "r");
1815-
if (f == NULL)
1830+
if (f == NULL) {
1831+
free(filename);
18161832
return 0;
1833+
}
18171834

18181835
if (client != NULL && client[0] == 0)
18191836
client = NULL;
@@ -1822,6 +1839,7 @@ have_srp_secret(char *client, char *server, int need_ip, int *lacks_ipp)
18221839

18231840
ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
18241841
fclose(f);
1842+
free(filename);
18251843
if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
18261844
if (lacks_ipp != 0)
18271845
*lacks_ipp = 1;
@@ -1858,19 +1876,22 @@ get_secret(int unit, char *client, char *server,
18581876
return 0;
18591877
}
18601878
} else {
1861-
filename = path_chapfile;
1879+
if (!ppp_check_access(path_chapfile, &filename, 0, 0))
1880+
return 0;
18621881
addrs = NULL;
18631882
secbuf[0] = 0;
18641883

18651884
f = fopen(filename, "r");
18661885
if (f == NULL) {
18671886
error("Can't open chap secret file %s: %m", filename);
1887+
free(filename);
18681888
return 0;
18691889
}
18701890
check_access(f, filename);
18711891

18721892
ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0);
18731893
fclose(f);
1894+
free(filename);
18741895
if (ret < 0)
18751896
return 0;
18761897

@@ -1912,12 +1933,14 @@ get_srp_secret(int unit, char *client, char *server,
19121933
if (!am_server && passwd[0] != '\0') {
19131934
strlcpy(secret, passwd, MAXWORDLEN);
19141935
} else {
1915-
filename = PPP_PATH_SRPFILE;
1936+
if (!ppp_check_access(PPP_PATH_SRPFILE, &filename, 0, 0))
1937+
return 0;
19161938
addrs = NULL;
19171939

19181940
fp = fopen(filename, "r");
19191941
if (fp == NULL) {
19201942
error("Can't open srp secret file %s: %m", filename);
1943+
free(filename);
19211944
return 0;
19221945
}
19231946
check_access(fp, filename);
@@ -1926,6 +1949,7 @@ get_srp_secret(int unit, char *client, char *server,
19261949
ret = scan_authfile(fp, client, server, secret, &addrs, &opts,
19271950
filename, am_server);
19281951
fclose(fp);
1952+
free(filename);
19291953
if (ret < 0)
19301954
return 0;
19311955

@@ -2304,18 +2328,25 @@ scan_authfile(FILE *f, char *client, char *server,
23042328
* Special syntax: @/pathname means read secret from file.
23052329
*/
23062330
if (word[0] == '@' && word[1] == '/') {
2331+
char *realname;
2332+
23072333
strlcpy(atfile, word+1, sizeof(atfile));
2308-
if ((sf = fopen(atfile, "r")) == NULL) {
2334+
if (!ppp_check_access(atfile, &realname, 0, 0))
2335+
continue;
2336+
if ((sf = fopen(realname, "r")) == NULL) {
23092337
warn("can't open indirect secret file %s", atfile);
2338+
free(realname);
23102339
continue;
23112340
}
23122341
check_access(sf, atfile);
23132342
if (!getword(sf, word, &xxx, atfile)) {
23142343
warn("no secret in indirect secret file %s", atfile);
23152344
fclose(sf);
2345+
free(realname);
23162346
continue;
23172347
}
23182348
fclose(sf);
2349+
free(realname);
23192350
}
23202351
strlcpy(lsecret, word, sizeof(lsecret));
23212352
}
@@ -2474,10 +2505,13 @@ have_eaptls_secret_server(char *client, char *server,
24742505
char cacertfile[MAXWORDLEN];
24752506
char pkfile[MAXWORDLEN];
24762507

2477-
filename = PPP_PATH_EAPTLSSERVFILE;
2508+
if (!ppp_check_access(PPP_PATH_EAPTLSSERVFILE, &filename, 0, 0))
2509+
return 0;
24782510
f = fopen(filename, "r");
2479-
if (f == NULL)
2480-
return 0;
2511+
if (f == NULL) {
2512+
free(filename);
2513+
return 0;
2514+
}
24812515

24822516
if (client != NULL && client[0] == 0)
24832517
client = NULL;
@@ -2490,6 +2524,7 @@ have_eaptls_secret_server(char *client, char *server,
24902524
0);
24912525

24922526
fclose(f);
2527+
free(filename);
24932528

24942529
/*
24952530
if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile,
@@ -2752,10 +2787,13 @@ get_eaptls_secret(int unit, char *client, char *server,
27522787
filename = (am_server ? PPP_PATH_EAPTLSSERVFILE : PPP_PATH_EAPTLSCLIFILE);
27532788
addrs = NULL;
27542789

2790+
if (!ppp_check_access(filename, &filename, 0, 0))
2791+
return 0;
27552792
fp = fopen(filename, "r");
27562793
if (fp == NULL)
27572794
{
27582795
error("Can't open eap-tls secret file %s: %m", filename);
2796+
free(filename);
27592797
return 0;
27602798
}
27612799

@@ -2765,6 +2803,7 @@ get_eaptls_secret(int unit, char *client, char *server,
27652803
cacertfile, pkfile, &addrs, &opts, filename, 0);
27662804

27672805
fclose(fp);
2806+
free(filename);
27682807

27692808
if (ret < 0) return 0;
27702809
}

0 commit comments

Comments
 (0)