From 11223e225396afca6bea8f3c2b42893ba364ac25 Mon Sep 17 00:00:00 2001
From: Per Cederqvist <ceder@lysator.liu.se>
Date: Mon, 16 Dec 1991 16:44:05 +0000
Subject: [PATCH] The asyncronous messages sent when a new text is created
 could previously contain information about secret conferences. This has now
 been fixed.

---
 src/server/ChangeLog    |  31 ++++++++
 src/server/conference.c |   6 +-
 src/server/manipulate.h |   8 +-
 src/server/membership.c |  25 ++++--
 src/server/send-async.c |  91 ++++------------------
 src/server/send-async.h |   7 +-
 src/server/text.c       | 169 ++++++++++++++++++++++++++++++++--------
 7 files changed, 212 insertions(+), 125 deletions(-)

diff --git a/src/server/ChangeLog b/src/server/ChangeLog
index 2edf278dd..2beadd1cb 100644
--- a/src/server/ChangeLog
+++ b/src/server/ChangeLog
@@ -1,3 +1,34 @@
+Mon Dec 16 15:32:57 1991  Per Cederqvist  (ceder at ruben)
+
+	* All the changes below fixes one single bug. When a text is
+	  created that has both a secret and a public conference as
+	  recipient the asynchronous messages that were sent out did not
+	  filter away the secret conference. This has how been fixed.
+
+	* conference.c (lookup_name): Use the new fast_access_perm().
+
+	* membership.c manipulate.h (fast_access_perm): New arguments:
+	  viewer and viewer_p.
+
+	* membership.c (copy_public_confs): Use the new fast_access_perm().
+
+	* send-async.c, text.c (is_member_in_recpt): Moved from
+	  send-async.c to text.c.
+
+	* send-async.h, send-async.c (async_new_text): Sends to a
+	  specified connection.
+
+	* text.c (create_text, create_anonymous_text): Use
+	  send_async_new_text.
+
+	* text.c (send_async_new_text): New function.
+
+	* text.c (get_text_stat): Use filter_secret_info.
+
+	* text.c (filter_secret_info): New function that given a text-stat
+	  and a person number yields a new text-stat that only contains
+	  tha recipients that the viewer is allowed to know about.
+
 Mon Nov 11 01:08:09 1991  Per Cederqvist  (ceder at ruben)
 
 	* fncdef.txt, prot-a.c, text.c: Added create_anonymous_text.
diff --git a/src/server/conference.c b/src/server/conference.c
index a343665ae..bf3eb256a 100644
--- a/src/server/conference.c
+++ b/src/server/conference.c
@@ -1,5 +1,5 @@
 /*
- * $Id: conference.c,v 0.13 1991/10/16 17:23:24 ceder Exp $
+ * $Id: conference.c,v 0.14 1991/12/16 16:44:03 ceder Exp $
  * Copyright (C) 1991  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -28,7 +28,7 @@
  * All atomic calls that deals with conferences.
  */
 
-static char *rcsid = "$Id: conference.c,v 0.13 1991/10/16 17:23:24 ceder Exp $";
+static char *rcsid = "$Id: conference.c,v 0.14 1991/12/16 16:44:03 ceder Exp $";
 
 
 #include <time.h>
@@ -499,7 +499,7 @@ lookup_name (const String    name,
 
     for ( i = result->no_of_conf_nos; i > 0; i-- )
     {
-	if ( fast_access_perm( *no ) <= none )
+	if ( fast_access_perm (*no, ACTPERS, ACT_P) <= none )
 	    --result->no_of_conf_nos;
 	else
 	{
diff --git a/src/server/manipulate.h b/src/server/manipulate.h
index 74381b329..0ee929f30 100644
--- a/src/server/manipulate.h
+++ b/src/server/manipulate.h
@@ -1,5 +1,5 @@
 /*
- * $Id: manipulate.h,v 0.3 1991/09/15 10:31:20 linus Exp $
+ * $Id: manipulate.h,v 0.4 1991/12/16 16:44:00 ceder Exp $
  * Copyright (C) 1991  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -23,7 +23,7 @@
  * Please mail bug reports to bug-lyskom@lysator.liu.se. 
  */
 /*
- * $Id: manipulate.h,v 0.3 1991/09/15 10:31:20 linus Exp $
+ * $Id: manipulate.h,v 0.4 1991/12/16 16:44:00 ceder Exp $
  *
  * manipulate.h
  *
@@ -392,7 +392,9 @@ access_perm(Conf_no 	  victim,
  *	error:	   see kom_errno
  */
 Access
-fast_access_perm(Conf_no victim);
+fast_access_perm(Conf_no  victim,
+		 Pers_no  viewer,
+		 Person  *viewer_p);
 
 
 /*
diff --git a/src/server/membership.c b/src/server/membership.c
index 07239fe5b..167b7b59e 100644
--- a/src/server/membership.c
+++ b/src/server/membership.c
@@ -1,5 +1,5 @@
 /*
- * $Id: membership.c,v 0.6 1991/09/21 13:07:01 ceder Exp $
+ * $Id: membership.c,v 0.7 1991/12/16 16:43:58 ceder Exp $
  * Copyright (C) 1991  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -29,7 +29,7 @@
  * (The person/conf relation).
  */
 
-static char *rcsid = "$Id: membership.c,v 0.6 1991/09/21 13:07:01 ceder Exp $";
+static char *rcsid = "$Id: membership.c,v 0.7 1991/12/16 16:43:58 ceder Exp $";
 
 #include <time.h>
 #include <stdlib.h>
@@ -88,7 +88,7 @@ copy_public_confs (Person   * censor_p,	/* The censored Person-struct */
 
     for ( i = 0; i < orig_p->conferences.no_of_confs; i++, orig_m++ )
     {
-	if ( fast_access_perm( orig_m->conf_no ) > none )
+	if ( fast_access_perm (orig_m->conf_no, ACTPERS, ACT_P) > none )
 	{
 	    *censor_m = *orig_m;
 
@@ -634,20 +634,31 @@ access_perm(Conf_no 	  victim,
 /*
  * Fast version of access_perm. See comment in file server/manipulate.h
  * where Access is defined.
+ *
+ * Check if viewer is allowed to look at victiom. viewer_p, if
+ * supplied, should be a pointer to the pers-stat of viewer.
  */
 Access
-fast_access_perm(Conf_no victim)
+fast_access_perm(Conf_no  victim,
+		 Pers_no  viewer,
+		 Person  *viewer_p) /* May be NULL. */
 {
     Conf_type conf_type;
 
     if ( !cached_conf_exists(victim) )
 	return error;
 
-    if ( ACTPERS != 0 && (ENA(admin, 2) || ENA(wheel,8) || ACTPERS == victim) )
+    if ( viewer != 0 && (ENA(admin, 2) || ENA(wheel,8) || viewer == victim) )
     	return unlimited;
 
-    if ( ACTPERS != 0 && locate_membership( victim, ACT_P ) != NULL )
-    	return member;
+    if ( viewer != 0 )
+    {
+	if ( viewer_p == NULL )
+	    GET_P_STAT(viewer_p, viewer, error);
+
+	if ( locate_membership( victim, viewer_p ) != NULL )
+	    return member;
+    }
 
     if ( (conf_type=cached_get_conf_type( victim )).secret )
 	return access_perm(victim, NULL); /* Only read in conference struct
diff --git a/src/server/send-async.c b/src/server/send-async.c
index 009d6e2d0..d2c1293b3 100644
--- a/src/server/send-async.c
+++ b/src/server/send-async.c
@@ -1,5 +1,5 @@
 /*
- * $Id: send-async.c,v 0.3 1991/09/15 10:29:22 linus Exp $
+ * $Id: send-async.c,v 0.4 1991/12/16 16:43:56 ceder Exp $
  * Copyright (C) 1991  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -28,7 +28,7 @@
  * Written by Per Cederqvist 1990-07-22--23
  */
 
-static char *rcsid = "$Id: send-async.c,v 0.3 1991/09/15 10:29:22 linus Exp $";
+static char *rcsid = "$Id: send-async.c,v 0.4 1991/12/16 16:43:56 ceder Exp $";
 
 
 #include <stdio.h>
@@ -49,87 +49,24 @@ static char *rcsid = "$Id: send-async.c,v 0.3 1991/09/15 10:29:22 linus Exp $";
 extern Bool		  send_async_messages;
 
 
-/*
- * Check if person is a member in any of the recipients or cc_recipients
- * of text_s
- */
-static  Bool
-is_member_in_recpt(Person    * person,
-		   Text_stat * text_s)
-{
-    int i;
-
-    for ( i = 0; i < text_s->no_of_misc; i++ )
-    {
-	switch(text_s->misc_items[ i ].type)
-	{
-	case recpt:
-	    if ( locate_membership(text_s->misc_items[ i ].datum.recipient,
-				   person) != NULL )
-	    {
-		return TRUE;
-	    }
-	    break;
-
-	case cc_recpt:
-	    if ( locate_membership(text_s->misc_items[ i ].datum.cc_recipient,
-				   person) != NULL )
-	    {
-		return TRUE;
-	    }
-	    break;
-
-	case comm_to:
-	case comm_in:
-	case footn_to:
-	case footn_in:
-	case loc_no:
-	case rec_time:
-	case sent_by:
-	case sent_at:
-	    break;
-
-#ifndef COMPILE_CHECKS
-	default:
-	    log(__FILE__ ": is_member_in_recpt(): bad misc_item.\n");
-	    break;
-#endif
-	}
-    }
-
-    return FALSE;
-}
-
 void
-async_new_text(Text_no    text_no, 
-	       Text_stat *text_s)
+async_new_text(struct connection *cptr,
+	       Text_no    	  text_no, 
+	       Text_stat         *text_s)
 {
-    Connection *cptr;
-    Session_no i = 0;
-
     if (!send_async_messages)
 	return;
 
-    while ( (i = traverse_connections(i)) != 0 )
+    switch(cptr->protocol)
     {
-	cptr = get_conn_by_number(i);
-	       
-	if ( cptr->person != NULL
-	    && is_member_in_recpt( cptr->person, text_s ) )
-	{
-	    switch(cptr->protocol)
-	    {
-	    case 0:
-		break;
-	    case 'A':
-		prot_a_async_new_text(cptr, text_no, text_s);
-		break;
-	    default:
-		restart_kom("async_new_text(): bad protocol.\n");
-		break;
-	    }
-	    
-	}
+    case 0:
+	break;
+    case 'A':
+	prot_a_async_new_text(cptr, text_no, text_s);
+	break;
+    default:
+	restart_kom("async_new_text(): bad protocol.\n");
+	break;
     }
 }
 
diff --git a/src/server/send-async.h b/src/server/send-async.h
index a5c1dc739..1233bd0df 100644
--- a/src/server/send-async.h
+++ b/src/server/send-async.h
@@ -1,5 +1,5 @@
 /*
- * $Id: send-async.h,v 0.3 1991/09/15 10:29:19 linus Exp $
+ * $Id: send-async.h,v 0.4 1991/12/16 16:43:54 ceder Exp $
  * Copyright (C) 1991  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -23,11 +23,12 @@
  * Please mail bug reports to bug-lyskom@lysator.liu.se. 
  */
 /*
- * $Id: send-async.h,v 0.3 1991/09/15 10:29:19 linus Exp $
+ * $Id: send-async.h,v 0.4 1991/12/16 16:43:54 ceder Exp $
  *
  */
 extern void
-async_new_text(Text_no text_no, 
+async_new_text(Connection *cptr,
+	       Text_no text_no, 
 	       Text_stat *text_s);
 
 extern void
diff --git a/src/server/text.c b/src/server/text.c
index 37bc0617d..94d0d52b6 100644
--- a/src/server/text.c
+++ b/src/server/text.c
@@ -1,5 +1,5 @@
 /*
- * $Id: text.c,v 0.10 1991/11/11 00:27:17 ceder Exp $
+ * $Id: text.c,v 0.11 1991/12/16 16:43:51 ceder Exp $
  * Copyright (C) 1991  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -28,7 +28,7 @@
  * All atomic calls that deals with texts.
  */
 
-static char *rcsid = "$Id: text.c,v 0.10 1991/11/11 00:27:17 ceder Exp $";
+static char *rcsid = "$Id: text.c,v 0.11 1991/12/16 16:43:51 ceder Exp $";
 
 #include <time.h>
 #include <stdlib.h>
@@ -47,6 +47,7 @@ static char *rcsid = "$Id: text.c,v 0.10 1991/11/11 00:27:17 ceder Exp $";
 #include "connections.h"
 #include "send-async.h"
 #include "admin.h"
+#include "internal-connections.h"
 
 /*
  * Static functions
@@ -1266,49 +1267,96 @@ get_text (Text_no       text_no,
     return OK;
 }
 
+
+
 /*
- * Get text status.
- *
- * If there are recipients of the text that are secret confs
- * those misc-items will be censored.
+ * Check if person is a member in any of the recipients or cc_recipients
+ * of text_s
  */
-extern Success
-get_text_stat (Text_no	  text_no,
-	       Text_stat *result )
+static  Bool
+is_member_in_recpt(Person    *person,
+		   Text_stat *text_s)
 {
-    Text_stat	* text_stat;
-    Misc_info	* orig;
-    Misc_info	* copy;		/* Censored Misc_infos */
+    int i;
 
-    GET_T_STAT(text_stat, text_no, FAILURE);
-    
-    if ( !text_read_access(text_no, text_stat) && !ENA(admin, 2))
+    for ( i = 0; i < text_s->no_of_misc; i++ )
     {
-	kom_errno = KOM_NO_SUCH_TEXT;
-	return FAILURE;
+	switch(text_s->misc_items[ i ].type)
+	{
+	case recpt:
+	    if ( locate_membership(text_s->misc_items[ i ].datum.recipient,
+				   person) != NULL )
+	    {
+		return TRUE;
+	    }
+	    break;
+
+	case cc_recpt:
+	    if ( locate_membership(text_s->misc_items[ i ].datum.cc_recipient,
+				   person) != NULL )
+	    {
+		return TRUE;
+	    }
+	    break;
+
+	case comm_to:
+	case comm_in:
+	case footn_to:
+	case footn_in:
+	case loc_no:
+	case rec_time:
+	case sent_by:
+	case sent_at:
+	    break;
+
+#ifndef COMPILE_CHECKS
+	default:
+	    log(__FILE__ ": is_member_in_recpt(): bad misc_item.\n");
+	    break;
+#endif
+	}
     }
 
-    *result = *text_stat;
-    
-    /* Delete secret confs */
+    return FALSE;
+}
+
+
+/*
+ * Copy the text_stat original into result, but only those part
+ * that viewer is allowed to see. (Censor away information about
+ * conferences that viewer is not allowed to know about).
+ *
+ * All memory is allocated via tmp_alloc().
+ */
+static void
+filter_secret_info(Text_stat *result,
+		   Text_stat *original,
+		   Pers_no    viewer,
+		   Person    *viewer_p)	/* May be NULL. */
+{
+    Misc_info	* orig;
+    Misc_info	* copy;		/* Censored Misc_infos */
 
     /* ^^^ Possible optimisation:
        No need to copy unless there is a secret conf among the recipients. */
 
+    *result = *original;
+
     result->misc_items = tmp_alloc(result->no_of_misc * sizeof ( Misc_info));
     result->no_of_misc = 0;
     copy = result->misc_items;
-    orig = text_stat->misc_items;    
+    orig = original->misc_items;    
     
-    while ( orig < text_stat->misc_items + text_stat->no_of_misc )
+    while ( orig < original->misc_items + original->no_of_misc )
     {
 	switch( orig->type )
 	{
 	case recpt:
-	    if ( fast_access_perm( orig->datum.recipient ) <= none 
+	    if ( (fast_access_perm (orig->datum.recipient, viewer, viewer_p)
+		  <= none )
 		&& !ENA(admin, 4))
 	    {
-		skip_recp ( &orig, text_stat );
+		skip_recp ( &orig, original );
 	    }
 	    else
 	    {
@@ -1318,10 +1366,11 @@ get_text_stat (Text_no	  text_no,
 	    break;
 
 	case cc_recpt:
-	    if ( fast_access_perm( orig->datum.cc_recipient ) <= none
+	    if ( (fast_access_perm (orig->datum.cc_recipient, viewer, viewer_p)
+		  <= none)
 		&& !ENA(admin, 4))
 	    {
-		skip_recp ( &orig, text_stat );
+		skip_recp ( &orig, original );
 	    }
 	    else
 	    {
@@ -1344,10 +1393,33 @@ get_text_stat (Text_no	  text_no,
 
 #ifndef COMPILE_CHECKS
 	default:
-	    restart_kom("get_text_stat() - illegal misc_item!\n");    
+	    restart_kom("filter_secret_info() - illegal misc_item!\n");    
 #endif
 	}
     }
+}
+
+/*
+ * Get text status.
+ *
+ * If there are recipients of the text that are secret confs
+ * those misc-items will be censored.
+ */
+extern Success
+get_text_stat (Text_no	  text_no,
+	       Text_stat *result )
+{
+    Text_stat	* text_stat;
+
+    GET_T_STAT(text_stat, text_no, FAILURE);
+    
+    if ( !text_read_access(text_no, text_stat) && !ENA(admin, 2))
+    {
+	kom_errno = KOM_NO_SUCH_TEXT;
+	return FAILURE;
+    }
+
+    filter_secret_info(result, text_stat, ACTPERS, ACT_P);
     return OK;
 }
 
@@ -1634,6 +1706,39 @@ create_text_add_miscs(Text_no     new_text,
     return OK;
 }
 
+/*
+ * Send an asynchronous message, but filter any secret information.
+ */
+
+static void
+send_async_new_text (Text_no text_no,
+		     Text_stat *text_s)
+{
+    Connection *cptr;
+    Session_no i = 0;
+    Text_stat filtered = EMPTY_TEXT_STAT;
+
+    while ( (i = traverse_connections(i)) != 0 )
+    {
+	cptr = get_conn_by_number(i);
+
+	/*
+	 * filter_secret_info copies the text-stat to filtered, but
+	 * since it is allocated with tmp_alloc we do not need to free
+	 * the memory now.
+	 */
+	filter_secret_info(&filtered, text_s, 
+			   cptr->pers_no, cptr->person);
+
+	if ( cptr->person != NULL
+	    && is_member_in_recpt (cptr->person, &filtered) )
+	{
+	    async_new_text (cptr, text_no, &filtered);
+	}
+    }
+}
+    
+
 /*
  * Create a text.
  *
@@ -1697,10 +1802,10 @@ create_text(String	  message,
     ACT_P->created_lines += t_stat->no_of_lines;
     ACT_P->created_bytes += t_stat->no_of_chars;
 
-    mark_person_as_changed( ACTPERS );
-    mark_text_as_changed( text );
+    mark_person_as_changed (ACTPERS);
+    mark_text_as_changed (text);
 
-    async_new_text( text, t_stat );	/* Send asynchronous message. */
+    send_async_new_text (text, t_stat);     /* Send asynchronous message. */
 
     return text;
 }
@@ -1763,10 +1868,10 @@ create_anonymous_text(String	  message,
 	return 0;
     }
 
-    mark_text_as_changed( text );
+    mark_text_as_changed (text);
     /* Don't add this person to create - we want true anonymity! */
 
-    async_new_text( text, t_stat );	/* Send asynchronous message. */
+    send_async_new_text (text, t_stat);
 
     return text;
 }
-- 
GitLab