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

Reply via email to