More big-endian patches for the PS and also fixes for file
locking the PS using fcntl instead of flock (threading concerns).
-Wyllys Ingersoll
--- src/tspi/ps/tspps.c.old Mon Jul 20 11:44:30 2009
+++ src/tspi/ps/tspps.c Wed Aug 5 13:18:26 2009
@@ -19,6 +19,11 @@
#include <sys/file.h>
#include <sys/stat.h>
#include <assert.h>
+#if defined (SOLARIS)
+#include <fcntl.h>
+#include <limits.h>
+#include <netdb.h>
+#endif
#include "trousers/tss.h"
#include "trousers/trousers.h"
@@ -33,6 +38,17 @@
#if (defined (__FreeBSD__) || defined (__OpenBSD__))
static MUTEX_DECLARE_INIT(user_ps_path);
#endif
+#if defined (SOLARIS)
+static struct flock fl = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ {0, 0, 0, 0}
+};
+#endif
/*
@@ -62,6 +78,16 @@
euid = geteuid();
+#if defined (SOLARIS)
+ /*
+ * Solaris keeps user PS in a local directory to avoid NFS problems
+ * and potential conflicts when sharing the same PS file among
+ * multiple machines with different TPMs.
+ *
+ * The directory path is /var/tpm/userps/[EUID]/
+ */
+ rc = snprintf(buf, sizeof (buf), "%s/%d", TSS_USER_PS_DIR, euid);
+#else
setpwent();
while (1) {
#if (defined (__linux) || defined (linux))
@@ -93,8 +119,9 @@
return TSPERR(TSS_E_OUTOFMEMORY);
/* Tack on TSS_USER_PS_DIR and see if it exists */
- rc = snprintf(buf, PASSWD_BUFSIZE, "%s/%s", home_dir, TSS_USER_PS_DIR);
- if (rc == PASSWD_BUFSIZE) {
+ rc = snprintf(buf, sizeof (buf), "%s/%s", home_dir, TSS_USER_PS_DIR);
+#endif /* SOLARIS */
+ if (rc == sizeof (buf)) {
LogDebugFn("USER PS: Path to file too long! (> %d bytes)",
PASSWD_BUFSIZE);
result = TSPERR(TSS_E_INTERNAL_ERROR);
goto done;
@@ -104,7 +131,7 @@
if ((rc = stat(buf, &stat_buf)) == -1) {
if (errno == ENOENT) {
errno = 0;
- /* Create the base directory, $HOME/.trousers */
+ /* Create the user's ps directory if it is not there. */
if ((rc = mkdir(buf, 0700)) == -1) {
LogDebugFn("USER PS: Error creating dir: %s:
%s", buf,
strerror(errno));
@@ -119,10 +146,15 @@
}
/* Directory exists or has been created, return the path to the file */
- rc = snprintf(buf, PASSWD_BUFSIZE, "%s/%s/%s", home_dir,
TSS_USER_PS_DIR,
+#if defined (SOLARIS)
+ rc = snprintf(buf, sizeof (buf), "%s/%d/%s", TSS_USER_PS_DIR, euid,
TSS_USER_PS_FILE);
- if (rc == PASSWD_BUFSIZE) {
- LogDebugFn("USER PS: Path to file too long! (> %d bytes)",
PASSWD_BUFSIZE);
+#else
+ rc = snprintf(buf, sizeof (buf), "%s/%s/%s", home_dir, TSS_USER_PS_DIR,
+ TSS_USER_PS_FILE);
+#endif
+ if (rc == sizeof (buf)) {
+ LogDebugFn("USER PS: Path to file too long! (> %d bytes)",
sizeof (buf));
} else
*file = strdup(buf);
@@ -143,12 +175,16 @@
/* check the global file handle first. If it exists, lock it and
return */
if (user_ps_fd != -1) {
+#if defined (SOLARIS)
+ fl.l_type = F_WRLCK;
+ if ((rc = fcntl(user_ps_fd, F_SETLKW, &fl))) {
+#else
if ((rc = flock(user_ps_fd, LOCK_EX))) {
+#endif /* SOLARIS */
LogDebug("USER PS: failed to lock file: %s",
strerror(errno));
MUTEX_UNLOCK(user_ps_lock);
return TSPERR(TSS_E_INTERNAL_ERROR);
}
-
*fd = user_ps_fd;
return TSS_SUCCESS;
}
@@ -167,8 +203,12 @@
MUTEX_UNLOCK(user_ps_lock);
return TSPERR(TSS_E_INTERNAL_ERROR);
}
-
+#if defined (SOLARIS)
+ fl.l_type = F_WRLCK;
+ if ((rc = fcntl(user_ps_fd, F_SETLKW, &fl))) {
+#else
if ((rc = flock(user_ps_fd, LOCK_EX))) {
+#endif /* SOLARIS */
LogDebug("USER PS: failed to get lock of %s: %s", file_name,
strerror(errno));
free(file_name);
close(user_ps_fd);
@@ -190,7 +230,12 @@
fsync(fd);
/* release the file lock */
+#if defined (SOLARIS)
+ fl.l_type = F_UNLCK;
+ if ((rc = fcntl(fd, F_SETLKW, &fl))) {
+#else
if ((rc = flock(fd, LOCK_UN))) {
+#endif /* SOLARIS */
LogDebug("USER PS: failed to unlock file: %s",
strerror(errno));
rc = -1;
}
@@ -365,6 +410,9 @@
LogDebug("read of %zd bytes: %s", sizeof(UINT32),
strerror(errno));
return TSPERR(TSS_E_INTERNAL_ERROR);
}
+#if defined(_BIG_ENDIAN)
+ num_keys = BSWAP_32(num_keys);
+#endif
if (increment)
num_keys++;
@@ -377,6 +425,9 @@
return TSPERR(TSS_E_INTERNAL_ERROR);
}
+#if defined(_BIG_ENDIAN)
+ num_keys = BSWAP_32(num_keys);
+#endif
if ((result = write_data(fd, (void *)&num_keys, sizeof(UINT32)))) {
LogDebug("%s", __FUNCTION__);
return result;
@@ -498,16 +549,28 @@
}
/* [UINT16 pub_data_size0 ] yes */
+#if defined(_BIG_ENDIAN)
+ pub_key_size = BSWAP_16(pub_key_size);
+#endif
if ((result = write_data(fd, &pub_key_size, sizeof(UINT16)))) {
LogDebug("%s", __FUNCTION__);
goto done;
}
+#if defined(_BIG_ENDIAN)
+ pub_key_size = BSWAP_16(pub_key_size);
+#endif
/* [UINT16 blob_size0 ] yes */
+#if defined(_BIG_ENDIAN)
+ key_blob_size = BSWAP_16(key_blob_size);
+#endif
if ((result = write_data(fd, &key_blob_size, sizeof(UINT16)))) {
LogDebug("%s", __FUNCTION__);
goto done;
}
+#if defined(_BIG_ENDIAN)
+ key_blob_size = BSWAP_16(key_blob_size);
+#endif
/* [UINT32 vendor_data_size0 ] yes */
if ((result = write_data(fd, &zero, sizeof(UINT32)))) {
@@ -516,10 +579,16 @@
}
/* [UINT16 cache_flags0 ] yes */
+#if defined(_BIG_ENDIAN)
+ cache_flags = BSWAP_16(cache_flags);
+#endif
if ((result = write_data(fd, &cache_flags, sizeof(UINT16)))) {
LogDebug("%s", __FUNCTION__);
goto done;
}
+#if defined(_BIG_ENDIAN)
+ cache_flags = BSWAP_16(cache_flags);
+#endif
/* [BYTE[] pub_data0 ] no */
if ((result = write_data(fd, (void *)key.pubKey.key, pub_key_size))) {
@@ -685,6 +754,9 @@
LogDebug("%s", __FUNCTION__);
goto err_exit;
}
+#if defined(_BIG_ENDIAN)
+ tmp[i].pub_data_size = BSWAP_16(tmp[i].pub_data_size);
+#endif
DBG_ASSERT(tmp[i].pub_data_size <= 2048);
@@ -693,6 +765,9 @@
LogDebug("%s", __FUNCTION__);
goto err_exit;
}
+#if defined(_BIG_ENDIAN)
+ tmp[i].blob_size = BSWAP_16(tmp[i].blob_size);
+#endif
DBG_ASSERT(tmp[i].blob_size <= 4096);
@@ -701,6 +776,9 @@
LogDebug("%s", __FUNCTION__);
goto err_exit;
}
+#if defined(_BIG_ENDIAN)
+ tmp[i].vendor_data_size = BSWAP_32(tmp[i].vendor_data_size);
+#endif
/* cache flags */
if ((result = read_data(fd, &tmp[i].flags, sizeof(UINT16)))) {
@@ -707,6 +785,9 @@
LogDebug("%s", __FUNCTION__);
goto err_exit;
}
+#if defined(_BIG_ENDIAN)
+ tmp[i].flags = BSWAP_16(tmp[i].flags);
+#endif
/* fast forward over the pub key */
offset = lseek(fd, tmp[i].pub_data_size, SEEK_CUR);
@@ -1031,6 +1112,10 @@
num_keys = 0;
}
+#if defined(_BIG_ENDIAN)
+ /* The system PS file is written in little-endian */
+ num_keys = BSWAP_32(num_keys);
+#endif
return num_keys;
}
@@ -1109,7 +1194,9 @@
LogDebug("%s", __FUNCTION__);
return result;
}
-
+#if defined(_BIG_ENDIAN)
+ c->pub_data_size = BSWAP_16(c->pub_data_size);
+#endif
DBG_ASSERT(c->pub_data_size <= 2048 && c->pub_data_size > 0);
/* blob size */
@@ -1117,7 +1204,9 @@
LogDebug("%s", __FUNCTION__);
return result;
}
-
+#if defined(_BIG_ENDIAN)
+ c->blob_size = BSWAP_16(c->blob_size);
+#endif
DBG_ASSERT(c->blob_size <= 4096 && c->blob_size > 0);
/* vendor data size */
@@ -1125,6 +1214,9 @@
LogDebug("%s", __FUNCTION__);
return result;
}
+#if defined(_BIG_ENDIAN)
+ c->vendor_data_size = BSWAP_32(c->vendor_data_size);
+#endif
/* cache flags */
if ((result = read_data(fd, &c->flags, sizeof(UINT16)))) {
@@ -1131,6 +1223,9 @@
LogDebug("%s", __FUNCTION__);
return result;
}
+#if defined(_BIG_ENDIAN)
+ c->flags = BSWAP_16(c->flags);
+#endif
/* fast forward over the pub key */
offset = lseek(fd, c->pub_data_size, SEEK_CUR);
@@ -1198,6 +1293,9 @@
return result;
}
+#if defined(_BIG_ENDIAN)
+ c->pub_data_size = BSWAP_16(c->pub_data_size);
+#endif
DBG_ASSERT(c->pub_data_size <= 2048 && c->pub_data_size > 0);
/* blob size */
@@ -1206,6 +1304,9 @@
return result;
}
+#if defined(_BIG_ENDIAN)
+ c->blob_size = BSWAP_16(c->blob_size);
+#endif
DBG_ASSERT(c->blob_size <= 4096 && c->blob_size > 0);
/* vendor data size */
@@ -1213,6 +1314,9 @@
LogDebug("%s", __FUNCTION__);
return result;
}
+#if defined(_BIG_ENDIAN)
+ c->vendor_data_size = BSWAP_32(c->vendor_data_size);
+#endif
/* cache flags */
if ((result = read_data(fd, &c->flags, sizeof(UINT16)))) {
@@ -1219,6 +1323,9 @@
LogDebug("%s", __FUNCTION__);
return result;
}
+#if defined(_BIG_ENDIAN)
+ c->flags = BSWAP_16(c->flags);
+#endif
if (c->pub_data_size == pub_size) {
/* read in the pub key */
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
TrouSerS-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/trousers-tech