Archive for January, 2010

SELinux and audit2allow

Using SELinux is reasonably straight forward once you get used to it.  It protects OS objects and configuration from potentially dangerous manipulation.  If an exception to its current policy is found then it is logged and either denied or allowed.  The reasons that it may be allowed depend on the policy’s construction.

For me I use a targeted, as opposed to blanket, policy and set the SELinux level to enforcing.  This means that not everything unplanned will be blocked, but it does log and alert me when something crosses the policy line and allows me to block it if I feel it is necessary.  Naturally it also can block services that I want to use too.  So in this case I will look at setting up vsftpd to access home directories.

If you run this command (you need the selinuxtools package installed) you will generate a new policy straight to the console to allow all of the exceptions found in the SELinux log ‘audit2allow < /var/log/audit/audit.log’.  Naturally this is not what we want as it will generate a policy that will allow all previously caught exceptions to proceed.  We just want to allow ftp; which is what the following statement does: ‘grep ftp /var/log/audit/audit.log | audit2allow -R’.

The result:

[foo@bar ~]# grep ftp /var/log/audit/audit.log | audit2allow -R
require {
type ftpd_t;
type home_root_t;
class capability net_raw;
class dir search;
}
#============= ftpd_t ==============
#!!!! This avc can be allowed using one of the these booleans:
#     allow_ftpd_full_access, allow_ftpd_full_access
allow ftpd_t home_root_t:dir search;
allow ftpd_t self:capability net_raw;

What is interesting here is that the audit2allow application alerts us to the fact that the same thing being achieved through the creation of this policy could also be accomplished using SELinux booleans; in this case  ‘setsebool -P allow_ftpd_full_access true’ would do the trick.  However we’re going to do this the long way as booleans are not always available, this is just the first step.

Now that we have inspected the policy we need to build it and integrate it into the active policy.  First we need to construct the new policy file using ‘grep ftp /var/log/audit/audit.log | audit2allow -M ftp’.  This will create a ‘ftp.te’ policy file and a ‘ftp.pp’ compiled policy file.  To make the new policy active simply run ‘semodule -i ftp.pp’ and its done.  This of course may reveal another denial or other OS configuration issue so you just need to perform an allow then test to see if there is anything else that needs sorting out.


A Brief Linux Sockets Connect Illustration

For a little while I’ve been playing with sockets in C now and have come up with the following succinct example of connecting.  Note that the connection is fairly flexible with regards to protocol and transport type.  It really is simply there to make the connection to somewhere else with as few questions asked.  It will involve DNS and service lookups if you provide names instead of the network address and port.  If you want to catch exceptions you need to clear the standard error variable and check it yourself after receiving a fail return value.  It won’t, or at least shouldn’t, report any exceptions because for my current purposes failures are not really exceptions just dead ends on some of many paths.  I tried to keep it simple too, have fun.


/* connect_to_socket
 *
 * connect to a socket using an initialised addrinfo structure,
 *
 * info is an initialised addrinfo structure
 * sock is a pointer to the location to store the socket descriptor when opened
 *
 * returns 0 if successful
 */
int connect_to_socket(const struct addrinfo *info, int* sock) {

    /* open socket */
    *sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
    if (*sock < 1) return -1;

    /* connect to the server*/
    if (connect(*sock, info->ai_addr, info->ai_addrlen) == 0)
        return 0;

    /* clean up on failure */
    close(*sock);
    return -1;
}

/* connect_to_server
 *
 * connect to a server using the server name or adress and port or service name
 *
 * server is a string containing either the name or address of the server
 * port is a string containing either the service name or port number to use
 * sock is a pointer to the location to store the socket descriptor when opened
 *
 *  returns 0 if successful
 */
int connect_to_server(const char* server, const char* port, int* sock) {

    struct addrinfo hints, *info = NULL, *list = NULL;
    int e = 0;

    /* initialise the hints for retrieving the address details */
    memset(&hints, 0, sizeof (hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    hints.ai_protocol = 0;

    /* get the address if the server to connect to */
    e = getaddrinfo(server, port, &hints, &list);
    if (e != 0) return -1;

    /* connect to the first socket in the list */
    for (info = list; info != NULL; info = info->ai_next)
        if (connect_to_socket(info, sock) == 0)
            break;

    /* clean up and return */
    if (list != NULL) freeaddrinfo(list);
    if (sock > 0) return 0;
    else return -1;
}

When there’s Nothing in your Sock

Normally I do most of my network programming in Java; life is just easier that way. But some times, *very* rarely, you need to carve up a little C.  So I’ve not touched socket networking for a while and all its foibles.  Hence a few problems with reading from a socket.

When socket programming with the ‘read’ function it does not always return the length read into the buffer.  In fact if you are talking to an HTTP server a ‘GET /‘ will nearly always end with read returning 0.  This is because the socket will have been closed on your last read.  This of course begs the question, how do you know how much was read in the last read?  For me this was simple; I just zero filled the buffer prior to reading.


ssize_t r_read(int sock, void* buf, size_t size)
{
        ssize_t ret;
        bzero(buf, size);
        while (ret = read(sock, buf, size - 1), ret == -1 && errno == EINTR);
        return ret;
}


Which does work because now its a simple matter of counting until the first 0 shows up, but I’d still like to know how to tell how many characters were read without having to do the count. This becomes more important when transferring binary files as you won’t know if the 0 is validly part of the file or not.


Copyright © 1996-2010 Code Snips. All rights reserved.
iDream theme by Templates Next | Powered by WordPress