<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ursecta.com &#187; Security</title>
	<atom:link href="http://ursecta.com/wp/category/security/feed/" rel="self" type="application/rss+xml" />
	<link>http://ursecta.com/wp</link>
	<description>J. Martin Wehlou on Security, Software Development, and Medicine</description>
	<lastBuildDate>Tue, 08 May 2012 10:19:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>An ode to Juniper</title>
		<link>http://ursecta.com/wp/2010/10/an-ode-to-juniper/</link>
		<comments>http://ursecta.com/wp/2010/10/an-ode-to-juniper/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 14:26:05 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=1059</guid>
		<description><![CDATA[I have a Juniper SSG-5 and the school I&#8217;m doing the network setup for also got one identical unit on my recommendation. I wanted to set up a fixed VPN between the two but failed miserably, so I logged a support request with Juniper on my machine, which is still in warranty but without any [...]]]></description>
			<content:encoded><![CDATA[<p>I have a Juniper SSG-5 and the school I&#8217;m doing the network setup for also got one identical unit on my recommendation. I wanted to set up a fixed VPN between the two but failed miserably, so I logged a support request with Juniper on my machine, which is still in warranty but without any kind of support contract. Oh, boy, do these guys have great service.</p>
<p>After just a day I got an engineer connecting to my system with desktop sharing software and we together went through a number of different configurations. It wasn&#8217;t really trivial, since the first config took us nearly three hours. Then I had another question of how to implement more finegrained control over the firewall policies in one direction, but not the other, which had us online another two hours using desktop sharing. The final result was perfect and I&#8217;ve learned so much more about the details of autokey VPN tunnels.</p>
<p>I&#8217;m totally blown away by the level and quality of support I got for this issue from Juniper. Maybe this particular engineer was exceptionally good and persistent, but I have the impression that it is more of a rule with Juniper. When I bought the SSG-5 I thought it was a little expensive, but after this experience, I&#8217;ve totally changed my mind. The support level and quality makes it worth the price hands down.</p>
<p>No, I don&#8217;t have shares in Juniper, but after this experience I think I may get some.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2010/10/an-ode-to-juniper/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>EHR systems are liars</title>
		<link>http://ursecta.com/wp/2010/07/ehr-systems-are-liars/</link>
		<comments>http://ursecta.com/wp/2010/07/ehr-systems-are-liars/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 10:41:49 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Medical Applications]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=1019</guid>
		<description><![CDATA[I&#8217;m just copying a post here I just did to a closed forum for CISSPs. A couple of days ago, I had to create a death certificate in Cosmic, the EHR system produced by Cambio Healthcare Systems and used in many provinces of Sweden and increasingly abroad. So, I opened up the records for the [...]]]></description>
			<content:encoded><![CDATA[<p><em>I&#8217;m just copying a post here I just did to a closed forum for CISSPs. </em></p>
<p>A couple of days ago, I had to create a death certificate in Cosmic, the EHR system produced by Cambio Healthcare Systems and used in many provinces of Sweden and increasingly abroad.</p>
<p>So, I opened up the records for the patient, created a new death certificate form and filled it in. Printed it out, since it needs to go the paper route to the IRS (in Sweden, they handle the population registry). Then, just to make sure my data matched the EHR entry I made a few days before, I opened up the form again and discovered four different entry fields had changed after I saved. Two adress fields were blanked, my &#8220;place of employment&#8221; was changed to &#8220;Summer house&#8221; (part of another field I had filled in) and finally, my telephone number I had added was blanked out. I corrected the fields and resaved, same thing happened again. Did it three times, same thing. I never signed the document, of course, instead having a secretary scan in my paper form, which was correct, and have that put in the EHR. The erroneous form remains there, but unsigned.</p>
<p>I pointed out this severe bug to the IT department, and the reply I just got went into some depth explaining to me what the different fields were supposed to contain, but they didn&#8217;t touch at all on the hairraising fact of changing the documents behind my back. That&#8217;s apparantly entirely ok for them.</p>
<p>In this scenario, I never signed, but if I had done that, nothing would have played out differently. The scary thing is that the normal workflow is to fill in a form, any form, print it out (optionally), then sign it, which flags it as signed and saves it in one operation. You never see what actually gets saved with your &#8220;signature&#8221; on it. We&#8217;ve had a number of bugs before, where dates were changed in sick leave forms, a number of crucial fields erased and so on, so this is just the last in a long series of such bugs.</p>
<p>This system, the largest on the Scandinavian market, uses Acrobat Reader (yes, you read that right, *Reader*) to fill in forms. So they prepare the form data in the background, launch the Reader, lock it down modally since they can&#8217;t handle the interactions right, then let you edit and save. The &#8220;save&#8221; and &#8220;signature&#8221;, even &#8220;delete&#8221; buttons are implemented *inside* the document form since they run modally. Just to give you an idea of the &#8220;leading edge technology&#8221; we&#8217;re talking about here.</p>
<p>The forms as such are designed by the end-user organisation, so the problem is in two parts: Cambio enables a sloppy workflow and does not respect the immutability of signed data in their application. The end-user organisation does not test new forms for problems.</p>
<p>So, my issues with all this are:</p>
<p>1. This product has passed CE approval. So where is the systems test? These problems are trivial to find before rollout. Not to mention that I, and others, have pointed these form problems out in public since at least two years. What&#8217;s the point of the CE, anyway? </p>
<p>2. If Cosmic is able to change the content of forms behind my back, why isn&#8217;t this recorded in a log? There is no way I can show after the fact that the form contains stuff I never wrote, even if I would be able to remember what I wrote and this has caused much consternation before with the sick leave forms. Why isn&#8217;t audit trailing of this a requirement from the user organisation or from the CE protocol?</p>
<p>3. Why does the system not warn me or show me the changed information during or after signature? It bloody well warns me for everything else I don&#8217;t need warnings for. A typical Windows app, if you get my drift.</p>
<p>4. Why doesn&#8217;t the &#8220;signature&#8221; mean anything? It&#8217;s simply a flag set in the system with no functional binding to the information. They&#8217;re in the process of rolling out smart cards now; I have one. You stick them into a slot on the keyboard to sign in, at least that&#8217;s the idea (doesn&#8217;t work, they don&#8217;t have the trusted root installed&#8230;). But that&#8217;s for Windows login. The &#8220;signature&#8221; in the EHR remains a dumb flag AFAIK.</p>
<p>Meanwhile, the law and regulations governing medical practice make a huge deal out of these signatures. We *have* to sign stuff in a timely fashion and can be sanctioned if we don&#8217;t. And if we do sign, we&#8217;re held to what we sign, legally, morally, ethically. Our careers can be held hostage by a stupid flag in a stupid database record, designed by an irresponsible designer, and implemented by an agile and equally uninformed coder.</p>
<p>My question is this: is this shitty state of affairs, this total ignorance of what the law and regulations say, this total lack of interest in quality and consistency in application design and implementation, something common to EHR systems everywhere? Is this laissez-faire attitude something you actively try to combat as security professionals if you work in the medical field, and if not, why not?</p>
<p>Or, provocatively, I&#8217;ve repeatedly heard on this list (it&#8217;s a while since last time) that doctors don&#8217;t respect security in EHR systems, but now my question is this: does anyone else? It seems not.</p>
<p>And finally, WTF is the point of the CE approval&#8230;? I&#8217;ve seen all the cynical answers, now I want a real answer somehow.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2010/07/ehr-systems-are-liars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSX, FreeRadius, Netscreen, and me</title>
		<link>http://ursecta.com/wp/2010/05/osx-freeradius-netscreen-and-me/</link>
		<comments>http://ursecta.com/wp/2010/05/osx-freeradius-netscreen-and-me/#comments</comments>
		<pubDate>Sat, 29 May 2010 14:19:04 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Networks]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Juniper]]></category>
		<category><![CDATA[Netscreen]]></category>
		<category><![CDATA[Radius]]></category>
		<category><![CDATA[Snow Leopard Server]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=782</guid>
		<description><![CDATA[Oh, wow, this was crazy. What I needed to get done is to have a Juniper SSG-5 firewall (which runs Netscreen OS 6.2) authenticate users from the FreeRadius server that runs by default in OSX Snow Leopard server (10.6.3). And I needed the SSG-5 to differentiate depending on groups on Open Directory on the OSX. [...]]]></description>
			<content:encoded><![CDATA[<p>Oh, wow, this was crazy. What I needed to get done is to have a Juniper SSG-5 firewall (which runs Netscreen OS 6.2) authenticate users from the FreeRadius server that runs by default in OSX Snow Leopard server (10.6.3). And I needed the SSG-5 to differentiate depending on groups on Open Directory on the OSX. But, man, is this poorly documented&#8230; the only thing you find in the OSX documentation is how to get an accesspoint to allow users in. That&#8217;s it. Not good enough.</p>
<p><em>You can click any of the images in this post to see the screenshots full size</em></p>
<p>First, a list of documents you may need, or I may need later and don&#8217;t want to lose:</p>
<p><a href="http://ursecta.com/wp/go.php?http://www.opensource.apple.com/source/freeradius/freeradius-11/freeradius/share/dictionary.freeradius.internal" target="_blank" title="(131 hits)">dictionary.freeradius.internal</a> &#8211; an Apple document listing the attributes passed to FreeRadius.</p>
<p><a href="http://ursecta.com/wp/go.php?http://old.nabble.com/Freeradius-Netscreen-help-td16769356.html" target="_blank" title="(165 hits)">A usegroup message with some useful examples</a></p>
<p><a href="http://ursecta.com/wp/go.php?http://blog.irisproservices.com/2009/12/18/using-mac-os-x-servers-radius-service-with-third-party-devices/" target="_blank" title="(140 hits)">Using OSX Radius with third party devices</a> &#8211; has some info on hunt groups</p>
<h2>Make sure radius is running</h2>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz004.png" title="(135 hits)"><img class="aligncenter size-medium wp-image-793" title="Server AdminScreenSnapz004" src="http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz004-300x241.png" alt="" width="300" height="241" /></a></p>
<p>Via Server Admin, make sure Radius is selected in the services tab so it occurs in your list of services in the left pane.</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz005.png" title="(92 hits)"><img class="aligncenter size-medium wp-image-798" title="Server AdminScreenSnapz005" src="http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz005-300x241.png" alt="" width="300" height="241" /></a></p>
<p>Then select &#8220;Radius&#8221; in the left panel, select &#8220;Settings&#8221; and click the dropdown for &#8220;RADIUS Certificate&#8221;. There you should either select a cert you already have installed on the server, or else select &#8220;Manage Certificates&#8230;&#8221; to go and create one. I already had one, and I had it created by <a href="http://ursecta.com/wp/go.php?https://www.cacert.org" title="(106 hits)">CAcert</a>, a free service for certificates of all kinds.</p>
<p>When you&#8217;ve got the cert sorted out, click the button &#8220;Edit Allowed Users&#8230;&#8221; and you&#8217;ll get to this screen:</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz001.png" title="(96 hits)"><img class="aligncenter size-medium wp-image-801" title="Server AdminScreenSnapz001" src="http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz001-300x241.png" alt="" width="300" height="241" /></a></p>
<p>See to it that you&#8217;ve selected &#8220;For selected services below:&#8221; in the left half of the right pane and that &#8220;RADIUS&#8221; is selected in the list. Then use the plus sign below right to add all groups you want to manage through Radius. Don&#8217;t forget to click the &#8220;Save&#8221; button when you&#8217;re done.</p>
<p>If you have any regular wireless access points you want to add, you can do that through the Server Admin as well, but you can&#8217;t add any other devices this way.</p>
<p>Just to see if things are more or less right, try to start the Radius server and then check the logs. You can do that by selecting RADIUS in the left panel, click the &#8220;Logs&#8221; tab on top and then play with the &#8220;Start RADIUS&#8221; and &#8220;Stop RADIUS&#8221; button at the bottom of the screen:</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz0061.png" title="(101 hits)"><img class="aligncenter size-medium wp-image-845" title="Server AdminScreenSnapz006" src="http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz0061-300x241.png" alt="" width="300" height="241" /></a></p>
<p>If it complains about the lack of any clients, don&#8217;t bother. Just leave it off, since we&#8217;ll add clients through the command line shortly.</p>
<p>Once you&#8217;ve played with this for a while and are satisfied that it is not too bad, you can leave the Radius server off. We&#8217;ll start it from the command line later.</p>
<blockquote><p>It&#8217;s important to understand that all the groups you select here, and only those groups, are copied over to the user database in the Radius server. Any users that are not in one of these groups cannot ever be enabled through Radius; they&#8217;re simply not seen by the Radius server.</p></blockquote>
<blockquote><p>Also important to understand is the fact that this is as far as Apple goes in its GUI implementation of Radius. That is, any user that is enabled for Radius this way can log in to any Radius enabled wireless access points on your net. They don&#8217;t make any distinction according to user or group as to what you can do, nor do they implement anything else but wireless access points. This means that for more sophisticated usage, you have to proceed on your own, largely through the command line and config files.</p></blockquote>
<h2>Add clients to radius</h2>
<p>A &#8220;client&#8221; is a piece of equipment that will ask the radius server to authenticate users, so clients are accesspoints, firewalls, maybe switches and routers. Each of these pieces of equipment that you want to have call the radius server needs to be configured in the server with its IP number and a shared secret (password). This shared secred is the same on both sides, so each piece has its secret shared with the radius server, but each pairing has another shared secret. If you want to add just Apple supported wireless access points, you can do that through Server Admin, but for everything else you have to do it as follows.</p>
<p>To add a client to the radius server, you use the radiusconfig utility on the OSX server:</p>
<pre>sudo radiusconfig -addclient 172.16.200.241 ssg5 firewall</pre>
<p>After you enter this command, radiusconfig will ask you for the shared secret. Remember it, because this is the same secret we will need to enter in the SSG-5 later.<em> A side note: the last parameter is the type and I gave it as &#8220;firewall&#8221;. As far as I can see, it&#8217;s purely descriptive and you can call it &#8220;bigbrownbear&#8221; for all the difference it makes.</em></p>
<p>If you check the list of &#8220;Base Stations&#8221; in Server Admin, you&#8217;ll should see this client in the list, at least if Radius is running:</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz003.png" title="(107 hits)"><img class="aligncenter size-medium wp-image-811" title="Server AdminScreenSnapz003" src="http://ursecta.com/wp/wp-content/uploads/2010/05/Server-AdminScreenSnapz003-300x241.png" alt="" width="300" height="241" /></a></p>
<h2>Add the DEFAULT entries to the users file</h2>
<p>Even though Radius users are held in an sql-lite database under OSX, the users file still does exist and is read. In this file, we can add in rules that will be processed for any user that is accepted by Radius, so we can add on values to be returned to the Radius client (in our case, the firewall). In the users file, you also have access to some information from Open Directory on OSX, so the users file is the place where information is transformed from OSX Open Directory to Radius clients. This is where the magic happens. We write all our rules for the magic user &#8220;DEFAULT&#8221;, which matches any user accepted by Radius. More than one rule may match a real user, and all of the matching rules will be applied.</p>
<p>Open the &#8220;/etc/raddb/users&#8221; file on the server with pico as root:</p>
<pre>sudo pico /etc/raddb/users</pre>
<p>In that file, towards the end, in among the other &#8220;DEFAULT&#8221; rules, add this one:</p>
<pre>DEFAULT   Group-Name == "Parents"
     NS-User-Group = "majors"</pre>
<p>What this rule does is that it checks if the user under OSX in open directory belongs to a group called &#8220;Parents&#8221; and if so it sends the NS-User-Group attribute with the value &#8220;majors&#8221; to the client, in this case our firewall. We&#8217;ll add another rule:</p>
<pre>DEFAULT   Group-Name == "Children"
     NS-User-Group = "kids"</pre>
<p><em>Note: I made the group names very different on the OSX Open Directory side (&#8220;Parents&#8221; and &#8220;Children&#8221;) and on the Radius client side (&#8220;majors&#8221; and &#8220;kids&#8221;) just to make it extra clear which group is which.</em></p>
<h2>Set up authentication server on the SSG-5</h2>
<p>Now we have to tell the SSG-5 how to find and talk to the Radius server. Log in on the SSG-5, go to &#8220;Configuration&#8221; &#8211; &#8220;Auth&#8221; &#8211; &#8220;Auth Servers&#8221; and click &#8220;New&#8221;.</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz001.png" title="(154 hits)"><img class="aligncenter size-medium wp-image-816" title="FirefoxScreenSnapz001" src="http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz001-300x197.png" alt="" width="300" height="197" /></a></p>
<p>Give the OSX Server a name, any name. It&#8217;s used to refer to this server when you create policies in the SSG-5 later. Enter the IP number, and select the &#8220;Auth&#8221; under &#8220;Account type&#8221;.</p>
<p>In the lower part, select &#8220;Radius&#8221; radio button, set the &#8220;RADIUS Port&#8221; to 1812, which is the default on the OSX FreeRadius server. Set the &#8220;RADIUS Accounting Port&#8221; to 1813, even though we don&#8217;t use accounting in this example. In the field &#8220;Shared Secret&#8221; you have to enter the same shared secret you entered while defining the SSG-5 client on the OSX Server using radiusconfig (see above). Leave the other fields unchanged and click &#8220;Save&#8221; at the bottom of the screen.</p>
<h2>Add external groups to the SSG-5</h2>
<p>We configured the OSX FreeRadius, via the DEFAULTS in the users file, to return groups &#8220;majors&#8221; and &#8220;kids&#8221; depending on who is logging on. Now we have to set up these groups on the SSG-5 as well. Go to &#8220;Objects&#8221; &#8211; &#8220;Users&#8221; &#8211; &#8220;External Groups&#8221; and click &#8220;New&#8221;.</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz002.png" title="(101 hits)"><img class="aligncenter size-medium wp-image-819" title="FirefoxScreenSnapz002" src="http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz002-300x264.png" alt="" width="300" height="264" /></a></p>
<p>In &#8220;Group Name&#8221;, write &#8220;majors&#8221;, then select the &#8220;Auth&#8221; checkbox for &#8220;Group Type&#8221;. Click the Ok button, then repeat the process for the &#8220;kids&#8221; group.</p>
<h2>Now we do a policy</h2>
<p>Now we finally arrive at the writing of policies that make use of the groups. In this example, I&#8217;m going to limit access to the dn.se site, Sweden&#8217;s largest newspaper, and I&#8217;ll only make it accessible to OSX users that belong to the &#8220;Parents&#8221; group on OSX. To do this, I&#8217;ll first have to make a policy that by default disallows everyone from accessing dn.se, then add a policy that allow members of the external group &#8220;majors&#8221; to access it anyway (remember that the OSX group &#8220;Parents&#8221; is translated to the group &#8220;majors&#8221; in the users file, so the external group is &#8220;majors&#8221; on the SSG-5). Let&#8217;s first do the policy that disallows all access to dn.se for everyone.</p>
<p>Go to &#8220;Policy&#8221; &#8211; &#8220;Policies&#8221;.</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz005.png" title="(90 hits)"><img class="aligncenter size-medium wp-image-822" title="FirefoxScreenSnapz005" src="http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz005-300x138.png" alt="" width="300" height="138" /></a></p>
<p>Select from &#8220;Trust&#8221; in upper left, to &#8220;Untrust&#8221; in upper right dropbox, then click &#8220;New&#8221;.</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz003.png" title="(97 hits)"><img class="aligncenter size-medium wp-image-826" title="FirefoxScreenSnapz003" src="http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz003-300x162.png" alt="" width="300" height="162" /></a></p>
<p>Use dig or nslookup from the command line to find the IP number for dn.se. As of the writing of this post, it was a single IP number: 62.119.189.4.</p>
<p>When the form opens, give the policy a reasonable name like &#8220;No DN&#8221;, leave the source address set to &#8220;Any&#8221;, but change the destination address to &#8220;62.119.189.4&#8243; and put in &#8220;32&#8243; in the mask field. The &#8220;Action&#8221; dropdown should be set to &#8220;Reject&#8221; and you can leave everything else as it was and click &#8220;Ok&#8221;.</p>
<p>Use the move tools in the policy list (far right) to move this policy to the top of the list. The policies are processed from top to bottom, so we want to make sure the rejection happens before any other policy may allow the connection.</p>
<p>Add another policy from &#8220;Trust&#8221; to &#8220;Untrust&#8221;, then fill it in as in the following screen:</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz006.png" title="(95 hits)"><img class="aligncenter size-medium wp-image-830" title="FirefoxScreenSnapz006" src="http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz006-300x240.png" alt="" width="300" height="240" /></a></p>
<p>Give it another name, in this case &#8220;Allow DN&#8221;. You can now select the destination address from the address book entry dropbox so you don&#8217;t have to type it in, it&#8217;s just a convenience since the SSG-5 now knows about this IP from the previous policy. The &#8220;Action&#8221; dropbox should now be set to &#8220;Permit&#8221;.</p>
<p>If this was all we did, we just simply nullified the previous policy, at least if we put this one above it in the policy list, and that would be pointless. Instead, click on the &#8220;Advanced&#8221; button at the bottom of the screen.</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz008.png" title="(110 hits)"><img class="aligncenter size-medium wp-image-831" title="FirefoxScreenSnapz008" src="http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz008-300x213.png" alt="" width="300" height="213" /></a></p>
<p>Now everything comes together. Enable &#8220;Authentication&#8221; by selecting that checkbox, then select &#8220;Auth Server&#8221; using the radio buttons. In the dropbox, select the auth server you created earlier, the MiniSL. Slightly to the right, you can select who is going to be authenticated and here you select &#8220;User Group&#8221;, then &#8220;External &#8211; majors&#8221;. If this selection isn&#8217;t available, check that you did define that external group as I described a bit earlier.</p>
<p>With all this done, save. In the list of policies, you should put this new policy at the top using the move tools in the last column so it ends up above the first policy we did that is set to reject connections to dn.se for everyone. The result should look like this:</p>
<p><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz009.png" title="(104 hits)"><img class="aligncenter size-medium wp-image-832" title="FirefoxScreenSnapz009" src="http://ursecta.com/wp/wp-content/uploads/2010/05/FirefoxScreenSnapz009-300x111.png" alt="" width="300" height="111" /></a></p>
<h2>Testing it all</h2>
<p>If you started the Radius server through Server Admin, go there and stop it first. Log in to the OSX server and open a terminal shell. Start the Radius server in debug mode from here by:</p>
<pre>sudo radiusd -X</pre>
<p>This should get your Radius server running and you&#8217;ll see how it handles requests. Now go to a browser on any other machine on the local net and try to open dn.se. You should get a login dialog from the browser itself and if you provide a username and password from someone who is defined in the OSX Workgroup manager, is in the &#8220;Parents&#8221; group, then you should get access, else not.</p>
<p>I hope it works for you. If not, explore the raclient tool as well, since it&#8217;s very useful for finding configuration errors. Once it all works, stop the Radius server on the command line and go start it from Server Admin instead, so it runs as it normally would.</p>
<p>A little remark: if you change settings in the users file, you have to stop and start the Radius server again each time, else it won&#8217;t see the changes.</p>
<p>I&#8217;m planning to do a post on hunt groups as well, but I haven&#8217;t done them yet, so it could be a while.</p>
<h2>Additional notes</h2>
<p>You will find files with all the predefined attributes in the folder /usr/share/freeradius. Each type of equipment has its own file. The attribute names I used above come from the file &#8220;dictionary.netscreen&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2010/05/osx-freeradius-netscreen-and-me/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Design for updates</title>
		<link>http://ursecta.com/wp/2010/04/design-for-updates/</link>
		<comments>http://ursecta.com/wp/2010/04/design-for-updates/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 09:00:24 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[iota]]></category>
		<category><![CDATA[Medical Applications]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=597</guid>
		<description><![CDATA[When designing new system architectures, you really must design for updating unless the system is totally trivial. This isn&#8217;t hard to do if you only do it systematically and from the ground up. You can tack it on afterwards, but it&#8217;s more work than it needs to be, but it&#8217;s still worth it. I&#8217;ll describe [...]]]></description>
			<content:encoded><![CDATA[<p>When designing new system architectures, you really must design for updating unless the system is totally trivial. This isn&#8217;t hard to do if you only do it systematically and from the ground up. You can tack it on afterwards, but it&#8217;s more work than it needs to be, but it&#8217;s still worth it.</p>
<p>I&#8217;ll describe how it&#8217;s done for a system based on a relational database. It does not matter what is above the database, even if it&#8217;s an object-relational layer, the method is still applicable.</p>
<p style="padding-left: 30px;"><em>I have a strong feeling that the problem is  trivial on graph databases, since the nodes and relations themselves  allow versions by their very nature. I haven&#8217;t designed using these graph databases yet, so I&#8217;m not 100% sure, though.</em></p>
<p>The reason I&#8217;m going into this now is that the iotaMed system must be designed with upgrades in mind, avoiding downtime and big bang upgrades. Just this weekend, the Cambio Cosmic system in our province (Uppsala, Sweden) is undergoing yet another traumatic upgrade involving taking the entire system offline for a couple of days. Very often it doesn&#8217;t come up on time or without serious problems after these upgrades, putting patients at risk entirely unnecessarily. The only reason these things need to happen is because of poor system design. A little forethought when building the system could have made a world of difference. The PMI communication system I built and which is used in Sweden has never (as far as I know) been taken down for upgrades, even though upgrading of both client and server systems is an easy and regular activity, and Cosmic could relatively easily have been build the same way. But it wasn&#8217;t, obviously. It&#8217;s not rocket science, exactly, just see for yourself in what follows.</p>
<h3>The problem</h3>
<p>The first step is to understand why the database structure is so tightly bound to the code layers, necessitating a simultaneous upgrade of the database structure and the code that accesses it. In the common and naive form, the data access layer is made up of application code outside the database itself which directly accesses tables for reads and writes. If there are several data access layer modules, all of them contain direct knowledge of table structures and all of them need to update simultaneously with the table structures. This means that if you change table structures you need to do all the following in one fell swoop, while all users are taken offline:</p>
<ol>
<li>Change table structures</li>
<li>Run through all data and convert it with scripts</li>
<li>Replace all application code that directly accesses table data</li>
<li>And while you&#8217;re at it, compound the disaster by also replacing business layer code and user interface code to use new functionality added in the data access layer and database while removing old application code that won&#8217;t work anymore with the new data structures</li>
</ol>
<p>This is what we call a &#8220;big bang&#8221; upgrade and it practically always goes wrong (that&#8217;s the &#8220;bang&#8221; part). It&#8217;s extremely hard to avoid disasters, since you have to do very detailed testing on secondary systems and you&#8217;ll never achieve full coverage of all the code or even all the little deviant data in the production database that will inevitably screw up the upgrade. And once you&#8217;re in the middle of the upgrade, you can&#8217;t back out, unless you have full downgrade scripts ready, that have been fully tested as well. The upgrade scripts, hard as they are to get right, are actually simpler than the emergency downgrade scripts, since the latter must take into consideration that the downgrade may be started from any point in the upgrade.</p>
<p>The result is that these upgrades are usually done without any emergency downgrade scripts. It&#8217;s like the high wire without a safety net. The only recourse is a total restore from backups, taking enormous amounts of time and leaving you shamefaced and nervous back at the spot you started after a long traumatic weekend. Since backing down is a public defeat, you&#8217;re under emotional pressure to press ahead at almost any cost, even in the face of evidence that things will probably go badly wrong, as long as there&#8217;s a chance of muddling through. Your ego is on the line.</p>
<p>This is no way to upgrade critical medical systems, but this is how they do it. <em>Shudder</em>.</p>
<h3>The solution</h3>
<p>The solution is to isolate the database structures from the application code. If different data access layers in application code can coexist, using each their own view of how the database is structured, while still accessing the same actual data within transactions, you can let two versions of application code stacks coexist while accessing the same data. If you can swing this, you&#8217;re free to change the database table structure without the application code in the data access layer even noticing. This implies that you can simply add a new view on the database that you need for a new version of the application, add in the new application code and start running it <em>without</em> removing the old application code or clients. New version clients, business layers, and data access layers run in parallel to old versions, so you can let the upgrade be slowly distributed out over the user population, allowing you to reverse the rollout at any point in time. Let it take weeks, if you wish. Or even leave some old clients there forever, if there&#8217;s a need for that.</p>
<p>To achieve the needed insulation, simply disallow any direct access to any tables whatsoever from application code. All accesses must be done through stored procedures or views.</p>
<p style="padding-left: 30px;"><em>SQL VIEWs where actually designed to achieve exactly this: different views on the table data, removing direct dependency of the application code on the tables, so the problem was clearly defined, known, and solved even before SQL hit the scene, so why are we even arguing this now? As an aside, I never use VIEWs, only stored procedures, since I can achieve the same effect with less constraints, but that does not detract anything from the argument that the problem was both recognized and solved ages ago.</em></p>
<p>Let&#8217;s assume you need to change the name of a table for some reason. (I never do that, I&#8217;m just taking a really radical example that ought to make your hair stand on end.) First, you edit the stored procedures that access the table to check if the old table name still exists, and if not, start using the new table name. Then you create the new table. Then you create trigger code on the old table that updates the new table with any changes. Then you use the core of that trigger code to run as a batch to transfer all the old table contents that aren&#8217;t accessed to the new table. You check a couple of times during actual use if the tables keep matching in contents. You drop the old table (or rename it if you&#8217;re chicken, and drop it later). Finally, you remove the check for the old table name in the stored procedures that access the table. Yes, this is somewhat &#8220;exciting&#8221;, but I&#8217;ve done this a number of times on critical systems and it works. And if you can do this, you can do anything.</p>
<p>A much simpler scenario is if you add columns to a table for a new version of your app. If the new column can safely remain invisible to the old version, just add it on the fly, using the right default values so any constraints don&#8217;t fire. Add a <em>new</em> stored procedure that is used for the new version of the application, implementing the parameters and functionality the new version needs. The old stored procedure won&#8217;t even know the column is there. If the new column must be set some particular way depending on old values, add a trigger for that and batch update the new column using the core of that trigger in a batch command. Again, there is absolutely no need to take down the database or even kick out users while doing all this. Once the new stored procedure is there, you can roll out new applications and have them come on line one by one, leaving old versions running undisturbed.</p>
<p>You can dream up almost any change in table structure, including new tables, splitting one table into two, combining and splitting columns, creating or removing dependencies between columns and tables, and I can catch all of that using a fairly simple combination of stored procedures, triggers, and the occasional user function. And all of it can be done on a live production database with very low risk (caveat: if you know what you&#8217;re doing).</p>
<p>To keep things easy and clean, I always use a set of stored procedures per application, where the application prefix is a prefix in the naming of the stored procedure. That lets you see at a glance which app is using which stored procedure. I never let two different apps use the same procedure (you can always let both stored procedures call a common third procedure to reduce code duplication). Versions of a procedure are named with a numeric postfix so they can coexist. Versions are only created if they have different behaviours as seen from the application code. So a procedure to find a patient, used by an iotaPad app, could be named &#8220;IP_FindPatient_2&#8243; if it was the third version (the first is without postfix, the second version with _1, etc).</p>
<p>Finally, since you only use stored procedures from application code, no application need have any read or write access at all to your database, only execute access to all the stored procedures with a prefix matching the app. This makes for a very easily verified set of GRANTs and a secure database.</p>
<p>Why this scheme isn&#8217;t used in products like Cambio Cosmic is a mystery to me. It can&#8217;t be laziness, since they&#8217;re working their butts off trying not to annihilate all the medical records we have, while stressing out both medical staff and their own programmers to the point of cardiac arrest everytime something goes wrong. A little forethought would have saved so much time and problems it&#8217;s almost unreal.</p>
<p>But on one point you can be certain: that little forethought is a definite requirement for the iotaMed project. It wouldn&#8217;t hurt if the other guys tried it as well, though.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2010/04/design-for-updates/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Welcome back, GPG Mail!</title>
		<link>http://ursecta.com/wp/2009/12/welcome-back-gpg-mail/</link>
		<comments>http://ursecta.com/wp/2009/12/welcome-back-gpg-mail/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 21:08:17 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=424</guid>
		<description><![CDATA[A friend just sent me this link to a blog entry that describes the return of GPG Mail to Snow Leopard 10.6.2: http://carlton.oriley.net/blog/?p=20 The link to the download is: http://carlton.oriley.net/blog/wp-content/uploads/2009/12/GPGMail-1.2.1.mailbundle.zip And it works! Go get it.]]></description>
			<content:encoded><![CDATA[<p>A friend just sent me this link to a blog entry that describes the return of GPG Mail to Snow Leopard 10.6.2:</p>
<p>http://carlton.oriley.net/blog/?p=20</p>
<p>The link to the download is:</p>
<p>http://carlton.oriley.net/blog/wp-content/uploads/2009/12/GPGMail-1.2.1.mailbundle.zip</p>
<p>And it works! Go get it.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2009/12/welcome-back-gpg-mail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Useless email limitation</title>
		<link>http://ursecta.com/wp/2009/10/useless-email-limitation/</link>
		<comments>http://ursecta.com/wp/2009/10/useless-email-limitation/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 12:02:34 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=368</guid>
		<description><![CDATA[Something just happened here in old Sweden. A doctor sent an email with confidential patient info to a local government office, but fatfingered the adresses, so it ended up with 200 different people at that government office. Problem was, except for the numbers, that the patient he was divulging info about, actually works at that [...]]]></description>
			<content:encoded><![CDATA[<p>Something just happened here in old Sweden. <a href="http://ursecta.com/wp/go.php?http://itivarden.idg.se/2.2898/1.264120/hundratals-fick-mejl-med-kansliga-patientuppgifter" target="_blank" title="(169 hits)">A doctor sent an email with confidential patient info to a local government office, but fatfingered the adresses</a>, so it ended up with 200 different people at that government office. Problem was, except for the numbers, that the patient he was divulging info about, actually works at that office as well. Embarrassing, to put it mildly. Now they&#8217;re discussing what disciplinary measures to apply for fatfingering the destinations.</p>
<p>But the problem here isn&#8217;t that he fatfingered the adresses, the problem is that he used email at all. Except that seems to be established practice here. I don&#8217;t, btw. I stick to envelopes or encrypted fax.</p>
<p>I got an email account at the provincial healthcare system where I work, but I can&#8217;t get at that email account from the outside. I found that pretty dumb. After reading about this case, I changed my mind. Now I find it totally moronic. Allowing me to access it only from inside the provincial healthcare network gives me the impression that it is somehow a local and safe medium, which it is not. I&#8217;m perfectly able to send out <em>any</em> confidential information to absolutely anyone in the world, using this system, intentionally or otherwise. The only thing the access restriction actually prevents is&#8230; um&#8230; normal use?</p>
<p>To be fair, there is the hypothetical danger of someone hacking into my email account from the outside, to get at confidential information that someone else may have sent me and that I haven&#8217;t, for some reason, deleted, but compared to the danger of me actively sending out information by mistake to the wrong people, like a mailing list or a group adress, it&#8217;s negligible. No egress filtering is in place that I know of.</p>
<p>There is one useful solution to all this, namely a messaging feature in the electronic health care record system, since that automatically limits distribution to other authorized users of the system itself. But in our case, that function disappeared when they changed out our old system for a new and &#8220;improved&#8221; one.</p>
<p>In conclusion, I&#8217;ll claim that limiting outside access to the mail system like this is an illconsidered and useless move, more likely than not to be counterproductive.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2009/10/useless-email-limitation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DoS your kids</title>
		<link>http://ursecta.com/wp/2009/10/dos-your-kids/</link>
		<comments>http://ursecta.com/wp/2009/10/dos-your-kids/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 09:48:12 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=318</guid>
		<description><![CDATA[Saw this &#8220;How old will you get?&#8221; site, in Swedish, linked from a friend&#8217;s Facebook page (or an ad, can&#8217;t really make it out, but that&#8217;s the nature of FB, right?): Stupid site, don&#8217;t go there. But if you do go there, they ask you to register. So you don&#8217;t, but click &#8220;Starta testet&#8221; instead. [...]]]></description>
			<content:encoded><![CDATA[<p>Saw this &#8220;How old will you get?&#8221; site, in Swedish, linked from a friend&#8217;s Facebook page (or an ad, can&#8217;t really make it out, but that&#8217;s the nature of FB, right?):</p>
<p><a href="http://ursecta.com/wp/go.php?http://www.livsprognos.se/" target="_blank" title="(105 hits)"><img class="alignnone size-full wp-image-319" title="6002253120099_1_65be9044" src="http://ursecta.com/wp/wp-content/uploads/2009/10/6002253120099_1_65be9044.jpg" alt="6002253120099_1_65be9044" width="110" height="80" /></a></p>
<p>Stupid site, don&#8217;t go there. But if you do go there, they ask you to register. So you don&#8217;t, but click &#8220;Starta testet&#8221; instead. Then they ask you for your email address, so you invent a dummy address, of course. Then they ask you for your personal number (before you Americans freak out, it&#8217;s not as secret as a social security number, but still, I wouldn&#8217;t give it to them), so you invent one. You&#8217;ve got a one in ten chance of making it a valid number, since only one digit is used as a check digit.</p>
<p>Anyway, after three failed tries, you get this:</p>
<p><img class="alignnone size-medium wp-image-320" title="581" src="http://ursecta.com/wp/wp-content/uploads/2009/10/581-300x131.jpg" alt="581" width="300" height="131" /></p>
<p>Great! Love it. Which inspired me to think we could use this mechanism to stop other members of our little NAT tribe, since we&#8217;re all behind the same public IP, to get to that stupid site so our kids could give away email adresses and personal numbers to dubious people. Instead of blacklisting their domains in the router, let&#8217;s lock out our public IP by random login trials.</p>
<p>Not that I see what advantage the method has technically, but it&#8217;s just so cool turning their own tools against them.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2009/10/dos-your-kids/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET considered harmful</title>
		<link>http://ursecta.com/wp/2009/09/net-considered-harmful/</link>
		<comments>http://ursecta.com/wp/2009/09/net-considered-harmful/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 11:24:50 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Dotnet]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=285</guid>
		<description><![CDATA[A friend of mine just told me about what an MS evangelist said at a symposium on multicore (paraphrased), after getting the question: &#8220;Did MS consider that cache awareness for programmers in multicore development?&#8221; &#8230;and he answered: &#8220;The average developer is not capable of handling that kind of level of detail. &#8230; Most developers are [...]]]></description>
			<content:encoded><![CDATA[<p>A friend of mine just told me about what an MS evangelist said at a symposium on multicore (paraphrased), after getting the question:</p>
<blockquote><p>&#8220;Did MS consider that cache awareness for programmers in multicore development?&#8221;</p></blockquote>
<p>&#8230;and he answered:</p>
<blockquote><p>&#8220;The average developer is not capable of handling that kind of level of detail. &#8230; Most developers are that ignorant. Welcome to the real world.&#8221;</p></blockquote>
<p>To me, this explains a lot. It explains why .NET looks like it does, and to clarify what I mean by that, let me simply copy in extracts from what I had to say about it in a private forum just weeks ago. In what follows, the italics are brief extracts of comments from others. The rest is my own text. It&#8217;s not always in a totally logical order and it starts out in midflight, but it&#8217;s a synthesis of a longish thread on a security related forum.</p>
<p><span id="more-285"></span></p>
<p><strong><em>Note: I didn&#8217;t ask any of my correspondents for permission to quote, but the quotes are so limited that I consider them &#8220;fair use&#8221;. If you think I crossed a line here, beat me into submission and I&#8217;ll never do it again.</em></strong></p>
<p>- &#8211; - here we go &#8211; - -</p>
<p><em>Even Java, Ada, and COBOL  do not inherently encourage &#8220;good programming style&#8221;.</em></p>
<p>Well, I wasn&#8217;t thinking of which language &#8220;encourages&#8221; good programming practices. IMNSHO, none really does. That&#8217;s an idea that isn&#8217;t even viable once you get into programming for real. The idea of &#8220;encouragement&#8221; from a language standpoint is, let me be blunt, something only wannabe programmers could think is relevant.</p>
<p>Once you really use a language and its platform, one is not bothered in the least about what the language or platform &#8220;encourages&#8221;, but what the language or platform *allows*, and that&#8217;s an entirely different kettle of fish. And this is where .NET falls down severely.</p>
<p>In .NET you can do reflection. Up to a point, and then not. You can do generics/templates. Up to a point, then it comes to a screeching halt. You can do aspects, but only to a very small point. You can do dynamic scripts, but only to a severely complicated and fairly worthless point. And on and on it goes. For every good abstraction technology they implement, you soon discover it&#8217;s just a faked out front that can&#8217;t scale up to something really useful.</p>
<p>So, like MS Basic before it, .NET languages and the platform have cheap selling points, leading you down a path of instant gratification and then you hit a wall. But it&#8217;s actually much worse than good ol&#8217; MS Basic was, since MS Basic was actually pretty close to what could be done back then, which wasn&#8217;t much. And you hit the wall soon enough to realize you should take another path. .NET, on the other hand, limits you from exploiting what currently very well can be done with computers, and it let&#8217;s you invest considerable energy and time in the platform before you get down to the bare metal behind it, only to discover it&#8217;s a rusty shell of improvised junk.</p>
<p>Let me put this in yet another way. Limiting languages to what is considered &#8220;safe&#8221; by non-programmers may limit the damage relative amateurs can do with these languages. But if this limitation also means you limit the *depth* of the language, like .NET does, then you actually put a ceiling on the level of abstraction than can be reached in larger systems built by people who actually know what they&#8217;re doing. Meaning that you exchange junk on a small and local scale for architectural and design junk on an epic scale.</p>
<p><em>With the reality of rapid time to market/deployment and a realistic assessment of the skills many programmers bring to the table, limited is what is needed quite often.</em></p>
<p>Yes, but what&#8230; um. Let me restart. It&#8217;s not a &#8220;yes, but&#8221; thing.</p>
<p>No, that&#8217;s wrong. Because it let&#8217;s you build small systems quicker and safer, that&#8217;s true, but small systems almost always become large systems. And these large systems almost always become monsters, due to the limitation that was built into them from the start. IOW, the limitation you talk about will practically always result in severe problems a bit down the road. It rewards shortsighted development.</p>
<p>Maybe, just maybe, limited and &#8220;safe&#8221; languages will reduce stupid errors in small systems by unskilled programmers more than they will cause deep errors in architecture of large systems (written by skilled or unskilled programmers, since skill doesn&#8217;t bring much to the table if the system won&#8217;t allow advanced techniques), but do we know that to be true? Has anyone tried to find out? As long as we don&#8217;t know that, you buy into &#8220;safe&#8221; languages on no better basis than what you do when you choose one shampoo over another.</p>
<p>- &#8211; -</p>
<p>Let me take a real life example to show what I mean, and why I currently detest .NET so much. (Maybe, just maybe, someone on the forum then tells me the one feature I missed in .NET and everyone gets to laugh at me, but I&#8217;m willing to risk that. I&#8217;m actually willing to *welcome* that, since it would be such a relief.)</p>
<p>When doing an app with grids and details, like 90% of everything out there, you want to let the user change details, add lines, delete lines, whatever, and then hit &#8220;Save&#8221; to save it all to the database, or &#8220;Revert&#8221; to go back to the original state. You also want the system to ask &#8220;Do you want to save first?&#8221; when you try to leave without saving changes. Right?</p>
<p>Ok, there are several ways of doing this. The &#8220;right&#8221; way would be to have the objects in memory versioned. You should be able to ask any object &#8220;did you change?&#8221; and &#8220;what did you change?&#8221;, and tell the object to roll back to a previous state or commit to the current state and start recording changes from there from now on.</p>
<p>You can&#8217;t do that in .NET, there&#8217;s no such feature. So, you say, what else is new, let&#8217;s fix that. With, um, AOP, which sounds just about right. Looking for solutions on the net shows nothing but spurious outbursts of unprintable language and gnashing of teeth. So forget it.</p>
<p>A mix-in, then? Um, no, .NET doesn&#8217;t support mix-ins, that&#8217;s only if you&#8217;ve got multiple inheritance.</p>
<p>Ah, let the objects deep-copy themselves to save state. Um, no, .NET has no reliable or complete deep-copy. And even if it had, it would copy too much of dependent object trees.</p>
<p>Then, let&#8217;s try good ol&#8217; raw bitblitting into memalloced save spaces and calculate our own offsets (and make the company CISSP, if there is one, turn blue in the face)? Um, no, such &#8220;unsafe techniques&#8221; aren&#8217;t allowed in .NET.</p>
<p>Let&#8217;s inject the dispatch table with a pre- and post-function to record changes (key/value observing or AOP, depending on taste)? Nope, can&#8217;t do. Unsafe.</p>
<p>Finally, if you still haven&#8217;t dumped the whole idea and started a bicycle shop instead, you may have worked your ass off to get a kind of reflection function lib going that can copy, compare, rollback your objects, if your objects conform to a fairly limited feature set and implement some clumsy attributes. That&#8217;s what I did, and I keep debugging this thing long past the time when it should have been clean. I&#8217;m also pretty sure it&#8217;s slow, but I don&#8217;t care anymore.</p>
<p>Or, you do what everyone else does, and that is riddling your code with checks if anything changed, and saving old values here and there when you think they may need to roll back. So if there are 15 ways of leaving that screen, you&#8217;ve got 15 different places you need to check if you need to reload or save any of maybe 20 different objects in your app. Leaving the support desk a never ending source of joy and happiness for years to come as customers find new and inventive ways of leaving half edited objects in memory.</p>
<p>You know what? If this had been C++, I would have done a real down to the metal hack of the dispatch vtable mechanism maybe, and gotten a fast solution working that could be used anywhere and forever to solve this problem. It would be &#8220;dangerous&#8221; but once debugged it would last forever.</p>
<p>What you see now in .NET is much less dangerous solutions, but they have to be done over and over again and everytime they risk new bugs, each of which is much harder to find than any bug I would have in my &#8220;unsafe&#8221; solution.</p>
<p>BTW, even my halfassed solution won&#8217;t work if you compile .NET apps in &#8220;secure&#8221; mode (or whatever it&#8217;s called) since reflection can&#8217;t be used then. (Meaning an even buggier solution with hundreds of times more code for the same thing&#8230;) And you know what, it&#8217;s actually *much more* difficult to get the 15 * 20 simple-code solution debugged than the one advanced vtable injection technique debugged.</p>
<p>So, that&#8217;s what &#8220;safe&#8221; languages deliver even for pedestrian apps. Hurrah.</p>
<p>- &#8211; -</p>
<p><em>Not sure I&#8217;d let most developers any where near C or C++.</em></p>
<p>Yes, but you also lose the opportunity to get really good scalable apps. I would suggest finding a few &#8220;real developers&#8221; instead of a load of &#8220;most developers&#8221;. Quantity can&#8217;t compensate lack of quality.</p>
<p><em>As for .Net, you could always mix managed and unmanaged code and do what you need to do in C++ if you&#8217;ve got the guys with the skills to do it right.</em></p>
<p>If that would let me attack the basic dispatch mechanism in .NET and have it install itself into all the objects in memory that I pointed out to it, with for instance attributes, I&#8217;d do it. But, AFAIK, you can&#8217;t do that. Then you need to switch over to C++ unmanaged for the entire project. Which, if we look back, was my exact argument. You *can&#8217;t* do scalable and safe programming in managed .NET even if you&#8217;re able to.</p>
<p>My argument is this: if you cripple a language, you&#8217;ve exchanged a few &#8220;dangerous&#8221; and qualified pieces of code against a sh..load of slightly dubious and simple pieces of code. And of the two ills, I am convinced the latter is the worst.</p>
<p>PS: I&#8217;m still waiting for someone to tell me I should&#8217;ve used disconnected datasets. Here I am, fully loaded for war and nobody shows up?</p>
<p>- &#8211; -</p>
<p><em>I&#8217;ve found it surprisingly practical on the scales I normally work with. I certainly concur that it&#8217;s not what you might call &#8220;large enterprise ready&#8221;, but then what really is?</em></p>
<p><em>BTW, couldn&#8217;t we define a &#8220;large system&#8221; as one in which none of the builders (are really able to) know what everything is doing?</em></p>
<p>I&#8217;ll take those two as the same question.</p>
<p>It *is* surprisingly practical for small scale stuff, or as the technical term goes: quick and dirty. But what is a &#8220;large system&#8221;? I&#8217;d say most useful systems are &#8220;large systems&#8221;, since the builder, even if he&#8217;s alone, can&#8217;t keep all parts of the system in his head all the time. I don&#8217;t think there are any, or more than very few, really &#8220;small&#8221; and useful systems out there, according to this definition.</p>
<p>A good programming system allows you to write &#8220;straight code&#8221;, or quick-and-dirty, as you start out and as soon as you see a pattern in your code, you are able to replace that pattern with a single implementation of an abstraction somewhere. All on the basis of DRY (Don&#8217;t Repeat Yourself). You *have* to be able to do this, else you get inheritance-by-editor, that is repeated and almost identical code in multiple places. Which is the most sure-fire way of making it a unmaintainable slag heap in no time.</p>
<p>For simple code sequences, we have functions. Even C# can do that. For structures we have objects. C# can, yay. For behaviours, we have templates aka generics. C# does that better than C++ in the &#8220;cute and nice to have&#8221; ways, but doesn&#8217;t do it at all in the &#8220;OMG-what&#8217;s-this- weird-code-but-it-saves-the-project&#8221; ways. It&#8217;s just cute and tantalizingly close to being real-world useful. Aspect oriented programming (AOP) or Key-value observing (KVO): C# is totally braindead. Same for run-time object extensions. Same for object delegation or runtime discovery of implementation (cfr respondsToSelector in Objective-C). None of these things are even there in any form. Even swapping out one DLL for another in runtime is painful in the extreme.</p>
<p>A highly abstract way to view this is to visualize a development effort curve that starts out linearly, then goes exponentially up. You stop there, grab the language by the neck and raise your code an abstraction level. You drop back to linear for a while, then you go exponential again, then you raise the code an abstraction level, etc.</p>
<p>With .NET, you can do this for a couple of times, then you either run out of abstraction levels or they don&#8217;t return you to a linear curve, but to another exponential curve (IOW, whatever you do, C# bites back). With C++ I&#8217;ve never run out of abstraction levels, they go on and on, right into user domain territory to an amazing degree. I suspect Objective-C won&#8217;t run out of them either. Languages like PHP don&#8217;t have them at all, they&#8217;re more or less at the level of MS Basic way back when. Almost. Which in itself is a kind of honesty, since PHP doesn&#8217;t even pretend to be a &#8220;real&#8221; language in that sense. It&#8217;s quick- and-dirty elevated to a religion.</p>
<p>Even though I can&#8217;t prove it, I strongly suspect that there are no simple projects really suitable for .NET. Almost all projects start out being the right scale, but almost all of them ultimately (or even &#8220;quickly&#8221;) escalate beyond the level where .NET is a good fit, but then they&#8217;re stuck on that platform. And it is in this phase of its lifecycle that we see the problems with unmaintainability and bugs, not while they&#8217;re still small.</p>
<p>So, in conclusion, I strongly doubt that &#8220;safe&#8221; programming systems bring us that safety. I think it&#8217;s the other way around. The problems we see due to poor use of sharp knives (horrible C++ code, for instance) can&#8217;t be solved by switching languages, but should be solved by switching or training programmers and fixing project management issues.</p>
<p>If you don&#8217;t have the project management and the developers you need to write solid, maintainable, and safe code with a real language, switching to &#8220;safe&#8221; languages won&#8217;t help you. I think that is what I&#8217;m trying to say.</p>
<p>- &#8211; -</p>
<p><em>A well-designed module will be maintainable. &#8220;Take the time to do the design before coding&#8221; beats the snot out of &#8220;pick the write language&#8221; when it comes to making the source readable and maintainable.</em></p>
<p>Uh, no. And yes. And no again.</p>
<p>The problem is that if you design your stuff first, the language has to be able to express that design. Unless you keep the design trivial enough to be expressed by any old (new) language.</p>
<p>For instance, if your design has the element &#8220;Restore this object tree to last savepoint&#8221; and your language has a feature that can be used to achieve that, you may get away with a handful of lines of code that clearly and succinctly express what you&#8217;re doing even without comments or docs, and that can be tacked onto your objects as mix-ins, categories, templates, reflection, or whatever.</p>
<p>If your language does not support the necessary operations and declarations, you&#8217;ll end up with stereotypical code that needs to be manually replicated into each and every darn class you&#8217;re building and that is specific for the very project you do them in, hindering reuse across projects. You end up with hundreds or thousands of lines of code spread all over, hard to understand, even harder to find when you need to find it and a real f&#8230;up to debug.</p>
<p>You can&#8217;t get around that if the language is too limited. Or &#8220;safe&#8221; as they call them nowadays.<br />
<em><br />
I have seen readable structured code in assembler and incomprehensible spaghetti in Modula-2</em></p>
<p>Assembler is much less limited than C# in this respect, so that isn&#8217;t so strange. It starts out at a very low abstraction level, but can reach very, very high. I&#8217;d say assembler is more or less linear in development complexity, but the problem is that the line, however straight, is very long.</p>
<p>Also, if you&#8217;ve already concluded that assembler can be well structured, then you have to admit C can as well. Same thing, almost. Extend at will to C++.</p>
<p><em>Of course it can!  Any language can!  That&#8217;s my point&#8230;.</em></p>
<p>Hah! OMG&#8230; so tell me, what&#8217;s wrong with MS Basic, then? Or MSDOS batch language?</p>
<p>Do an undo/redo manager for MS Basic, or even (let&#8217;s be generous here) C#, in an average accounting app. Then in Objective-C. Then compare for &#8220;well structured&#8221;. I&#8217;d guarantee you that the C# undo/redo manager will be unreadable, plastered all over the project up to the rafters, a neverending source of joyous bugs and a strongly contributing cause to the death of the product just a few years hence. Not so with Objective-C. (The undo/redo manager is already part of the libraries, but even if it wasn&#8217;t, it could be built by the developer in a very reasonable time. Not so for C#.)</p>
<p>And no amount of design will change that. C# simply doesn&#8217;t have the features you need and is brimming with the &#8220;safety&#8221; to stop you from getting it done. Thanks to the drive for &#8220;safer languages&#8221;, I have to add.</p>
<p><em>Isn&#8217;t the CISSP-relevant point here that your redo manager, or any comparable object, necessarily constitutes a locus of increased risk? Seems to me that might be why it&#8217;s hard to implement in such a language.</em></p>
<p>Yes, maybe, which points out why the CISSP-relevant point is nuts. Somebody decides that the undo/redo manager (or something equivalent) is dangerous, so let&#8217;s not do that. Um, so what do we do when we don&#8217;t have an undo/redo? We fake it in each of the 50 or 100 classes that need it and the problem is now orders of magnitude larger. Or, more likely, we prohibit undo/redo entirely, making the use of the app a bloody nightmare, causing the actual business to suffer. And if the bloody user makes an error, he can&#8217;t correct it, but then it&#8217;s his fault, right?</p>
<p>In any case, this method of suppressing any patterns that carry risk only moves the problem elsewhere, usually making it much worse at the same time.</p>
<p><em>Pretty much all languages these days do the real work with library calls. The accretion of platforms slowly renders specific languages less relevant, as implementations increasingly consist of calls to external libraries and objects held outside the language&#8217;s environment. So-called &#8220;safe&#8221; languages attempt to fulfill their promise by limiting external calls or, in the .Net case, opening holes to &#8220;unmanaged code&#8221;.</em></p>
<p>I intentionally took an example of something that can&#8217;t be done by libraries. You can&#8217;t equip classes or objects with runtime state monitoring by library calls if there is no dynamic injection or intercept functionality in the language. There is no equivalence between language functionality and library functionality; those cover disparate areas of functionality. Libraries have in absolutely no way taken over from languages, but libraries have grown much faster than languages, so it may seem so if you just compare sizes.</p>
<p><em>This is the dichotomy of Java: it lives in a sandbox that makes it very safe, leaving you with the problem of getting things in and out of the sandbox.</em></p>
<p>As taken right out of the marketing book. It&#8217;s BS. If it was as easy as prohibiting dangerous behaviour and then danger went away, Java would have solved world hunger by now.</p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2009/09/net-considered-harmful/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MS patch of&#8230; Firefox?</title>
		<link>http://ursecta.com/wp/2009/06/ms-patch-of-firefox/</link>
		<comments>http://ursecta.com/wp/2009/06/ms-patch-of-firefox/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 09:36:36 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[Dotnet]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=238</guid>
		<description><![CDATA[To quote an article on annoyances.org about the new ClickOnce install support that MS has added to .NET: The Microsoft .NET Framework 3.5 Service Pack 1 update, pushed through the Windows Update service to all recent editions of Windows in February 2009, installs the Microsoft .NET Framework Assistant firefox extension without asking your permission. This [...]]]></description>
			<content:encoded><![CDATA[<p>To quote an <a href="http://ursecta.com/wp/go.php?http://annoyances.org/exec/show/article08-600" target="_blank" title="(140 hits)">article on annoyances.org</a> about the new ClickOnce install support that MS has added to .NET:</p>
<blockquote><p>The <a href="http://ursecta.com/wp/go.php?http://support.microsoft.com/kb/951847" target="_blank" title="(132 hits)">Microsoft .NET Framework 3.5 Service Pack 1</a> update, pushed through the Windows Update service to all recent editions of Windows in February 2009, installs the Microsoft .NET Framework Assistant firefox extension without asking your permission.<br />
This update adds to Firefox one of the most dangerous vulnerabilities present in all versions of Internet Explorer: the ability for websites to easily and quietly install software on your PC. Since this design flaw is one of the reasons you may&#8217;ve originally choosen to abandon IE in favor of a safer browser like Firefox, you may wish to remove this extension with all due haste.</p>
<p>Unfortunately, Microsoft in their infinite wisdom has taken steps to make the removal of this extension particularly difficult &#8211; open the Add-ons window in Firefox, and you&#8217;ll notice the Uninstall button next to their extension is grayed out! Their reasoning, according to <a href="http://ursecta.com/wp/go.php?http://blogs.msdn.com/brada/archive/2009/02/27/uninstalling-the-clickonce-support-for-firefox.aspx" target="_blank" title="(162 hits)">Microsoft blogger Brad Abrams</a>, is that the extension needed &#8220;support at the machine level in order to enable the feature for all users on the machine,&#8221; which, of course, is precisely the reason this add-on is bad news for all Firefox users.</p></blockquote>
<p>And then follows a convoluted procedure to hack the crap out of the registry. <a href="http://ursecta.com/wp/go.php?http://annoyances.org/exec/show/article08-600" target="_blank" title="(140 hits)">Go there, read it</a>, do it, if you run Windows, this service pack, and Firefox.</p>
<p>Tech Republic put it like this:</p>
<blockquote><p>In a surprise move this year, Microsoft has decided to quietly install what amounts to a massive security vulnerability in Firefox without informing the user. Find out what Microsoft has to say about it, and how you can undo the damage.</p></blockquote>
<p>Read the entire <a href="http://ursecta.com/wp/go.php?http://blogs.techrepublic.com.com/security/?p=1716&amp;tag=nl.e019" target="_blank" title="(149 hits)">Tech Republic article</a>.</p>
<p><em>PS: this isn&#8217;t exactly news (the annoyances.org article is dated February 27, 2009), but I only just noticed through a posting by Rob S on a private list.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2009/06/ms-patch-of-firefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evil after all?</title>
		<link>http://ursecta.com/wp/2009/05/evil-after-all/</link>
		<comments>http://ursecta.com/wp/2009/05/evil-after-all/#comments</comments>
		<pubDate>Wed, 27 May 2009 18:04:29 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://ursecta.com/wp/?p=235</guid>
		<description><![CDATA[I habitually block outbound connections to tracking services like google-analytics.com. (I use Little Snitch for this.) Just because I don&#8217;t like them. Recently I noticed I often can&#8217;t connect to youtube.com, getting &#8220;server not found&#8221; errors. Amazingly, once I let google-analytics through again, everything works. I haven&#8217;t verified exactly why this happens so I&#8217;m guessing [...]]]></description>
			<content:encoded><![CDATA[<p>I habitually block outbound connections to tracking services like google-analytics.com. (I use <a title="Little Snitch homepag (130 hits)" href="http://ursecta.com/wp/go.php?http://www.obdev.at/products/littlesnitch/index.html" target="_blank">Little Snitch</a> for this.) Just because I don&#8217;t like them. Recently I noticed I often can&#8217;t connect to youtube.com, getting &#8220;server not found&#8221; errors. Amazingly, once I let google-analytics through again, everything works.</p>
<p>I haven&#8217;t verified exactly why this happens so I&#8217;m guessing the DNS for google-analytics resolves to at least some of the IP numbers for youtube, causing this to happen. Maybe not, maybe something else is happening.</p>
<p>But that&#8217;s not the important question. The thing that disturbs me more is if Google is intentionally making life difficult for people like me that don&#8217;t want excessive tracking of their surfing habits. Is that what is going on? Is it the start of a new and highly evil trend?</p>
<div id="attachment_236" class="wp-caption alignnone" style="width: 310px"><a href="http://ursecta.com/wp/go.php?http://ursecta.com/wp/wp-content/uploads/2009/05/507.jpg" title="(132 hits)"><img class="size-medium wp-image-236" title="Little snitch rules for outbound filters" src="http://ursecta.com/wp/wp-content/uploads/2009/05/507-300x129.jpg" alt="Little snitch rules for outbound filters" width="300" height="129" /></a><p class="wp-caption-text">Little snitch rules for outbound filters</p></div>
]]></content:encoded>
			<wfw:commentRss>http://ursecta.com/wp/2009/05/evil-after-all/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

