* Use counter to track number of read-only sessions:
   Use global "ro_session_count" counter to track the number
   of existing read-only sessions, since this information
   is necessary to check if the SO can perform log-in

 * Adjust session_mgr_so_session_exists() and
   session_mgr_user_session_exists() to take advantage of
   the global login state: All sessions must be either logged
   in as user, as SO or are public sessions. This patch
   makes use of global login state infrastructure that was
   already there.

 * Rename session_mgr_readonly_exists() to
   session_mgr_readonly_session_exists() for consistency.

Signed-off-by: Klaus Heinrich Kiwi <[email protected]>
---
 usr/lib/pkcs11/common/globals.c  |    4 +-
 usr/lib/pkcs11/common/h_extern.h |    4 +-
 usr/lib/pkcs11/common/new_host.c |    2 +-
 usr/lib/pkcs11/common/sess_mgr.c |  148 ++++++++++++--------------------------
 4 files changed, 50 insertions(+), 108 deletions(-)

diff --git a/usr/lib/pkcs11/common/globals.c b/usr/lib/pkcs11/common/globals.c
index e9116f7..7b1432f 100755
--- a/usr/lib/pkcs11/common/globals.c
+++ b/usr/lib/pkcs11/common/globals.c
@@ -329,9 +329,9 @@ DL_NODE  *publ_token_obj_list = NULL;
 DL_NODE  *priv_token_obj_list = NULL;
 DL_NODE  *object_map     = NULL;
 
+CK_ULONG  ro_session_count = 0;
 
-CK_STATE  global_login_state = 0;
-
+CK_STATE  global_login_state = CKS_RO_PUBLIC_SESSION;
 
 LW_SHM_TYPE *global_shm;
 
diff --git a/usr/lib/pkcs11/common/h_extern.h b/usr/lib/pkcs11/common/h_extern.h
index 9cf34c1..4368902 100755
--- a/usr/lib/pkcs11/common/h_extern.h
+++ b/usr/lib/pkcs11/common/h_extern.h
@@ -357,10 +357,10 @@ extern LW_SHM_TYPE *global_shm;
 extern TOKEN_DATA        *nv_token_data;
 extern CK_SLOT_INFO       slot_info;
 
+extern CK_ULONG  ro_session_count;
 extern CK_ULONG next_object_handle;
 extern CK_ULONG next_session_handle;
 
-// SAB FIXME FIXME
 extern CK_STATE  global_login_state;
 
 
@@ -1834,7 +1834,7 @@ CK_RV  session_mgr_login_all ( CK_USER_TYPE user_type );
 CK_RV  session_mgr_logout_all( void );
 CK_RV  session_mgr_new( CK_ULONG flags, SESSION **sess );
 
-CK_BBOOL  session_mgr_readonly_exists( void );
+CK_BBOOL  session_mgr_readonly_session_exists( void );
 CK_BBOOL  session_mgr_so_session_exists    ( void );
 CK_BBOOL  session_mgr_user_session_exists  ( void );
 CK_BBOOL  session_mgr_public_session_exists( void );
diff --git a/usr/lib/pkcs11/common/new_host.c b/usr/lib/pkcs11/common/new_host.c
index a346412..394203f 100755
--- a/usr/lib/pkcs11/common/new_host.c
+++ b/usr/lib/pkcs11/common/new_host.c
@@ -1656,7 +1656,7 @@ CK_RV SC_Login( ST_SESSION_HANDLE   sSession,
                        st_err_log(56, __FILE__, __LINE__);
                        rc = CKR_USER_ALREADY_LOGGED_IN;
                }
-               if (session_mgr_readonly_exists()){
+               if (session_mgr_readonly_session_exists()){
                        st_err_log(142, __FILE__, __LINE__);
                        rc = CKR_SESSION_READ_ONLY_EXISTS;
                }
diff --git a/usr/lib/pkcs11/common/sess_mgr.c b/usr/lib/pkcs11/common/sess_mgr.c
index d6d9513..d6d5aa8 100755
--- a/usr/lib/pkcs11/common/sess_mgr.c
+++ b/usr/lib/pkcs11/common/sess_mgr.c
@@ -401,44 +401,19 @@ session_mgr_new( CK_ULONG flags, SESSION **sess )
    new_session->session_info.flags         = flags;
    new_session->session_info.ulDeviceError = 0;
 
-   rc = MY_LockMutex( &sess_list_mutex );
-   if (rc != CKR_OK){
-      st_err_log(146, __FILE__, __LINE__); 
-      return rc;
-   }
-   sess_locked = TRUE;
 
    // determine the login/logout status of the new session.  PKCS 11 requires
    // that all sessions belonging to a process have the same login/logout 
status
    //
-   node = sess_list;
-   while (node) {
-      SESSION *s = (SESSION *)node->data;
-      if (s->session_info.state == CKS_RW_SO_FUNCTIONS) {
-         so_session = TRUE;
-         break;
-      }
+   so_session = session_mgr_so_session_exists();
+   user_session = session_mgr_user_session_exists();
 
-      if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) ||
-          (s->session_info.state == CKS_RW_USER_FUNCTIONS))
-      {
-         user_session = TRUE;
-         break;
-      }
-
-      node = node->next;
-   }
-
-// SAB XXX login does not drop after all sessions are closed XXX
-   if ( global_login_state == CKS_RW_SO_FUNCTIONS) {
-       so_session = TRUE;
-   }
-   if ((global_login_state == CKS_RO_USER_FUNCTIONS) ||
-       (global_login_state == CKS_RW_USER_FUNCTIONS)) {
-       user_session = TRUE;
+   rc = MY_LockMutex( &sess_list_mutex );
+   if (rc != CKR_OK){
+      st_err_log(146, __FILE__, __LINE__); 
+      return rc;
    }
-
-// END SAB login state carry
+   sess_locked = TRUE;
 
    // we don't have to worry about having a user and SO session at the same 
time.
    // that is prevented in the login routine
@@ -446,8 +421,10 @@ session_mgr_new( CK_ULONG flags, SESSION **sess )
    if (user_session) {
       if (new_session->session_info.flags & CKF_RW_SESSION)
          new_session->session_info.state = CKS_RW_USER_FUNCTIONS;
-      else
+      else {
          new_session->session_info.state = CKS_RO_USER_FUNCTIONS;
+         ro_session_count++;
+      }
    }
    else if (so_session) {
       new_session->session_info.state = CKS_RW_SO_FUNCTIONS;
@@ -455,8 +432,10 @@ session_mgr_new( CK_ULONG flags, SESSION **sess )
    else {
       if (new_session->session_info.flags & CKF_RW_SESSION)
          new_session->session_info.state = CKS_RW_PUBLIC_SESSION;
-      else
+      else {
          new_session->session_info.state = CKS_RO_PUBLIC_SESSION;
+         ro_session_count++;
+      }
    }
 
    sess_list = dlist_add_as_first( sess_list, new_session );
@@ -486,30 +465,20 @@ done:
 CK_BBOOL
 session_mgr_so_session_exists( void )
 {
-   DL_NODE *node = NULL;
-   CK_RV    rc;
+   CK_BBOOL result;
+   CK_RV rc;
 
+   /* we must acquire sess_list_mutex in order to inspect glogal_login_state */
    rc = MY_LockMutex( &sess_list_mutex );
    if (rc != CKR_OK){
       st_err_log(146, __FILE__, __LINE__); 
-      return rc;
-   }
-   node = sess_list;
-   while (node) {
-      SESSION *s = (SESSION *)node->data;
-      if (s->session_info.state == CKS_RW_SO_FUNCTIONS) {
-         rc = TRUE;
-         goto done;
-      }
-
-      node = node->next;
+      return FALSE;      // FIXME: make this function return proper errors
    }
 
-   rc = FALSE;
+   result = (global_login_state == CKS_RW_SO_FUNCTIONS);
 
-done:
    MY_UnlockMutex( &sess_list_mutex );
-   return rc;
+   return result;
 }
 
 
@@ -522,32 +491,20 @@ done:
 CK_BBOOL
 session_mgr_user_session_exists( void )
 {
-   DL_NODE *node = NULL;
-   CK_RV    rc;
+   CK_BBOOL result;
+   CK_RV rc;
 
+   /* we must acquire sess_list_mutex in order to inspect glogal_login_state */
    rc = MY_LockMutex( &sess_list_mutex );
    if (rc != CKR_OK){
       st_err_log(146, __FILE__, __LINE__); 
-      return rc;
+      return FALSE;        // FIXME: return proper errors
    }
-   node = sess_list;
-   while (node) {
-      SESSION *s = (SESSION *)node->data;
-      if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) ||
-          (s->session_info.state == CKS_RW_USER_FUNCTIONS))
-      {
-         rc = TRUE;
-         goto done;
-      }
 
-      node = node->next;
-   }
+   result = ( (global_login_state == CKS_RO_USER_FUNCTIONS) || 
(global_login_state == CKS_RW_USER_FUNCTIONS) );
 
-   rc = FALSE;
-
-done:
    MY_UnlockMutex( &sess_list_mutex );
-   return rc;
+   return result;
 }
 
 
@@ -560,32 +517,20 @@ done:
 CK_BBOOL
 session_mgr_public_session_exists( void )
 {
-   DL_NODE *node = NULL;
-   CK_RV    rc;
+   CK_BBOOL result;
+   CK_RV rc;
 
+   /* we must acquire sess_list_mutex in order to inspect glogal_login_state */
    rc = MY_LockMutex( &sess_list_mutex );
    if (rc != CKR_OK){
       st_err_log(146, __FILE__, __LINE__); 
-      return rc;
-   }
-   node = sess_list;
-   while (node) {
-      SESSION *s = (SESSION *)node->data;
-      if ((s->session_info.state == CKS_RO_PUBLIC_SESSION) ||
-          (s->session_info.state == CKS_RW_PUBLIC_SESSION))
-      {
-          rc = TRUE;
-          goto done;
-      }
-
-      node = node->next;
+      return FALSE;      // FIXME: return proper errors
    }
 
-   rc = FALSE;
+   result = ( (global_login_state == CKS_RO_PUBLIC_SESSION) || 
(global_login_state == CKS_RW_PUBLIC_SESSION) );
 
-done:
    MY_UnlockMutex( &sess_list_mutex );
-   return rc;
+   return result;
 }
 
 
@@ -595,32 +540,22 @@ done:
 // because the SO cannot log in if a read-only session exists.
 //
 CK_BBOOL
-session_mgr_readonly_exists( void )
+session_mgr_readonly_session_exists( void )
 {
-   DL_NODE *node = NULL;
-   CK_RV    rc;
+   CK_BBOOL result;
+   CK_RV rc;
 
+   /* we must acquire sess_list_mutex in order to inspect glogal_login_state */
    rc = MY_LockMutex( &sess_list_mutex );
    if (rc != CKR_OK){
       st_err_log(146, __FILE__, __LINE__); 
       return rc;
    }
-   node = sess_list;
-   while (node) {
-      SESSION *s = (SESSION *)node->data;
-      if ((s->session_info.flags & CKF_RW_SESSION) == 0) {
-         rc = TRUE;
-         goto done;
-      }
 
-      node = node->next;
-   }
-
-   rc = FALSE;
+   result = (ro_session_count > 0);
 
-done:
    MY_UnlockMutex( &sess_list_mutex );
-   return rc;
+   return result;
 }
 
 
@@ -656,6 +591,11 @@ session_mgr_close_session( SESSION *sess )
 
    object_mgr_purge_session_objects( sess, ALL );
 
+   if ( (sess->session_info.state == CKS_RO_PUBLIC_SESSION) ||
+        (sess->session_info.state == CKS_RO_USER_FUNCTIONS) ) {
+      ro_session_count--;
+   }
+
    if (sess->find_list)
       free( sess->find_list );
 
@@ -706,7 +646,7 @@ session_mgr_close_session( SESSION *sess )
        // SAB  XXX  if all sessions are closed.  Is this effectivly logging out
           object_mgr_purge_private_token_objects();
    
-               global_login_state = 0;
+               global_login_state = CKS_RO_PUBLIC_SESSION;
       // The objects really need to be purged .. but this impacts the
       // performance under linux.   So we need to make sure that the 
       // login state is valid.    I don't really like this.
@@ -778,6 +718,8 @@ session_mgr_close_all_sessions( void )
       sess_list = dlist_remove_node( sess_list, sess_list );
    }
 
+   ro_session_count = 0;
+
    MY_UnlockMutex( &sess_list_mutex );
    return CKR_OK;
 }
-- 
1.6.6.1


------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
Opencryptoki-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opencryptoki-tech

Reply via email to