Skip to content
This repository was archived by the owner on May 30, 2025. It is now read-only.

Commit 0a425bd

Browse files
authored
Merge pull request #111 from blizzz/fix/noid/constrained-delegation
fix check with krb constrained delegation
2 parents c1ce4fb + baaded2 commit 0a425bd

File tree

2 files changed

+51
-31
lines changed

2 files changed

+51
-31
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ jobs:
208208
name: Psalm static analysis
209209

210210
strategy:
211+
fail-fast: false
211212
matrix:
212213
php-version:
213214
- "7.2"

src/KerberosApacheAuth.php

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,65 @@ class KerberosApacheAuth extends KerberosAuth implements IAuth {
3131
/** @var string */
3232
private $ticketPath = "";
3333

34-
// only working with specific library (mod_auth_kerb, krb5, smbclient) versions
35-
/** @var bool */
36-
private $saveTicketInMemory = false;
37-
3834
/** @var bool */
3935
private $init = false;
4036

37+
/** @var string|false */
38+
private $ticketName;
39+
40+
public function __construct() {
41+
$this->ticketName = getenv("KRB5CCNAME");
42+
}
43+
44+
45+
/**
46+
* Copy the ticket to a temporary location and use that ticket for authentication
47+
*
48+
* @return void
49+
*/
50+
public function copyTicket(): void {
51+
if (!$this->checkTicket()) {
52+
return;
53+
}
54+
$krb5 = new \KRB5CCache();
55+
$krb5->open($this->ticketName);
56+
$tmpFilename = tempnam("/tmp", "krb5cc_php_");
57+
$tmpCacheFile = "FILE:" . $tmpFilename;
58+
$krb5->save($tmpCacheFile);
59+
$this->ticketPath = $tmpFilename;
60+
$this->ticketName = $tmpCacheFile;
61+
}
62+
4163
/**
42-
* @param bool $saveTicketInMemory
64+
* Pass the ticket to smbclient by memory instead of path
65+
*
66+
* @return void
4367
*/
44-
public function __construct(bool $saveTicketInMemory = false) {
45-
$this->saveTicketInMemory = $saveTicketInMemory;
68+
public function passTicketFromMemory(): void {
69+
if (!$this->checkTicket()) {
70+
return;
71+
}
72+
$krb5 = new \KRB5CCache();
73+
$krb5->open($this->ticketName);
74+
$this->ticketName = (string)$krb5->getName();
4675
}
4776

4877
/**
4978
* Check if a valid kerberos ticket is present
5079
*
5180
* @return bool
81+
* @psalm-assert-if-true string $this->ticketName
5282
*/
5383
public function checkTicket(): bool {
5484
//read apache kerberos ticket cache
55-
$cacheFile = getenv("KRB5CCNAME");
56-
if (!$cacheFile) {
85+
if (!$this->ticketName) {
5786
return false;
5887
}
5988

6089
$krb5 = new \KRB5CCache();
61-
$krb5->open($cacheFile);
62-
return (bool)$krb5->isValid();
90+
$krb5->open($this->ticketName);
91+
/** @psalm-suppress MixedArgument */
92+
return count($krb5->getEntries()) > 0;
6393
}
6494

6595
private function init(): void {
@@ -75,28 +105,13 @@ private function init(): void {
75105
}
76106

77107
//read apache kerberos ticket cache
78-
$cacheFile = getenv("KRB5CCNAME");
79-
if (!$cacheFile) {
108+
if (!$this->checkTicket()) {
80109
throw new Exception('No kerberos ticket cache environment variable (KRB5CCNAME) found.');
81110
}
82111

83-
$krb5 = new \KRB5CCache();
84-
$krb5->open($cacheFile);
85-
if (!$krb5->isValid()) {
86-
throw new Exception('Kerberos ticket cache is not valid.');
87-
}
88-
89-
90-
if ($this->saveTicketInMemory) {
91-
putenv("KRB5CCNAME=" . (string)$krb5->getName());
92-
} else {
93-
//workaround: smbclient is not working with the original apache ticket cache.
94-
$tmpFilename = tempnam("/tmp", "krb5cc_php_");
95-
$tmpCacheFile = "FILE:" . $tmpFilename;
96-
$krb5->save($tmpCacheFile);
97-
$this->ticketPath = $tmpFilename;
98-
putenv("KRB5CCNAME=" . $tmpCacheFile);
99-
}
112+
// note that even if the ticketname is the value we got from `getenv("KRB5CCNAME")` we still need to set the env variable ourselves
113+
// this is because `getenv` also reads the variables passed from the SAPI (apache-php) and we need to set the variable in the OS's env
114+
putenv("KRB5CCNAME=" . $this->ticketName);
100115
}
101116

102117
public function getExtraCommandLineArguments(): string {
@@ -106,7 +121,11 @@ public function getExtraCommandLineArguments(): string {
106121

107122
public function setExtraSmbClientOptions($smbClientState): void {
108123
$this->init();
109-
parent::setExtraSmbClientOptions($smbClientState);
124+
try {
125+
parent::setExtraSmbClientOptions($smbClientState);
126+
} catch (Exception $e) {
127+
// suppress
128+
}
110129
}
111130

112131
public function __destruct() {

0 commit comments

Comments
 (0)