Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
authorDan
Sat, 23 Jun 2007 09:55:58 -0400
changeset 15 ad5986a53197
parent 14 ce6053bb48d8
child 16 64e0d3d4cf14
Fixed complicated SQL injection vulnerability in URL handler, updated license info for Tigra Tree Menu, and killed one XSS vulnerability
TODO
ajax.php
includes/clientside/static/admin-menu.js
includes/clientside/static/ajax.js
includes/dbal.php
includes/functions.php
includes/pageprocess.php
includes/pageutils.php
includes/paths.php
includes/template.php
index.php
licenses/index.html
licenses/tigra-menu.html
plugins/SpecialAdmin.php
--- a/TODO	Fri Jun 22 18:42:26 2007 -0400
+++ b/TODO	Sat Jun 23 09:55:58 2007 -0400
@@ -24,7 +24,7 @@
 [x] Change the string shown on a successful re-auth into elevated privileges
     [x] ...and write a function that converts a numeric userlevel to a string
 [x] Make Special:Login remember parameters (target level, target page) even on auth fail
-[ ] Register users_extra table in system tables list (already done?)
+[x] Register users_extra table in system tables list (already done?)
 [x] Trigger form submit on press of enter in Dynano login form
 [ ] Rewrite the change theme dialog - it's archaic code that hasn't changed since beta 1!
     [ ] This should be the next-to-last step in phasing out the JWS code, which should be removed in the first 1.1 alpha
--- a/includes/clientside/static/admin-menu.js	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/clientside/static/admin-menu.js	Sat Jun 23 09:55:58 2007 -0400
@@ -27,7 +27,11 @@
  *
  * - Header block of script file (tree.js) CAN NOT be modified or removed.
  * - The above items CAN NOT be sold as are, either individually or together.
- * - The above items CAN NOT be modified and then sold as a library component, either individually or together. 
+ * - The above items CAN NOT be modified and then sold as a library component, either individually or together.
+ *
+ * Due to the unclear licensing conditions on this script, I contacted the author, who said that because Enano
+ * is not a "competing product" I was allowed to treat the code as GPL. The conversation can be seen in the
+ * /licenses/tigra-menu.html document in the Enano distribution.
  */
  
 var ck = readCookie('admin_menu_state');
--- a/includes/clientside/static/ajax.js	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/clientside/static/ajax.js	Sat Jun 23 09:55:58 2007 -0400
@@ -466,6 +466,13 @@
 
 function ajaxChangeStyle()
 {
+  var inner_html = '';
+  inner_html += '';
+}
+
+/*
+function ajaxChangeStyle()
+{
   var win = document.getElementById("cn2");
   win.innerHTML = ' \
     <form action="'+ENANO_SPECIAL_CHANGESTYLE+'" onsubmit="jws.closeWin(\'root2\');" method="post" style="text-align: center"> \
@@ -501,6 +508,7 @@
     }
   });
 }
+*/
 
 function ajaxSwapCSS() {
   setAjaxLoading();
--- a/includes/dbal.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/dbal.php	Sat Jun 23 09:55:58 2007 -0400
@@ -80,7 +80,7 @@
       ob_clean();
     }
     header('HTTP/1.1 500 Internal Server Error');
-    $bt = $this->sql_backtrace();
+    $bt = $this->latest_query; // $this->sql_backtrace();
     $e = htmlspecialchars(mysql_error());
     if($e=='') $e='&lt;none&gt;';
     if(defined('ENANO_CONFIG_FETCHED')) die_semicritical('Database error', '<h3>An error occurred during a database query.</h3><p>'.$t.'<br />Error returned by MySQL: '.$e.'<br />SQL Backtrace:</p><pre>'.$bt.'</pre>');
--- a/includes/functions.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/functions.php	Sat Jun 23 09:55:58 2007 -0400
@@ -1443,6 +1443,12 @@
     
   }
   
+  // Vulnerability from ha.ckers.org/xss.html:
+  // <script src="http://foo.com/xss.js"
+  // <
+  // The rule is so specific because everything else will have been filtered by now
+  $html = preg_replace('/<(script|iframe)(.+?)src=([^>]*)</i', '&lt;\\1\\2src=\\3&lt;', $html);
+  
   return $html;
   
 }
@@ -1834,19 +1840,8 @@
 function sanitize_page_id($page_id)
 {
   
-  // First, replace spaces with underscores  
-  $page_id = str_replace(' ', '_', $page_id);
-  
-  preg_match_all('/\.[A-Fa-f0-9][A-Fa-f0-9]/', $page_id, $matches);
-  
-  foreach ( $matches[0] as $id => $char )
-  {
-    $char = substr($char, 1);
-    $char = strtolower($char);
-    $char = intval(hexdec($char));
-    $char = chr($char);
-    $page_id = str_replace($matches[0][$id], $char, $page_id);
-  }
+  // Remove character escapes
+  $page_id = dirtify_page_id($page_id);
   
   $pid_clean = preg_replace('/[\w\/:;\(\)@\[\]_-]/', 'X', $page_id);
   $pid_dirty = enano_str_split($pid_clean, 1);
@@ -1887,6 +1882,31 @@
 }
 
 /**
+ * Removes character escapes in a page ID string
+ * @param string Page ID string to dirty up
+ * @return string
+ */
+
+function dirtify_page_id($page_id)
+{
+  // First, replace spaces with underscores  
+  $page_id = str_replace(' ', '_', $page_id);
+  
+  preg_match_all('/\.[A-Fa-f0-9][A-Fa-f0-9]/', $page_id, $matches);
+  
+  foreach ( $matches[0] as $id => $char )
+  {
+    $char = substr($char, 1);
+    $char = strtolower($char);
+    $char = intval(hexdec($char));
+    $char = chr($char);
+    $page_id = str_replace($matches[0][$id], $char, $page_id);
+  }
+  
+  return $page_id;
+}
+
+/**
  * Inserts commas into a number to make it more human-readable. Floating point-safe.
  * @param int The number to process
  * @return string Input number with commas added
--- a/includes/pageprocess.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/pageprocess.php	Sat Jun 23 09:55:58 2007 -0400
@@ -32,6 +32,13 @@
   var $namespace;
   
   /**
+   * Unsanitized page ID.
+   * @var string
+   */
+  
+  var $page_id_unclean;
+  
+  /**
    * Tracks if the page we're loading exists in the database or not.
    * @var bool
    */
@@ -148,6 +155,10 @@
         return false;
       }
     }
+    else if ( $this->namespace == 'User' )
+    {
+      $this->_handle_userpage();
+    }
     else if ( ( $this->namespace == 'Template' || $this->namespace == 'System' ) && $this->page_exists )
     {
       $this->header();
@@ -181,7 +192,7 @@
         $this->err_page_not_existent();
       }
     }
-    else // if ( in_array($this->namespace, array('Article', 'User', 'Project', 'Help', 'File', 'Category')) && $this->page_exists )
+    else // (disabled for compatibility reasons) if ( in_array($this->namespace, array('Article', 'User', 'Project', 'Help', 'File', 'Category')) && $this->page_exists )
     {
       // Send as regular page
       $text = $this->fetch_text();
@@ -195,8 +206,6 @@
         $this->render();
       }
     }
-    
-    
   }
   
   /**
@@ -212,6 +221,7 @@
     
     $this->page_id = $page_id_cleaned;
     $this->namespace = $namespace;
+    $this->page_id_unclean = dirtify_page_id($page_id);
     
     $this->perms = $session->fetch_page_acl( $page_id, $namespace );
     
@@ -332,6 +342,105 @@
   }
   
   /**
+   * Handles the extra overhead required for user pages.
+   * @access private
+   */
+   
+  function _handle_userpage()
+  {
+    global $db, $session, $paths, $template, $plugins; // Common objects
+    
+    if ( $this->page_id == $paths->cpage['urlname_nons'] && $this->namespace == $paths->namespace )
+    {
+      $page_name = ( isset($paths->cpage['name']) ) ? $paths->cpage['name'] : $this->page_id;
+    }
+    else
+    {
+      $page_name = ( isset($paths->pages[$this->page_id]) ) ? $paths->pages[$this->page_id]['name'] : $this->page_id;
+    }
+    
+    if ( $page_name == str_replace('_', ' ', $this->page_id) || $page_name == $paths->nslist['User'] . str_replace('_', ' ', $this->page_id) )
+    {
+      $target_username = strtr($page_name, 
+        Array(
+          '_' => ' ',
+          '<' => '&lt;',
+          '>' => '&gt;'
+          ));
+      $target_username = preg_replace('/^' . preg_quote($paths->nslist['User']) . '/', '', $target_username);
+      $page_name = "$target_username's user page";
+    }
+    else
+    {
+      // User has a custom title for their userpage
+      $page_name = $paths->pages[ $paths->nslist[$this->namespace] . $this->page_id ]['name'];
+    }
+    
+    $template->tpl_strings['PAGE_NAME'] = htmlspecialchars($page_name);
+    
+    $this->header();
+    
+    if ( $send_headers )
+    {
+      display_page_headers();
+    }
+    
+    // Start left sidebar: basic user info, latest comments
+    
+    echo '<table border="0" cellspacing="4" cellpadding="0" style="width: 100%;">';
+    echo '<tr><td style="width: 150px;">';
+    
+    echo '<div class="tblholder">
+            <table border="0" cellspacing="1" cellpadding="4">';
+    
+    // Main part of sidebar
+            
+    echo '  </table>
+          </div>';
+    
+    echo '</td><td>';
+    
+    // User's own content
+    
+    $send_headers = $this->send_headers;
+    $this->send_headers = false;
+    
+    if ( $this->page_exists )
+    {
+      $this->render();
+    }
+    else
+    {
+      $this->err_page_not_existent();
+    }
+    
+    // Right sidebar
+    
+    echo '</td><td style="width: 150px;">';
+    
+    echo '<div class="tblholder">
+            <table border="0" cellspacing="1" cellpadding="4">';
+    
+    // Main part of sidebar
+            
+    echo '  </table>
+          </div>';
+          
+    echo '</tr></table>';
+    
+    if ( $send_headers )
+    {
+      display_page_footers();
+    }
+    
+    $this->send_headers = $send_headers;
+    unset($send_headers);
+    
+    $this->footer();
+    
+  }
+  
+  /**
    * Send the error message to the user that the access to this page is denied.
    * @access private
    */
--- a/includes/pageutils.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/pageutils.php	Sat Jun 23 09:55:58 2007 -0400
@@ -1194,16 +1194,29 @@
     $prot = ( ( $paths->pages[$pname]['protected'] == 2 && $session->user_logged_in && $session->reg_time + 60*60*24*4 < time() ) || $paths->pages[$pname]['protected'] == 1) ? true : false;
     $wiki = ( ( $paths->pages[$pname]['wiki_mode'] == 2 && getConfig('wiki_mode') == '1') || $paths->pages[$pname]['wiki_mode'] == 1) ? true : false;
     
-    if( empty($name)) die('Name is too short');
-    if( ( $session->get_permissions('rename') && ( ( $prot && $session->get_permissions('even_when_protected') ) || !$prot ) ) && ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' )) {
-      $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'rename\', \''.$paths->cpage['urlname_nons'].'\', \''.$paths->namespace.'\', \''.$session->username.'\', \''.$paths->cpage['name'].'\')');
-      if(!$e) $db->_die('The page title could not be updated.');
-      $e = $db->sql_query('UPDATE '.table_prefix.'pages SET name=\''.$db->escape($name).'\' WHERE urlname=\''.$page_id.'\' AND namespace=\''.$namespace.'\';');
-      if(!$e) $db->_die('The page title could not be updated.');
-      else return('The page "'.$paths->pages[$pname]['name'].'" has been renamed to "'.$name.'". You are encouraged to leave a comment explaining your action.
-
-You will see the change take effect the next time you reload this page.');
-    } else {
+    if( empty($name)) 
+    {
+      die('Name is too short');
+    }
+    if( ( $session->get_permissions('rename') && ( ( $prot && $session->get_permissions('even_when_protected') ) || !$prot ) ) && ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' ))
+    {
+      $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'rename\', \''.$db->escape($paths->cpage['urlname_nons']).'\', \''.$paths->namespace.'\', \''.$db->escape($session->username).'\', \''.$db->escape($paths->cpage['name']).'\')');
+      if ( !$e )
+      {
+        $db->_die('The page title could not be updated.');
+      }
+      $e = $db->sql_query('UPDATE '.table_prefix.'pages SET name=\''.$db->escape($name).'\' WHERE urlname=\''.$db->escape($page_id).'\' AND namespace=\''.$db->escape($namespace).'\';');
+      if ( !$e )
+      {
+        $db->_die('The page title could not be updated.');
+      }
+      else
+      {
+        return('The page "'.$paths->pages[$pname]['name'].'" has been renamed to "'.$name.'". You are encouraged to leave a comment explaining your action.' . "\n\n" . 'You will see the change take effect the next time you reload this page.');
+      }
+    }
+    else
+    {
       return('Access is denied.');
     }
   }
--- a/includes/paths.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/paths.php	Sat Jun 23 09:55:58 2007 -0400
@@ -246,6 +246,9 @@
       }
     }
     
+    $this->page = sanitize_page_id($this->page);
+    $this->fullpage = sanitize_page_id($this->fullpage);
+    
     dc_here('paths: setting $paths->cpage');
     
     if(isset($this->pages[$this->page]))
@@ -296,8 +299,17 @@
     {
       dc_here('paths: page doesn\'t exist, creating new page in memory<br />our page ID is: '.$this->page);
       $this->page_exists = false;
+      $page_name = dirtify_page_id($this->page);
+      $page_name = str_replace('_', ' ', $page_name);
+      
+      $pid_cleaned = sanitize_page_id($this->page);
+      if ( $pid_cleaned != $this->page )
+      {
+        redirect($pid_cleaned, 'Sanitizer message', 'page id sanitized', 0);
+      }
+      
       $this->cpage = Array(
-        'name'=>str_replace('_', ' ', $this->page),
+        'name'=>$page_name,
         'urlname'=>$this->page,
         'namespace'=>'Article',
         'special'=>0,
--- a/includes/template.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/includes/template.php	Sat Jun 23 09:55:58 2007 -0400
@@ -470,7 +470,7 @@
     }
     
     // Clear logs button
-    if ( $session->get_permissions('read') && $session->get_permissions('clear_logs') && $paths->wiki_mode && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
+    if ( $session->get_permissions('read') && $session->get_permissions('clear_logs') && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
     {
       $menubtn->assign_vars(array(
           'FLAGS' => 'onclick="void(ajaxClearLogs()); return false;" title="Remove all edit and action logs for this page from the database. IRREVERSIBLE! (alt-l)" accesskey="l"',
@@ -644,11 +644,14 @@
     
     $SID = ($session->sid_super) ? $session->sid_super : '';
     
+    $urlname_clean = str_replace('\'', '\\\'', str_replace('\\', '\\\\', dirtify_page_id($paths->fullpage)));
+    $urlname_clean = strtr( $urlname_clean, array( '<' => '&lt;', '>' => '&gt;' ) );
+    
     // Generate the dynamic javascript vars
     $js_dynamic = '    <script type="text/javascript">// <![CDATA[
       // This section defines some basic and very important variables that are used later in the static Javascript library.
       // SKIN DEVELOPERS: The template variable for this code block is {JS_DYNAMIC_VARS}. This MUST be inserted BEFORE the tag that links to the main Javascript lib.
-      var title=\''. str_replace('\'', '\\\'', str_replace('\\', '\\\\', $paths->fullpage)) .'\';
+      var title=\''. $urlname_clean .'\';
       var page_exists='. ( ( $paths->page_exists) ? 'true' : 'false' ) .';
       var scriptPath=\''. scriptPath .'\';
       var contentPath=\''.contentPath.'\';
@@ -662,7 +665,7 @@
       var editNotice = \'' . ( (getConfig('wiki_edit_notice')=='1') ? str_replace("\n", "\\\n", RenderMan::render(getConfig('wiki_edit_notice_text'))) : '' ) . '\';
       var prot = ' . ( ($paths->page_protected && !$session->get_permissions('even_when_protected')) ? 'true' : 'false' ) .'; // No, hacking this var won\'t work, it\'s re-checked on the server
       var ENANO_SPECIAL_CREATEPAGE = \''. makeUrl($paths->nslist['Special'].'CreatePage') .'\';
-      var ENANO_CREATEPAGE_PARAMS = \'_do=&pagename='. addslashes($paths->cpage['name']) .'&namespace=' . $paths->namespace . '\';
+      var ENANO_CREATEPAGE_PARAMS = \'_do=&pagename='. $urlname_clean .'&namespace=' . $paths->namespace . '\';
       var ENANO_SPECIAL_CHANGESTYLE = \''. makeUrlNS('Special', 'ChangeStyle') .'\';
       var namespace_list = new Array();
       var AES_BITS = '.AES_BITS.';
@@ -684,10 +687,10 @@
         $js_dynamic .= "namespace_list['{$k}'] = '$c';";
       }
       $js_dynamic .= "\n    //]]>\n    </script>";
-    
+      
     $tpl_strings = Array(
-      'PAGE_NAME'=>$paths->cpage['name'],
-      'PAGE_URLNAME'=>$paths->cpage['urlname'],
+      'PAGE_NAME'=>htmlspecialchars($paths->cpage['name']),
+      'PAGE_URLNAME'=> $urlname_clean,
       'SITE_NAME'=>getConfig('site_name'),
       'USERNAME'=>$session->username,
       'SITE_DESC'=>getConfig('site_desc'),
--- a/index.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/index.php	Sat Jun 23 09:55:58 2007 -0400
@@ -14,7 +14,7 @@
  
   // Set up gzip encoding before any output is sent
   
-  $aggressive_optimize_html = true;
+  $aggressive_optimize_html = false;
   
   global $do_gzip;
   $do_gzip = false;
--- a/licenses/index.html	Fri Jun 22 18:42:26 2007 -0400
+++ b/licenses/index.html	Sat Jun 23 09:55:58 2007 -0400
@@ -82,8 +82,9 @@
 <ul>
   <li><a href="http://phpwiki.sourceforge.net/">phpWiki</a> - just the diff engine, which is also used in MediaWiki</li>
   <li><a href="http://www.mediawiki.org/">MediaWiki</a>'s table parsing engine (the Text_Wiki one doesn't work in PHP 5.2.0)</li>
-  <li>One of the CAPTCHA easter eggs was ported from the phpBB <a href="http://phpbbhacks.com/download/6276">Advanced Visual Confirmation Mod</a>. The strange thing here is this: The installation instructions expressly state that the MOD is distributed under the GPL, but immediately afterwards it says that the MOD "can be freely used, but not distributed, without permission." Sorry buddy, but I'm with the FSF on this one, I'm legally allowed to distribute/modify it under the GPL.
+  <li>One of the CAPTCHA easter eggs was ported from the phpBB <a href="http://phpbbhacks.com/download/6276">Advanced Visual Confirmation Mod</a>. The strange thing here is this: The installation instructions expressly state that the MOD is distributed under the GPL, but immediately afterwards it says that the MOD "can be freely used, but not distributed, without permission." Sorry buddy, but I'm with the FSF on this one, I'm legally allowed to distribute/modify it under the GPL.</li>
   <li>The <a href="http://www.jracademy.com/~jtucek/">e-mail address encryption</a> routine was originally written by Jim Tucek, and ported to PHP by Dan Fuhry. Jim allowed the code to be released under the GPL specifically for Enano.</li>
+  <li><a href="http://www.softcomplex.com/products/tigra_tree_menu/">Tigra Tree Menu</a> - a modified version that remembers the state of the tree. The license terms are stated <a href="http://www.softcomplex.com/products/tigra_tree_menu/docs/#terms_cond">here</a>. After <a href="tigra-menu.html">contacting the author</a>, I was given permission to use the Tigra Tree Menu code as if it were under the GNU GPL. Therefore, you may use this code unde the terms of the GPL, however if you're making commercial use of it, the Softcomplex guys would appreciate if (but not require that) you would contact them first.</li>
 </ul>
 
 <h2>GNU Lesser General Public License</h2>
@@ -122,7 +123,6 @@
 <ul>
   <li><a href="http://www.thecodebehind.com/code/slide-in-slide-out-ala-digg.aspx">Slide-in-slide-out, ala Digg</a> - used for the collapsible sidebar headings in the Oxygen theme. The original author says the code may be used "for whatever you want."</li>
   <li><a href="http://szewo.com/php/graph">Graph Generator for PHP</a> - only used when the GD-based graph generator won't work (e.g. no GD support)</li>
-  <li><a href="http://www.softcomplex.com/products/tigra_tree_menu/">Tigra Tree Menu</a> - a modified version that remembers the state of the tree. The license terms are stated <a href="http://www.softcomplex.com/products/tigra_tree_menu/docs/#terms_cond">here</a>. I believe that these terms are GPL-compatible, at least to a point where the code can be used in GPL-licensed programs. If you believe this is not the case then please <a href="http://enano.homelinux.org/Contact_us">contact me</a>.</li>
 </ul>
 
 <div class="copyright">valid <a href="http://validator.w3.org/check/referer">xhtml</a> and <a href="http://jigsaw.w3.org/css-validator/validator?uri=referer">css</a>&nbsp;&nbsp;|&nbsp;&nbsp;design by <a href="http://enano.homelinux.org/User:dandaman32">dan fuhry</a> and <a href="http://www.fusionnerd.com/">manoj maddali</a></div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/licenses/tigra-menu.html	Sat Jun 23 09:55:58 2007 -0400
@@ -0,0 +1,6 @@
+<html>
+<head><title>817108</title></head>
+<body><h1>Conversation with 817108</h1>
+<font color="#204a87"><font size="2">(06:59:52 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> is this the ICQ support for the Softcomplex/Tigra products?</font><br><font color="#204a87"><font size="2">(07:00:42 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> i would like to know about the licensing terms for the Tigra Tree Menu</font><br><font size="2"><font color="#cc0000">(07:01:12 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> sure</font><br><font color="#204a87"><font size="2">(07:01:52 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> according to the license terms, I should be allowed to modify the code, and then distribute it in my own free software, correct?</font><br><font color="#204a87"><font size="2">(07:02:23 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> full credit is given in the source code, as shown in: <a href="http://nighthawk.enanocms.org/includes/clientside/static/admin-menu.js">http://nighthawk.enanocms.org/includes/clientside/static/admin-menu.js</a></font><br><font size="2"><font color="#cc0000">(07:02:23 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> yep</font><br><font color="#204a87"><font size="2">(07:02:41 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> are you familiar with the GNU General Public License at all?</font><br><font size="2"><font color="#cc0000">(07:03:10 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> yep, but I'm not a legal type</font><br><font size="2"><font color="#cc0000">(07:03:35 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> If you prefer GNU, then consider it GNU</font><br><font color="#204a87"><font size="2">(07:04:59 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> wow, thanks =)<br>the problem is that just saying that would probably get me into trouble if someone asked about the license info, because the GPL may in some circumstances go against your licensing terms</font><br><font color="#204a87"><font size="2">(07:05:21 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> the license condition that concerns me is: The above items CAN NOT be modified and then sold as a library component, either individually or together.</font><br><font size="2"><font color="#cc0000">(07:06:07 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> this means that you can't sell it as own modified tree</font><br><font size="2"><font color="#cc0000">(07:06:18 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> if it's the part of larger system then no problem</font><br><font color="#204a87"><font size="2">(07:06:24 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> the GNU General Public License says that you are explicitly allowed to use the code commercially (i.e. charge for it) but you must ensure that any publicly distributed version is also available under the terms of the GPL, and that all recipients are allowed to freely distribute their copies</font><br><font color="#204a87"><font size="2">(07:07:14 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> it also means that someone can take my modified version, modify it further, and then charge for copies of it</font><br><font size="2"><font color="#cc0000">(07:07:17 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> can't be sold deal is just to prevent from creating the competing free or commercial product based on our script</font><br><font color="#204a87"><font size="2">(07:07:49 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> ahh, i see, so that means that i may treat the code as if it were GPL?</font><br><font size="2"><font color="#cc0000">(07:07:55 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> I understand that your product is not competing with the javascript tree</font><br><font color="#204a87"><font size="2">(07:08:28 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> ok, thank you very much for your help, i will update the license block in that file accordingly</font><br><font color="#204a87"><font size="2">(07:14:34 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> just as a side note, you may want to mention that if the free products are used as a part of a larger project that they can be under Free Software licenses, to save yourself from undue annoyances from guys like me ;-)</font><br><font size="2"><font color="#cc0000">(07:15:14 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> luckily very few give a damn about the legal writing ;)</font><br><font color="#204a87"><font size="2">(07:17:45 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> haha<br>is it ok with you if i include an HTML copy of this conversation in the licenses folder in the Enano distribution, as proof of the license conditions?</font><br><font size="2"><font color="#cc0000">(07:18:13 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> ;) that's pretty loose language</font><br><font color="#204a87"><font size="2">(07:18:51 PM) </font><b><font size="3">Dan:</font></b></font><font size="3"></font><font size="3"> well if Enano ever gets in some sort of legal issue, the first thing my lawyer will ask me is, did you document all license info on third party code</font><br><font size="2"><font color="#cc0000">(07:19:31 PM) </font></font><font color="#cc0000"><b><font size="3">817108:</font></b></font><font size="3"></font><font size="3"> ok, then as long a lawyers don't get too much work</font>
+</body>
+</html>
--- a/plugins/SpecialAdmin.php	Fri Jun 22 18:42:26 2007 -0400
+++ b/plugins/SpecialAdmin.php	Sat Jun 23 09:55:58 2007 -0400
@@ -116,7 +116,7 @@
     echo '<tr><td class="'.$cls.'">';
     switch($r['action']) {
       case "admin_auth_good": echo 'Successful elevated authentication'; if ( !empty($r['page_text']) ) { $level = $session->userlevel_to_string( intval($r['page_text']) ); echo "<br /><small>Authentication level: $level</small>"; } break;
-      case "admin_auth_bad":  echo 'Failed administration logon'; break;
+      case "admin_auth_bad":  echo 'Failed elevated authentication'; if ( !empty($r['page_text']) ) { $level = $session->userlevel_to_string( intval($r['page_text']) ); echo "<br /><small>Attempted auth level: $level</small>"; } break;
       case "activ_good": echo 'Successful account activation'; break;
       case "auth_good": echo 'Successful regular user logon'; break;
       case "activ_bad": echo 'Failed account activation'; break;