repo: games action: commit revision: path_from: revision_from: 464edcfc9df861311e6df40e1a545d92b1823c8b: path_to: revision_to:
commit 464edcfc9df861311e6df40e1a545d92b1823c8b Author: epochDate: Sat Apr 19 07:32:41 2025 +0000 fix overflow through TTY env var in shoot. rewrite make-pond to do stuff itself. diff --git a/duck/Makefile b/duck/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4a42a19f33185579c55b5176fa298b9365951261 --- /dev/null +++ b/duck/Makefile @@ -0,0 +1,13 @@ +PREFIX:=/usr/local + +CFLAGS=-Wall -pedantic + +all: shoot make-pond + +install: all + install -t $(PREFIX)/bin shoot + chown duck:duck $(PREFIX)/bin/shoot + chmod u+s,g+s $(PREFIX)/bin/shoot + install -t $(PREFIX)/bin make-pond + chown root:duck $(PREFIX)/bin/make-pond + chmod u+s,o= $(PREFIX)/bin/make-pond diff --git a/duck/make-pond.c b/duck/make-pond.c new file mode 100644 index 0000000000000000000000000000000000000000..bf30f8102651990aec7eef67c6f38ab1a0151c08 --- /dev/null +++ b/duck/make-pond.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include + +// the script it runs is just mknod and chown. that should be easy for me to do. + +// /usr/bin/mknod /dev/pond c 4 0 +// /usr/bin/chown duck:duck /dev/pond + +int main(int argc,char *argv[]) { + char *pathname="/dev/pond"; + mknod(pathname,S_IFCHR|0644,makedev(4,0)); + struct passwd *pwd=getpwnam("duck"); + if(!pwd) { + syslog(LOG_ERR,"duck user is missing!"); + } + chown(pathname,pwd->pw_uid,pwd->pw_gid); + /*char *name[2]; + name[0]="/etc/duck/MAKE_POND.sh"; + name[1]=0; + execv(name[0],name); + perror("execve");*/ + return 1; +} diff --git a/duck/shoot.c b/duck/shoot.c new file mode 100644 index 0000000000000000000000000000000000000000..d6bca594e1ae0f8cee2794d6383cb7ddfaa9c5e7 --- /dev/null +++ b/duck/shoot.c @@ -0,0 +1,98 @@ +#include +#include //strchr +#include +#include +#include +#include +#include +#include + +int main(int argc,char *argv[]) { + FILE *fp; + int delta; + int l; + int duck_count=0; + char filename[PATH_MAX]; + char tty[PATH_MAX]; + //char remote_addr[PATH_MAX]=""; + char identifier[PATH_MAX]; + char duck[256];//long enough + char tmp[256]; + char *user; + time_t t=time(0); +// struct passwd *pwd=getpwuid(getuid()); +// printf("%s\n",pwd->pw_name); +// what we need to do... +// if there exists a duck in the wild + user=getenv("USER"); + if(!user) { + struct passwd *pwd=getpwuid(getuid()); + if(!pwd) { + fprintf(stderr,"shoot: USER env var is unset, and I can't find a username for your uid. who the fuck are you?\n"); + return 5; + } + user=pwd->pw_name; + } + + if((l=readlink("/proc/self/fd/0",tty,PATH_MAX)) == -1) { + fprintf(stderr,"failed to get your terminal, but you still have the duck.\n"); + return 3; + } else { + tty[l]=0; + } + if(!strcmp(tty,"/dev/null") && getenv("TTY")) { //only allow env override if /dev/null + snprintf(tty,PATH_MAX,"%s",getenv("TTY")); + } + if(!strncmp("/dev/",tty,5)) { + memmove(tty,tty+5,strlen(tty)); + } + + if(strcmp(tty,"null")) { + if(getenv("REMOTE_ADDR")) { //remote users + snprintf(identifier,PATH_MAX,"talk://%s@%s/%s",user,getenv("REMOTE_ADDR"),tty); + } else { //local users in a tty + snprintf(identifier,PATH_MAX,"talk://%s@%s/%s",user,"batou",tty); + } + } else { //IRC users + snprintf(identifier,PATH_MAX,"IRC user %s",user); + } + + if((fp=fopen("/var/cache/duck/duck_time","r")) == NULL) { + fprintf(stderr,"shoot: %s, there is no duck to shoot\n",identifier); + return 1; + } + l=fread(duck,sizeof(char),sizeof(duck),fp);//it'll actually read less than duck. +// fprintf(stderr,"read duck: '%s'\n",duck); + fclose(fp); + unlink("/var/cache/duck/duck_time"); + snprintf(filename,PATH_MAX,"/var/items/duck/%s",user);// user can be injected with USER= and stdin being null. + if((fp=fopen(filename,"a")) == NULL) { + fprintf(stderr,"shoot: unable to put the duck in your inventory (%s)\n",filename); + return 2; + } + if(strchr(duck,'\n')) *strchr(duck,'\n')=0; + fprintf(fp,"%s %ld\n",duck,t); + fclose(fp); + duck_count=0; + fp=fopen(filename,"r");//assume it'll work. we made it here with 'a' earlier + for(duck_count=0;fgets(tmp,sizeof(tmp)-1,fp);duck_count++); + fclose(fp); + printf("%s shot the duck\n",user); + + if((fp=fopen("/home/segfault/files/default","a")) == NULL) { + fprintf(stderr,"shoot: couldn't open the file for telling IRC about your kill\n"); + return 4; + } + + delta=time(0) - atoi(duck); + + if(strcmp(tty,"null")) { + fprintf(fp,"%s shot the duck from their terminal %s after %d seconds and now has %d ducks\n",user,tty,delta,duck_count); + fprintf(stderr,"%s shot the duck from their terminal %s after %d seconds and now has %d ducks\n",user,tty,delta,duck_count); + } else { + fprintf(fp,"%s shot the duck after %d seconds and now has %d ducks\n",user,delta,duck_count); + fprintf(stderr,"%s shot the duck after %d seconds and now has %d ducks\n",user,delta,duck_count); + } + fclose(fp); + return 0; +}
-----END OF PAGE-----