tag:blogger.com,1999:blog-69555332944010293062024-03-09T00:21:52.290+01:00inFragmentsLukas Lipavskyhttp://www.blogger.com/profile/05237176564462163447noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-6955533294401029306.post-86093688870487148892010-01-25T15:44:00.016+01:002010-01-25T17:30:54.480+01:00Update without root password?<p>In the old days of openSUSE 10.x I used <code>sudo</code> and its configuration to install updates and new software in GUI without the most-annoying (I know, secure) need to enter password of root. Since version 11, this is no longer possible.
</p><p>
Since I am too lazy to enter root password (I've already logged-in, it's me, right?), I spent quite some time figuring out how to solve it. And I finally did.
</p><p>
In KDE the kupdateapplet is used to check for updates. In default installation kupdate applet uses <a href="http://www.packagekit.org/">PackageKit</a> backend. To make things more complicated, PackageKit uses another framework: <a href="http://hal.freedesktop.org/docs/PolicyKit/">PolicyKit</a>. (From <a href="http://www.packagekit.org/pk-intro.html">What's PackageKit?</a>: <citation>"The primary design goal is to unify all the software graphical tools used in different distributions, and use some of the latest technology like PolicyKit to make the process suck less."</citation> - WTF?! I wanna sudo!).
</p><p>
How does it work? When the update applet issue update command to PackageKit, PackageKit asks PolicyKit for permission. PolicyKit checks it's configuration and either allows it, denies it, or ask for authentication (enter password). If you want to know how it works, read the PolicyKit and PackageKit documentation.
</p><p>
What we need to do is configure PolicyKit in a way that it gives permission to update action of PackageKit.
</p><p>
Default permissions are stored in file <code>/etc/polkit-default-privs.standard</code> (or <code>/etc/polkit-default-privs.restrictive</code> according to value of <code>POLKIT_DEFAULT_PRIVS</code> in <code>/etc/sysconfig/security</code>). The file have following syntax:
</p><p>
<code>action_id permissions</code></p><p>
or (one line)</p><p>
<code>action_id  perm_any_user:perm_user_not_on_the_active_console:perm_user_on_the_active_console</code>
</p><p>
In first case, same permission are applied. In second case different permission are used for user on active console, etc.
</p><p>
Possible permissions are:
<ul>
<li><b>yes</b> allowed</li>
<li><b>no</b> denied</li>
<li><b>auth_admin</b> need root password</li>
<li><b>auth_admin_keep</b> same as above, but will not require password again for some time</li>
<li><b>auth_user</b> need user password</li>
<li><b>auth_user_keep</b> same as above, but will not require password again for some time</li></ul>
</p><p>
Action IDs and their descriptions can be found in files located in <code>/usr/share/polkit-1/actions/</code>. The one we're looking for is: <code>org.freedesktop.packagekit.system-update</code>.
</p><p>
In our case, we want that user on active console don't have to enter root password for installation of updates. So we add following rule to <code>/etc/polkit-default-privs.local</code> (do not modify <code>polkit-default-privs.standard</code> and <code>polkit-default-privs.restrictive</code> since they may be overwritten during some update!):
</p><p>
<code>org.freedesktop.packagekit.system-update auth_admin:auth_admin:yes</code>
</p><p>
And we need to install the privileges to the system (without following command, it won't work):
</p><p>
<code>/sbin/set_polkit_default_privs</code>
</p><p>
Yes! Now you should be able to update your system without the need to enter root password.
</p><p>
Same way can be used for package installation, removal, etc. You can also ask user to enter his password instead of root password. The only thing I miss is Vista-like way: make user explicitly click "I know what I'm doing" without the need to enter password. Why? Because this way some script can install a package on your system without you even knowing it (If you have passwordless installation allowed for user on active console and the user runs the script without knowing what it exactly does. But I didn't test it, maybe it doesn't work this way? Maybe there's some check?)
</p><p>
Special thanks to Ludwig Nussel for pointing me to <code>/sbin/set_polkit_default_privs</code>.</p>Lukas Lipavskyhttp://www.blogger.com/profile/05237176564462163447noreply@blogger.com0tag:blogger.com,1999:blog-6955533294401029306.post-42180523664850313262009-11-09T13:14:00.006+01:002009-11-09T13:47:45.298+01:00OpenSUSE without the mess<p>I've just learned out, that openSUSE zypp has wery useful configuration file <span style="font-family:courier new;">/etc/zypp/zypp.conf</span>, which contains crucial option <span style="font-family:courier new;">solver.onlyRequires</span>. If you set it to <span style="font-family:courier new;">True</span>, only really needed dependencies will be installed (of course you can install other packages manually).
<p>
This should be also possible to set during the installation. Just need to set the value from console before the libzypp is initialize - during first few screens of installation. But don't forget that it must be set after reboot/kexec as well so it is also valid for 2nd stage of installation and installed system.Lukas Lipavskyhttp://www.blogger.com/profile/05237176564462163447noreply@blogger.com0tag:blogger.com,1999:blog-6955533294401029306.post-83436177256738633962009-02-26T16:50:00.005+01:002009-03-03T17:34:29.277+01:00RTFM!<p>Everybody knows. It's written in all programming languages textbooks (I hope). Always check function return values. As you learn more and more, you learn that there are two types of functions: those that need to be checked (I'll refer to them as important functions) and other functions.</p><p>Even though it is sometimes discutable (and depending of lazyness and carelessness of specific developer) which group a function belongs to, there are many functions where no such discussion is needed.</p><p>One example of important function is <tt><a href="http://www.openssl.org/docs/crypto/EVP_VerifyInit.html">EVP_VerifyFinal()</a></tt> which is part of <a href="http://www.openssl.org/">openSSL</a> library. The function is used as part of signature verification, so (hopefully) only complete idiot would dare not to check the return value.</p><p><sarcasm>Unfortunatelly the function is so complicated, that it can return three possible values: verification success, verification fail and error.</sarcasm> This is cleanly written in manual page. Since this part of the documentation is extreamply clear, I wonder why search for <tt>EVP_VerifyFinal</tt> on <a href="http://web.nvd.nist.gov/view/vuln/search">National Vulnerability Database</a> displays 10 results of (somehow) important applications which do not check the return values of the function.
</p><p>Since return values are described clearly in the documentation, I'm surprised that the return values are not (correctly) checked. The only reason I can think about so far is that the author did not read the documentation. Since the function is really important (it's part of secure connection initialization!), author should use it in a proper way. Which means - according to documentation...
</p><p>Conclusion: RTFM!
</p>Lukas Lipavskyhttp://www.blogger.com/profile/05237176564462163447noreply@blogger.com0tag:blogger.com,1999:blog-6955533294401029306.post-4159613353374864302009-02-20T14:16:00.002+01:002009-03-06T09:27:55.501+01:00NTP With Autokey Authentication<p>Recently I had to verify the functionality of NTP server with autokey authentication. Though I thought that it would be simple, it took me several days to find out how to configure the authentication. I found out dozens of different howtos, but none of them worked for me. So when I finally came to <a href="http://support.ntp.org/bin/view/Support/ConfiguringAutokey" class="external text" title="http://support.ntp.org/bin/view/Support/ConfiguringAutokey" rel="nofollow">one that worked</a>, I created several shell scripts that helped me to configure different kind of (unicast) NTP authentication. </p><p>The shell scripts are paired: setup_server_XYZ.sh and setup_client_XYZ.sh where XYZ is used <a href="http://www.eecis.udel.edu/%7Emills/ident.html" class="external text" title="http://www.eecis.udel.edu/~mills/ident.html" rel="nofollow">identity scheme</a>. MV identity scheme seems not to work on sles9.The usage of the scripts is: </p> <ol><li> Edit <tt>PASS/SPASS/CPASS</tt> variables in both client and server script! These are password for generated keys </li><li> Edit <tt>SERVER</tt> variable in setup_server_XYZ.sh - that is the server which will your server use for own synchronization. </li><li> Copy setup_server_XYZ.sh to the ntp server. </li><li> Run setup_server_XYZ.sh on the server. If XYZ is mv, script takes one argument N, which is number of client keys to generate + 1 (N-1 clients will be able to use the server). </li><li> Copy setup_client_XYZ.sh to the client. </li><li> Run setup_client_XYZ.sh <server_name_or_ip>. If XYZ is mv, script takes additional argument X which is client id - number between 1 and N-1 - which specifies which key client will use. The script will ask for server root's password twice - first time to identify the key to download from the server, and the second time to actually download the key. </server_name_or_ip></li><li> Make sure that both server and client are not configured to run in chroot (or copy/move <tt>/etc/ntp/</tt> and <tt>/etc/ntp.conf</tt> to appropriate chroot directory). </li><li> Start <tt>ntpd</tt> (manually or with initscript) on server and clients. It takes some time to establish the link between client and server (approximately 15 minutes). </li></ol> <p>When ntp is set up and running, the status can be checked with several commands: </p> <ul><li> <tt>ntpq -p</tt> - prints a list of server the host has configured as its NTP servers. If there's a star '*' before the server name, host uses the server for synchronization. </li><li> <tt>ntp -c as</tt> - print list of associations - including authentication status. Following output shows successfully authenticated association: </li></ul> <pre>ind assID status conf reach auth condition last_event cnt
===========================================================
1 26132 f694 yes yes ok sys.peer reachable 9
</pre> <p>
The scripts have following limitations: </p> <ul><li> Server is configured to use one server - which is not a good idea - it should use more than one (same for clients). To fix this just add more server lines to <tt>/etc/ntp.conf</tt>. </li><li> Usage of <tt>/dev/urandom</tt> is not the best one as well, <tt>/dev/random</tt> (or file generated by command <tt>openssl rand</tt>) should probably be used for maximal security. </li><li> Configuration is saved to <tt>/etc</tt> but <tt>ntpd</tt> usually run in chroot. </li><li> The script setup_server_mv.sh always endlessly loops while generating client keys - seems to continuously reject duplicate keys - this is probably not problem in the script. So, try to use it but don't be surprised ;-) </li></ul> <p>setup_server_gq.sh: </p> <pre>#!/bin/bash
PASS=lala
SERVER=ntp2.suse.de
rm -fr /etc/ntp
mkdir -p /etc/ntp
cat <<> /etc/ntp.conf
server $SERVER
keysdir /etc/ntp
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
EOF
cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -T -G -p $PASS
echo server is set up. Start it with \'ntpd -u ntp [-d]\'
</pre> <p>setup_client_gq.sh: </p> <pre>#!/bin/bash
PASS=lala
ping -c1 "$1" > /dev/null
if [ $? -ne 0 -o $# -ne 1 ] ; then
echo "Needs one argument - ntp server address"
exit 1
fi
rm -fr /etc/ntp
mkdir -p /etc/ntp
cat <<> /etc/ntp.conf
server $1 autokey
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
keysdir /etc/ntp
EOF
cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -H -p $PASS
KEY="`ssh root@$1 ls /etc/ntp/ntpkey_GQpar_\* | sed 's,.*/,,'`"
if [ "x$KEY" = "x" ] ; then
echo Error while fetching key name
exit 1
fi
scp root@$1:/etc/ntp/$KEY .
LINK="`echo $KEY | sed 's/^ntpkey_GQpar_\(.*\)\.[0-9]\+$/ntpkey_gp_\1/'`"
ln -s $KEY $LINK
echo client is set up. Start it with \'ntpd -u ntp [-d]\'
</pre> <p>setup_server_iff.sh: </p> <pre>#!/bin/bash
SPASS=lala
CPASS=alal
SERVER=ntp2.suse.de
rm -fr /etc/ntp
mkdir -p /etc/ntp
cat <<> /etc/ntp.conf
server $SERVER
keysdir /etc/ntp
crypto pw $SPASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
EOF
cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -T -I -p $SPASS
RANDFILE=/dev/urandom ntp-keygen -e -q $SPASS -p $CPASS > tmp_key
echo keyname "'`head -n1 tmp_key | sed 's/^# *//'`'"
mv tmp_key `head -n1 tmp_key | sed 's/^# *//'`
echo server is set up. Start it with \'ntpd -u ntp [-d]\'
</pre> <p>setup_client_iff.sh: </p> <pre>#!/bin/bash
CPASS=alal
ping -c1 "$1" > /dev/null
if [ $? -ne 0 -o $# -ne 1 ] ; then
echo "Needs one argument - ntp server address"
exit 1
fi
rm -fr /etc/ntp
mkdir -p /etc/ntp
cat <<> /etc/ntp.conf
server $1 autokey
crypto pw $CPASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
keysdir /etc/ntp
EOF
cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -H -p $CPASS
KEY="`ssh root@$1 ls /etc/ntp/ntpkey_IFFkey_\* | sed 's,.*/,,'`"
if [ "x$KEY" = "x" ] ; then
echo Error while fetching key name
exit 1
fi
scp root@$1:/etc/ntp/$KEY .
LINK="`echo $KEY | sed 's/^ntpkey_IFFkey_\(.*\)\.[0-9]\+$/ntpkey_iff_\1/'`"
ln -s $KEY $LINK
echo client is set up. Start it with \'ntpd -u ntp [-d]\'
</pre> <p>setup_server_mv.sh (loops!!!): </p> <pre>#!/bin/bash
PASS=lala
SERVER=ntp2.suse.de
if [ "x`echo $1 | grep '^[1-9][0-9]*$'`" = "x" ] ; then
echo Needs one argument n - number of client certificates to create + 1.
exit 1
fi
rm -fr /etc/ntp
mkdir -p /etc/ntp
cat <<> /etc/ntp.conf
server $SERVER
keysdir /etc/ntp
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
EOF
cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -V $1 -p $PASS
echo server is set up. Start it with \'ntpd -u ntp [-d]\'
</pre> <p>setup_client_mv.sh (untested, because setup_server_mv.sh loops!): </p> <pre>#!/bin/bash
PASS=lala
ping -c1 "$1" > /dev/null
if [ $? -ne 0 -o $# -ne 2 -o "x`echo $2 | grep '^[1-9][0-9]*$'`" = "x" ] ; then
echo "Needs two arguments:"
echo " 1. ntp server address"
echo " 2. ntp client id 1..n-1 - which certificate to get."
exit 1
fi
rm -fr /etc/ntp
mkdir -p /etc/ntp
cat <<> /etc/ntp.conf
server $1 autokey
crypto pw $PASS randfile /dev/urandom
logfile /var/log/ntp
logconfig =all
keysdir /etc/ntp
EOF
cd /etc/ntp
RANDFILE=/dev/urandom ntp-keygen -H -p $PASS
KEY="`ssh root@$1 ls /etc/ntp/ntpkey_MVkey$2_\* | sed 's,.*/,,'`"
if [ "x$KEY" = "x" ] ; then
echo Error while fetching key name
exit 1
fi
scp root@$1:/etc/ntp/$KEY .
LINK="`echo $KEY | sed 's/^ntpkey_MVkey[1-9][0-9]*_\(.*\)\.[0-9]\+$/ntpkey_mv_\1/'`"
ln -s $KEY $LINK
echo client is set up. Start it with \'ntpd -u ntp [-d]\'
</pre><p>That's all, I hope this can spare some time...</p><p><span style="font-style: italic;">(</span><span style="font-style: italic;">This text has also been published on <a href="http://en.opensuse.org/NTP_With_Autokey_Authentication">openSUSE wiki</a>)
</span></p>Lukas Lipavskyhttp://www.blogger.com/profile/05237176564462163447noreply@blogger.com0tag:blogger.com,1999:blog-6955533294401029306.post-37828899828737279342009-02-18T13:50:00.000+01:002009-02-18T14:12:46.567+01:00Overloading library function<p>Sometimes during testing (especially while testing maintenance update), I come to a problem how to test the reaction of the program to an unusual function return value (e.g. special error), data, etc. The problem is, that I need to test the unmodified program binary and that it is almost impossible to set up a situation when the error "naturally" occurs. </p><p>If the function is in a shared library, there is a simple way to force the program to use another function instead of the one from the library. The program will call the new function, which will return the specific value (unusual error I need to test). </p><p>The magic "tool" is <tt>LD_PRELOAD</tt> variable. When the program is loaded to memory, libraries specified in <tt>LD_PRELOAD</tt> are loaded before libraries needed by the program. If I have function <tt>strdup()</tt> in my custom library (loaded by <tt>LD_PRELOAD</tt>), it will be used instead of <tt>strdup()</tt> from standard C library. </p><p>So for (very simplified) example, let's say I need to test program <tt>prog</tt> correctly checks whether <tt>strdup()</tt> returns <tt>NULL</tt> (I assume that <tt>prog</tt> segfaults on <tt>NULL</tt> access): I'll write simple library libexploit which will only contains my new <tt>strdup()</tt>. </p><p>exploit.c: </p> <pre>char *strdup(const char *s)
{
return NULL;
}
</pre> <p>Makefile: </p> <pre>all: libexploit.so.1.0
clean:
rm -f libexploit.so.1.0 *.o
libexploit.so.1.0: exploit.o
gcc -shared -Wl,-soname,libexploit.so.1 -o libexploit.so.1.0 exploit.o
exploit.o: exploit.c
gcc -Wall -fPIC -c exploit.c
</pre> <p>
Now when I make the simple library, I'll get result libexploit.so.1.0 which I'll preload to the program: </p> <pre>LD_PRELOAD="`pwd`/libexploit.so.1.0" prog
</pre> <p>And it is all - the program got <tt>NULL</tt> from all calls to <tt>strdup()</tt>. </p><p>Simple, right? There is one catch, however. Or two. </p><p>First problem is that the original function is replaced by the new one, so you cannot call the original one (not even from your "new" function). </p><p>Second problem is that even the original library will start using your function. So if the library is using the overloaded function, it uses the new one. This may result in unexpected library behavior. </p><p>Both these problems are not (AFAIK) solvable in a easy way. The only way I've found out so far is the re-factoring of the original library in following steps: </p> <ol><li> Rename the original function - e.g. from <tt>strdup()</tt> to <tt>__strdup()</tt>. </li><li> Replace all calls of function <tt>strdup()</tt> with calls of function <tt>__strdup()</tt> in the library source - this will ensure that the library code will always call the correct function. </li><li> Create new function <tt>strdup()</tt> which will contain the testing code (and can also call the original <tt>__strdup()</tt> function). </li><li> Compile the library and load it with <tt>LD_PRELOAD</tt> as described above. </li></ol> <p>Now, that's finally all.
</p><p><span style="font-style: italic;">(This text has also been published on <a href="http://en.opensuse.org/Overloading_library_function">openSUSE wiki</a>)</span>
</p>Lukas Lipavskyhttp://www.blogger.com/profile/05237176564462163447noreply@blogger.com0