From 898603a3682e43440679461e4fd494fa9873aaba Mon Sep 17 00:00:00 2001 From: short <> Date: Mon, 9 Jul 2001 22:49:08 +0000 Subject: [PATCH 1/1] Various common utility sources --- src/flock.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pserverchroot.c | 74 ++++++++++++++++++++++++++++++++++++++++++++ src/unmime.c | 26 ++++++++++++++++ src/urlencode.c | 24 +++++++++++++++ 4 files changed, 213 insertions(+) create mode 100644 src/flock.c create mode 100644 src/pserverchroot.c create mode 100644 src/unmime.c create mode 100644 src/urlencode.c diff --git a/src/flock.c b/src/flock.c new file mode 100644 index 0000000..e256676 --- /dev/null +++ b/src/flock.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define failf(name) do { fprintf(stderr,"%s: ",pname); perror(name"()"); exit(EXIT_FAILURE); } while (0) +const char version[]="This is FLock, version 1.0\n"; + +int verbose; + +char *pname; + +static __NORETURN void usage(void) +{ + fprintf(stderr,"\ +%s\ +This command acts as an interface to flock(2):\n\ +\n\ +Usage: flock [{-s|--shared}|{-x|--exclusive}] [-n|--nonblock]\n\ + [-v|--verbose] [-h|--help] [-V|--version]\n\ + \n\ +\n\ + -s, --shared\tCreate shared lock (LOCK_SH) - DEFAULT\n\ + -x, --exclusive\tCreate exclusive lock (LOCK_EX)\n\ + -n, --nonblock\tFail immediately if req. lock is busy\n\ + -v, --verbose\tDisplay progress during locking\n\ + -h, --help\tPrint a summary of the options\n\ + -V, --version\tPrint the version number\n\ +",version); + exit(EXIT_FAILURE); +} + +const struct option longopts[]={ +{"shared" ,0,0,'s'}, +{"exclusive",0,0,'x'}, +{"nonblock" ,0,0,'n'}, +{"verbose" ,0,0,'v'}, +{"help" ,0,0,'h'}, +{"version" ,0,0,'V'}}; + +int main(int argc,char **argv) +{ +char *fn,*cmd; +int locktype=LOCK_SH,nonblock=0,fd,optc; + + pname=*argv; + while ((optc=getopt_long(argc,argv,"sxnvhV",longopts,NULL))!=EOF) switch (optc) { + case 's': + locktype=LOCK_SH; + break; + case 'x': + locktype=LOCK_EX; + break; + case 'n': + nonblock=LOCK_NB; + break; + case 'v': + verbose=1; + break; + case 'V': + fprintf(stderr,version); + exit(EXIT_FAILURE); + default: /* also 'h' */ + usage(); + break; + } + if (optind+2!=argc) { + fprintf(stderr,"%s: Incorrect number of parameters (command needs quoting?)!\n",pname); + exit(EXIT_FAILURE); + } + fn=argv[optind]; + cmd=argv[optind+1]; + if (verbose) { fprintf(stderr,"%s: Opening \"%s\"...",pname,fn); fflush(stderr); } + if ((fd=open(fn,O_RDONLY|(nonblock?O_NONBLOCK:0)))==-1) failf("open"); + if (verbose) { fprintf(stderr,"done\n%s: Locking \"%s\"...",pname,fn); fflush(stderr); } + if (flock(fd,locktype|nonblock)) failf("flock"); + if (verbose) { fprintf(stderr,"done\n%s: Running \"%s\"...",pname,cmd); fflush(stderr); } + if (system(cmd)==-1) failf("system"); + if (verbose) { fprintf(stderr,"done\n%s: Finishing - removing lock.\n",pname); } + return(EXIT_SUCCESS); +} diff --git a/src/pserverchroot.c b/src/pserverchroot.c new file mode 100644 index 0000000..ca79201 --- /dev/null +++ b/src/pserverchroot.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +extern const char **environ; + + +#define SETUID 613 /* "pserver" user UID */ +#define SETGID 613 /* "pserver" group GID */ +#define PERMITTED_ENV_LIST "PWD" +#define EXEC_PATHNAME "/usr/bin/cvs" + + +#ifndef G_GNUC_NORETURN +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define G_GNUC_NORETURN __attribute__((noreturn)) +#else /* !__GNUC__ */ +#define G_GNUC_NORETURN +#endif /* !__GNUC__ */ +#endif /* !G_GNUC_NORETURN */ + +#define EXITLOG(msg...) do {\ + openlog("pserverchroot",LOG_PID,LOG_DAEMON); \ + syslog(LOG_CRIT,msg); \ + closelog(); \ + exit(EXIT_FAILURE); \ + } while (0) + +#define LENGTH(x) (sizeof((x))/sizeof(*(x))) + +#define FUNCCHK(funcname,args...) do { \ + if (errno=0,funcname(args)) \ + funcfail( #funcname ); \ + } while (0) + +static void funcfail(const char *funcname) G_GNUC_NORETURN; +static void funcfail(const char *funcname) +{ + EXITLOG("Unable to %s(2): %s",funcname,strerror(errno)); +} + +int main(int argc,char **argv) +{ +int total=0; +const char *allowed[]={ PERMITTED_ENV_LIST }; +const char **allp,**envp; +char *dup=NULL,*s; + +retry: + for (envp=environ;*envp;envp++) { + if (dup) free(dup); + dup=strdup(*envp); + if ((s=strchr(dup,'='))) *s='\0'; + for (allp=allowed;allp1000) + EXITLOG("Unable to clean environment for CVS pserver: %s",*envp); + unsetenv(dup); + goto retry; +ok:; + } + FUNCCHK(setenv,"PATH","/usr/bin",1); + FUNCCHK(chroot,"/home/short/pserver"); + FUNCCHK(chdir,"/"); + FUNCCHK(setgid,SETGID); + FUNCCHK(setuid,SETUID); + if (!getuid() || !geteuid() || !getgid() || !getegid()) + EXITLOG("Privileges NOT dropped!: uid=%d,euid=%d,gid=%d,egid=%d", + getuid(),geteuid(),getgid(),getegid()); + errno=0,execv(EXEC_PATHNAME,argv); + funcfail("execv"); +} diff --git a/src/unmime.c b/src/unmime.c new file mode 100644 index 0000000..1150f11 --- /dev/null +++ b/src/unmime.c @@ -0,0 +1,26 @@ +#include + +int fromhex(int a) +{ + return(a<='9'?a-'0':a-'A'+10); +} + +int main(int argc,char **argv) +{ +char c,seek; +int i; + if (argc>1&&*(argv[1])) seek=*(argv[1]); + for (;;) { + i=getchar(); + if (i==-1) break; + if (i!=seek) { putchar(i); continue; } + i=getchar(); + if (i=='\n') continue; + if (i==-1) break; + c=i; + i=getchar(); + if (i==-1) break; + putchar(fromhex(c)*0x10+fromhex(i)); + } + return(0); +} diff --git a/src/urlencode.c b/src/urlencode.c new file mode 100644 index 0000000..7a0497a --- /dev/null +++ b/src/urlencode.c @@ -0,0 +1,24 @@ +#include +#include +#include + +int main(void) +{ +int c; + while ((c=getchar())!=EOF) switch (c) { + case ' ': + putchar('+'); + break; + case '0' ... '9': + case 'A' ... 'Z': + case 'a' ... 'z': + case '!': case '*': case '\'': case '(': case ')': case ',': /* extra */ + case '$': case '-': case '_' : case '.': /* safe */ + putchar(c); + break; + default: + printf("%%%02X",c); + } + fflush(stdout); + return(0); +} -- 1.8.3.1