I'm attaching a patch which updates the udev rule generation stuff in
libconcord. It adds a fourth option to gen_udev_support (because, you
know, it wasn't messy enough already).

Modern udev - well, udev since June 2009 - can control access to device
nodes via ACLs, avoiding the need for anything external (hal, policykit,
consolekit, whatever) for controlling access. The existing 'generic
udev' support is kind of hacky, abusing a system group and requiring you
to add user accounts to it manually. The existing 'policykit' and
'consolekit' support (which should really be named hal/policykit and
hal/consolekit) rely on hal and are therefore useless on modern
distributions where hal is being nuked with a vengeance. I doubt the
policykit stuff would work with pk 1.0 either, though I haven't checked
(can't check, no hal in fedora). Using udev-acl is very simple and
elegant and avoids all that complexity and reliance on dead/dying
interfaces.

This will only work with udev builds that have this commit in them:

https://git.kernel.org/?p=linux/hotplug/udev.git;a=commit;h=5e199245f2d2fd03c2586a7f1140300b073a4abe

since it relies on that ID_REMOTE_CONTROL bit. Upstream, I believe that
should be udev 167 and newer. It would be pretty trivial to pull the
patch downstream into distributions with older udev versions, though.
I'm going to pull it into F15 if it isn't there already, so all
supported Fedoras would work okay. The underlying ACL stuff has been in
udev since 2009.

The patch uses ATTR rather than SYSFS for the new udev template, since
use of SYSFS has been deprecated forever and it is actually completely
removed in very recent udev. I left the old template as ATTR, though I
think SYSFS should work with *anything* since 2006, pretty much, it
would probably be safe to change it. I changed a BUS to a SUBSYSTEM in
the 'neat trick' for the same reason - BUS is not valid in current udev
and breaks the rule. Again, I think SUBSYSTEM has worked and BUS been
deprecated since 2006, so it's probably not worth the bother of making
this different between 'new' and 'old' generic udev options, since the
'neat trick' is currently not conditional on which method you're
picking. I don't think this should break any remotely sane system. And
besides, the previous two lines use SUBSYSTEM anyway...

The patch gives the udev rules file a priority of 60 rather than 99. For
the ACL support to work it needs to be ahead of 70-uaccess.rules, and I
don't think a priority of 60 should break the old udev case, I don't
think it depends on any other rules lower than 60 in the pecking order.
Let me know if you can see an issue with this.

Kay Sievers was a huge help in working out this patch, so thanks to him.
According to him, the permissions udev actually sets on the node should
be just about identical to what the hal/policykit method does - it
allows just about the same set of 'active users' to have access, and
denies the same set of 'inactive users'. Here's the IRC snippet:

 the line above will grant access to locally logged-in users
 not to all users
<kay> not to ssh users
 not to inactive users
 not to the ones with fast-user-switching and in the background

so I think we're good there. I have confirmed at least that you cannot
access the remote as a user who's logged in via ssh.

I updated the INSTALL.linux file with what I hope is an accurate
explanation of the benefits/drawbacks of each choice.

I note there's a zwave-work (or something like that) branch for new
devices which is more active than HEAD these days, but happily it seems
like none of the files I touched is different between HEAD and that
branch, so this should apply to both.

With this patch, libconcord finally actually works as a regular user in
Fedora again! We only left it broken for a year or so. :) We started the
ACL stuff like nearly a year ago, but it never worked and we just got
around to revisiting it today and figuring out why (a silly typo in the
rules file, and the rules ordering issue).

I did at least test that with this patch, all four gen_udev_support
options work and generate the files as they should (and that any wrong
attempt to invoke gen_udev_support still fails as it should). I admit I
didn't test the renamed makefile rules for the old udev support, but I
did look at them carefully and I'm pretty sure I didn't do it wrong. =)

I'll try follow up with a patch that drastically cleans up the udev
rules file - since you can use ranges for device IDs, we should be able
to make it, like, three lines long. Something like:

SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c1[1-4][0-9a-f]",  
ENV{ID_REMOTE_CONTROL}="1"

plus a line for the one device with the old vendor ID. This would
obviate the need for the 'neat trick' entirely. This is also a
suggestion from Kay, so credit to him.  I also have a trivial patch to
fix compilation with GCC 4.7.
-- 
Adam Williamson
Fedora QA Community Monkey
IRC: adamw | Twitter: AdamW_Fedora | identi.ca: adamwfedora
http://www.happyassassin.net
diff -urN concordance-0.23/libconcord/gen_udev_support concordance-0.23-new/libconcord/gen_udev_support
--- concordance-0.23/libconcord/gen_udev_support	2009-02-26 10:22:49.000000000 -0800
+++ concordance-0.23-new/libconcord/gen_udev_support	2012-01-16 17:37:26.867310609 -0800
@@ -15,7 +15,8 @@
 #
 
 UDEV_POLICY_TEMPLATE='ATTR{idVendor}=="%s", ATTR{idProduct}=="%s", SYMLINK+="harmony-%%k"'
-UDEV_NO_POLICY_TEMPLATE='SYSFS{idVendor}=="%s", SYSFS{idProduct}=="%s", MODE="0660", GROUP="dialout"'
+UDEV_NEW_NO_POLICY_TEMPLATE='ATTR{idVendor}=="%s", ATTR{idProduct}=="%s", ENV{ID_REMOTE_CONTROL}="1"'
+UDEV_OLD_NO_POLICY_TEMPLATE='SYSFS{idVendor}=="%s", SYSFS{idProduct}=="%s", MODE="0660", GROUP="dialout"'
 
 HAL_PRE_TEMPLATE='    <match key="usb_device.vendor_id" int="0x%s">'
 HAL_RULE_TEMPLATE='      <match key="usb_device.product_id" int="0x%s">
@@ -66,7 +67,7 @@
 # Neat trick so that non-harmony devices don't read through a million rules
 SUBSYSTEM=="usb_device", GOTO="harmony_usb_rules"
 SUBSYSTEM=="usb", GOTO="harmony_usb_rules"
-BUS!="usb", GOTO="harmony_rules_end"
+SUBSYSTEM!="usb", GOTO="harmony_rules_end"
 GOTO="harmony_rules_end"
 LABEL="harmony_usb_rules"
 END
@@ -85,8 +86,10 @@
     type="$2"
     if [ "$type" == 'policykit' -o "$type" == 'consolekit' ]; then
         template="$UDEV_POLICY_TEMPLATE"
+    elif [ "$type" == 'old_udev' ]; then
+        template="$UDEV_OLD_NO_POLICY_TEMPLATE"
     else
-        template="$UDEV_NO_POLICY_TEMPLATE"
+        template="$UDEV_NEW_NO_POLICY_TEMPLATE"
     fi
 
     emit_for_all $file "$template" 'yes'
@@ -192,14 +195,14 @@
 #
 
 usage() {
-    echo "Usage: $0 <-u|-p|-c>"
+    echo "Usage: $0 <-u|-p|-c|-o>"
 }
 
 #
 # MAIN
 #
 
-while getopts upc opt; do
+while getopts upco opt; do
     case $opt in
         u)
             MODE='udev_only'
@@ -210,6 +213,9 @@
         c)
             MODE='consolekit'
             ;;
+        o)
+            MODE='old_udev'
+            ;;
         *)
             usage
             exit 1
diff -urN concordance-0.23/libconcord/INSTALL.linux concordance-0.23-new/libconcord/INSTALL.linux
--- concordance-0.23/libconcord/INSTALL.linux	2010-08-01 09:00:42.000000000 -0700
+++ concordance-0.23-new/libconcord/INSTALL.linux	2012-01-16 17:47:03.024191082 -0800
@@ -31,34 +31,62 @@
 3. INSTALL UDEV/CONSOLEKIT/POLICYKIT SUPPORT (OPTIONAL)
 
 If you don't want to have to be root to use concordance (or any other
-libconcord frontend), you'll need to set up udev, consolekit, or policykit
-support. If you don't know which of these your distribution uses, then the
-plain udev support will work:
+libconcord frontend), you'll need to set up udev-acl, hal/consolekit, 
+hal/policykit or old udev support.
+
+Most modern distributions should use the udev-acl support. udev versions since
+167, released on 2011-03-30, have the necessary support for this method to
+work.
+
+With this option, all locally logged-in users will be able to have access
+to the remote control, but remote users (such as those logged in via ssh or
+fast user switching) will not. This support does not depend on anything beyond
+a sufficiently recent version of udev itself. To use the udev-acl support, do:
 
   make udev
   sudo make install_udev
 
-This will allow anyone in the "dialout" group to read and write to harmony
-remote controls connected to the machine.
+If you have an older distribution without a recent enough version of udev, you
+can choose between old-style generic udev support, hal/consolekit support, and
+hal/policykit support.
 
-Alternatively, if you use policykit (fedora, and ubuntu, for example), you can
-do:
+To use hal/policykit support, you can do:
 
   make policykit
   sudo make install_policykit
 
-This will generate a different udev file and all the appropriate policykit
+This will generate a different udev file and all the appropriate HAL/policykit
 files and install them in the right place for the console user to have access
-to the remote when it's plugged in. In otherwords, there is no need to do udev
-and policykit - policykit will take care of everything needed for policykit.
+to the remote when it's plugged in. It will work only if your distribution has
+udev, HAL and PolicyKit of around the correct vintage - approximately, the
+versions that were current in early 2009 - correctly built to work with each
+other.
 
-If your system is using consolekit, then you can use:
+To use hal/consolekit, you can do:
 
   make consolekit
   sudo make install_consolekit
 
-If you're not sure which method your system uses, the udev one will work on
-all systems. 
+This will do much the same as the hal/policykit support does, only with
+consolekit instead. As with the hal/policykit support, it depends on having
+udev, HAL and ConsoleKit of an early 2009 vintage, correctly built to work
+together.
+
+The safest option for old systems is the old generic udev support:
+
+  make old-udev
+  sudo make install_old-udev
+
+This will allow anyone in the "dialout" group to read and write to harmony
+remote controls connected to the machine. It should work with any udev system,
+including modern ones, but is a less sophisticated solution than the udev-acl
+support and requires you to add your user to the "dialout" group. 
+
+If you are not sure which method to use, and your distribution came out since
+March 2011, try the new udev option first, as it provides the cleanest
+configuration and most transparent operation. If it does not work, you can try
+the hal/consolekit or hal/policykit options, but old-udev is the most likely
+to work.
 
 NOTE: By default the install prefix is /usr/local which means that the
 udev/policykit/consolekit make targets will install in /usr/local/etc which
diff -urN concordance-0.23/libconcord/Makefile.am concordance-0.23-new/libconcord/Makefile.am
--- concordance-0.23/libconcord/Makefile.am	2010-08-14 14:17:04.000000000 -0700
+++ concordance-0.23-new/libconcord/Makefile.am	2012-01-16 17:12:27.975236664 -0800
@@ -15,10 +15,15 @@
 install_udev_generic:
 	$(MKDIR_P) $(DESTDIR)$(sysconfdir)/udev/rules.d
 	$(install_sh_DATA) libconcord.rules \
-		$(DESTDIR)$(sysconfdir)/udev/rules.d/99-libconcord.rules
+		$(DESTDIR)$(sysconfdir)/udev/rules.d/60-libconcord.rules
 
 install_udev: udev install_udev_generic
 
+old-udev:
+	./gen_udev_support -o
+
+install_old-udev: old-udev install_udev_generic
+
 policykit:
 	./gen_udev_support -p
 
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to