Changeset 1042

Show
Ignore:
Timestamp:
05/14/08 17:22:03 (7 months ago)
Author:
alonbl
Message:

Non privileged operation

As OpenCT is a security component, it best to use least privileged mode, and udev allows this now.
The attached patch allows users to run the ifdhandler as none root user.

The configuration file was modified, not the ifdhandler is a node in the following format:

#
# Path to ifdhandler
ifdhandler {

program = SBINDIR/ifdhandler;

# user = openctd;
# groups = {
# usb,
# };
};

I believe this place is correct, but if people want to keep backward compatibility I guess
this can be splitted, and keep current ifdhandler key.

The openct-control running from init.d script or udev rule script will fork the ifdhandler using
the specified user and set the context to the specified groups. There may be more than one
group as there are more than one device type.

It also set the /var/run/openct/status owner to the specified user.

M src/tools/openct-control.c
M src/ifd/utils.c
M src/ifd/init.c
M src/include/openct/openct.h
M src/ct/status.c
M etc/openct.conf.in

Location:
trunk
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/etc/openct.conf.in

    r1038 r1042  
    44# Enable hot plugging 
    55hotplug = yes; 
     6 
    67# 
    78# Path to ifdhandler 
    8 ifdhandler = SBINDIR/ifdhandler; 
     9ifdhandler { 
     10        program         = SBINDIR/ifdhandler; 
     11#       user            = openctd; 
     12#       groups = { 
     13#               usb, 
     14#       }; 
     15}; 
    916 
    1017# 
  • trunk/src/ct/status.c

    r1033 r1042  
    1111#include <sys/mman.h> 
    1212#include <sys/stat.h> 
     13#include <sys/types.h> 
     14#include <pwd.h> 
    1315#include <signal.h> 
    1416#include <unistd.h> 
     
    6264} 
    6365 
    64 int ct_status_clear(unsigned int count) 
    65 { 
    66         int fd; 
     66int ct_status_clear(unsigned int count, const char *owner) 
     67{ 
     68        int fd = -1; 
    6769        char status_path[PATH_MAX]; 
    6870 
     
    7678            || fchmod(fd, 0644) < 0) { 
    7779                ct_error("cannot create %s: %m", status_path); 
    78                 unlink(status_path); 
    79                 if (fd >= 0) 
    80                         close(fd); 
    81                 return -1; 
     80                goto error; 
     81        } 
     82 
     83        if (owner != NULL) { 
     84                struct passwd *p = getpwnam(owner); 
     85 
     86                if (p == NULL) { 
     87                        ct_error("cannot parse user %s", owner); 
     88                        goto error; 
     89                } 
     90 
     91                if (fchown(fd, p->pw_uid, -1) == -1) { 
     92                        ct_error("cannot chown %s to %s: %m", status_path, owner); 
     93                        goto error; 
     94                } 
    8295        } 
    8396 
    8497        return 0; 
     98 
     99error: 
     100 
     101        unlink(status_path); 
     102        if (fd >= 0) 
     103                close(fd); 
     104        return -1; 
    85105} 
    86106 
  • trunk/src/ifd/init.c

    r1009 r1042  
    6262                ct_config.debug = ival; 
    6363 
    64         if (ifd_conf_get_string("ifdhandler", &sval) >= 0) 
     64        if (ifd_conf_get_string("ifdhandler.program", &sval) >= 0) 
    6565                ct_config.ifdhandler = sval; 
    6666 
  • trunk/src/ifd/utils.c

    r964 r1042  
    1414#include <sys/stat.h> 
    1515#include <sys/wait.h> 
     16#include <sys/types.h> 
     17#include <pwd.h> 
     18#include <grp.h> 
    1619 
    1720#ifndef __GNUC__ 
     
    8790        int argc, n; 
    8891        pid_t pid; 
     92        char *user = NULL; 
    8993 
    9094        ifd_debug(1, "driver=%s, devtype=%s, index=%d", driver, devtype, idx); 
     
    141145        while (--n > 2) 
    142146                close(n); 
     147         
     148        if ((n = ifd_conf_get_string_list("ifdhandler.groups", NULL, 0)) > 0) { 
     149                char **groups = (char **)calloc(n, sizeof(char *)); 
     150                gid_t *gids = (gid_t *)calloc(n, sizeof(gid_t)); 
     151                int j; 
     152                if (!groups || !gids) { 
     153                        ct_error("out of memory"); 
     154                        exit(1); 
     155                } 
     156                n = ifd_conf_get_string_list("ifdhandler.groups", groups, n); 
     157                for (j = 0; j < n; j++) { 
     158                        struct group *g = getgrnam(groups[j]); 
     159                        if (g == NULL) { 
     160                                ct_error("failed to parse group %s", groups[j]); 
     161                                exit(1); 
     162                        } 
     163                        gids[j] = g->gr_gid; 
     164                } 
     165                if (setgroups(n-1, &gids[1]) == -1) { 
     166                        ct_error("failed set groups %m"); 
     167                        exit(1); 
     168                } 
     169                if (setgid(gids[0]) == -1) { 
     170                        ct_error("failed setgid %d %m", gids[0]); 
     171                        exit(1); 
     172                } 
     173                free(groups); 
     174                free(gids); 
     175        } 
     176 
     177        if (ifd_conf_get_string("ifdhandler.user", &user) >= 0) { 
     178                struct passwd *p = getpwnam(user); 
     179 
     180                if (p == NULL) { 
     181                        ct_error("failed to parse user %s", user); 
     182                        exit(1); 
     183                } 
     184 
     185                if (setuid(p->pw_uid) == -1) { 
     186                        ct_error("failed to set*uid user %s %m", user); 
     187                        exit(1); 
     188                } 
     189        } 
    143190 
    144191        execv(ct_config.ifdhandler, (char **)argv); 
  • trunk/src/include/openct/openct.h

    r859 r1042  
    9292                                const void *send_buf, size_t send_len); 
    9393 
    94 extern int              ct_status_clear(unsigned int); 
     94extern int              ct_status_clear(unsigned int, const char *); 
    9595extern ct_info_t *      ct_status_alloc_slot(int *); 
    9696extern int              ct_status_update(ct_info_t *); 
  • trunk/src/tools/openct-control.c

    r1032 r1042  
    9494static int mgr_init(int argc, char **argv) 
    9595{ 
     96        char *ifdhandler_user = NULL; 
     97        char *sval; 
    9698        int n; 
    9799 
     
    99101                usage(1); 
    100102 
     103        /* Get the ifdhandler user so we can set ownership */ 
     104        if (ifd_conf_get_string("ifdhandler.user", &sval) >= 0) 
     105                ifdhandler_user = sval; 
     106 
    101107        /* Zap the status file */ 
    102         ct_status_clear(OPENCT_MAX_READERS); 
     108        ct_status_clear(OPENCT_MAX_READERS, ifdhandler_user); 
    103109 
    104110        /* Initialize IFD library */