Skip to content

Commit e2a50ad

Browse files
committed
Add option to store the session encryption key.
With the new 'file:' sytnax a session key can be automatically generated the first time mod_auth_gssapi runs and stored on the filesystem. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Robbie Harwood <rharwood@redhat.com> Closes #117
1 parent 0d6a1a3 commit e2a50ad

File tree

3 files changed

+99
-16
lines changed

3 files changed

+99
-16
lines changed

README

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,21 @@ admin can choose to install a permanent key in the configuration so that
144144
session data remain accessible after a restart or by multiple servers
145145
sharing the same key.
146146

147-
The key must be a base64 encoded raw key of 32 bytes of length.
147+
Two schemes to read persistent keys are provided, 'key' and 'file'.
148148

149-
#### Example
149+
- 'key'
150+
A key is read from the configuration directive.
151+
The key must be a base64 encoded raw key of 32 bytes of length.
152+
153+
- 'file'
154+
A file on the file system is used to store the key. If the file does not
155+
exists one is created with a randomly generated key during the first
156+
execution.
157+
158+
159+
#### Examples
150160
GssapiSessionKey key:VGhpcyBpcyBhIDMyIGJ5dGUgbG9uZyBzZWNyZXQhISE=
161+
GssapiSessionKey file:/var/lib/httpd/secrets/session.key
151162

152163

153164
### GssapiCredStore

src/mod_auth_gssapi.c

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,34 +1238,105 @@ static const char *mag_deleg_ccache_unique(cmd_parms *parms, void *mconfig,
12381238

12391239
#endif
12401240

1241+
#define SESS_KEYS_TOT_LEN 32
1242+
1243+
static void create_sess_key_file(cmd_parms *parms, const char *name)
1244+
{
1245+
apr_status_t ret;
1246+
apr_file_t *fd = NULL;
1247+
unsigned char keys[SESS_KEYS_TOT_LEN];
1248+
apr_size_t bw;
1249+
1250+
ret = apr_file_open(&fd, name,
1251+
APR_FOPEN_CREATE | APR_FOPEN_WRITE | APR_FOPEN_EXCL,
1252+
APR_FPROT_UREAD | APR_FPROT_UWRITE, parms->temp_pool);
1253+
if (ret != APR_SUCCESS) {
1254+
char err[256];
1255+
apr_strerror(ret, err, sizeof(err));
1256+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1257+
"Failed to create key file %s: %s", name, err);
1258+
return;
1259+
}
1260+
ret = apr_generate_random_bytes(keys, SESS_KEYS_TOT_LEN);
1261+
if (ret != OK) {
1262+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1263+
"Failed to generate random sealing key!");
1264+
ret = APR_INCOMPLETE;
1265+
goto done;
1266+
}
1267+
ret = apr_file_write_full(fd, keys, SESS_KEYS_TOT_LEN, &bw);
1268+
if ((ret != APR_SUCCESS) || (bw != SESS_KEYS_TOT_LEN)) {
1269+
char err[256];
1270+
apr_strerror(ret, err, sizeof(err));
1271+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1272+
"Failed to store key in %s: %s", name, err);
1273+
ret = APR_INCOMPLETE;
1274+
goto done;
1275+
}
1276+
done:
1277+
apr_file_close(fd);
1278+
if (ret != APR_SUCCESS) apr_file_remove(name, parms->temp_pool);
1279+
}
1280+
12411281
static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w)
12421282
{
12431283
struct mag_config *cfg = (struct mag_config *)mconfig;
12441284
struct databuf keys;
12451285
unsigned char *val;
12461286
apr_status_t rc;
1247-
const char *k;
12481287
int l;
12491288

1250-
if (strncmp(w, "key:", 4) != 0) {
1251-
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1252-
"Invalid key format, expected prefix 'key:'");
1253-
return NULL;
1254-
}
1255-
k = w + 4;
1289+
if (strncmp(w, "key:", 4) == 0) {
1290+
const char *k = w + 4;
1291+
1292+
l = apr_base64_decode_len(k);
1293+
val = apr_palloc(parms->temp_pool, l);
1294+
1295+
keys.length = (int)apr_base64_decode_binary(val, k);
1296+
keys.value = (unsigned char *)val;
1297+
1298+
if (keys.length != SESS_KEYS_TOT_LEN) {
1299+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1300+
"Invalid key length, expected 32 got %d",
1301+
keys.length);
1302+
return NULL;
1303+
}
1304+
} else if (strncmp(w, "file:", 5) == 0) {
1305+
apr_status_t ret;
1306+
apr_file_t *fd = NULL;
1307+
apr_int32_t ronly = APR_FOPEN_READ;
1308+
const char *fname;
12561309

1257-
l = apr_base64_decode_len(k);
1258-
val = apr_palloc(parms->temp_pool, l);
1310+
keys.length = SESS_KEYS_TOT_LEN;
1311+
keys.value = apr_palloc(parms->temp_pool, keys.length);
12591312

1260-
keys.length = (int)apr_base64_decode_binary(val, k);
1261-
keys.value = (unsigned char *)val;
1313+
fname = w + 5;
12621314

1263-
if (keys.length != 32) {
1315+
ret = apr_file_open(&fd, fname, ronly, 0, parms->temp_pool);
1316+
if (APR_STATUS_IS_ENOENT(ret)) {
1317+
create_sess_key_file(parms, fname);
1318+
1319+
ret = apr_file_open(&fd, fname, ronly, 0, parms->temp_pool);
1320+
}
1321+
if (ret == APR_SUCCESS) {
1322+
apr_size_t br;
1323+
ret = apr_file_read_full(fd, keys.value, keys.length, &br);
1324+
apr_file_close(fd);
1325+
if ((ret != APR_SUCCESS) || (br != keys.length)) {
1326+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1327+
"Failed to read sealing key from %s!", fname);
1328+
return NULL;
1329+
}
1330+
} else {
1331+
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1332+
"Failed to open key file %s", fname);
1333+
return NULL;
1334+
}
1335+
} else {
12641336
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
1265-
"Invalid key length, expected 32 got %d", keys.length);
1337+
"Invalid key format, unexpected prefix in %s'", w);
12661338
return NULL;
12671339
}
1268-
12691340
rc = SEAL_KEY_CREATE(cfg->pool, &cfg->mag_skey, &keys);
12701341
if (rc != OK) {
12711342
ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,

tests/httpd.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ CoreDumpDirectory /tmp
137137
GssapiUseSessions On
138138
Session On
139139
SessionCookieName gssapi_session path=/spnego;httponly
140+
GssapiSessionKey file:${HTTPROOT}/session.key
140141
GssapiCredStore ccache:${HTTPROOT}/tmp/httpd_krb5_ccache
141142
GssapiCredStore client_keytab:${HTTPROOT}/http.keytab
142143
GssapiCredStore keytab:${HTTPROOT}/http.keytab

0 commit comments

Comments
 (0)