/* * OpenFWTK authentication database manager client * Copyright (c) 2003-2007, OpenFWTK Development Group * All rights reserved. See LICENSE. * (C) 2003 ADVA Research Center * (C) 2003 Alexei Kravchuk * (C) 2003 ArkanoiD, portability modifications */ #include #include #include #include #include #include "firewall.h" #include "firewall2.h" #include "fwfunc.h" #include "auth.h" #include #include static char *moduleId ATTR_UNUSED = "$Id: authmgr.c,v 1.7 2007/09/10 02:49:12 arkenoi Exp $"; extern char *getpassword(); void lostconn(); #define FLG_LOCAL 1 typedef struct { char *cnam; int flg; char *help; int (*cfun)(); } Cmd; static int logged_in = 0; static int do_quit(); static int do_login(); static int do_passwd(); static int do_help(); static int do_multiline(); static Cmd *find_command(); static Cmd ctab[] = { {"login", FLG_LOCAL, "login", do_login }, {"adduser", 0, "adduser username [longname]", 0 }, {"deluser", 0, "deluser username", 0 }, {"display", FLG_LOCAL, "display username", do_multiline }, {"list", FLG_LOCAL, "list [group]", do_multiline }, {"enable", 0, "enable username", 0 }, {"disable", 0, "disable username", 0 }, {"addgroup", 0, "addgroup username group", 0 }, {"revoke", 0, "revoke username group", 0 }, {"rename", 0, "rename user newname [longname]", 0 }, {"proto", 0, "proto username auth-proto", 0 }, {"wiz", 0, "wiz username", 0 }, {"unwiz", 0, "unwiz username", 0 }, {"password", FLG_LOCAL, "password [user [pass]]", do_passwd }, {"quit", FLG_LOCAL, "quit", do_quit }, {"exit", FLG_LOCAL, "exit", do_quit }, {"?", FLG_LOCAL, "?", do_help }, {"help", FLG_LOCAL, "help", do_help }, {0, 0, 0, 0 } }; static int stin; /* terminal is standard input */ static Cfg *confp; int main(ac,av) int ac; char *av[]; { Cmd *cp; char buf[MAX_STR]; char *xa[MAX_ARG]; char xb[MAX_STR]; int xc; char *p; #ifndef LOG_NDELAY openlog("authmgr",LOG_PID); #else openlog("authmgr",LOG_PID|LOG_NDELAY,LOG_USER); #endif confp = cfg_read("authmgr"); sotimeout(proxy_timeout); /* this uses confp to get server/port numbers */ if(auth_open(confp)) { fprintf(stderr,"Cannot open auth service\n"); exit(1); } if(auth_recv(buf,sizeof(buf))) lostconn(); if(strncmp(buf,"Authsrv ready",13)) { fprintf(stderr,"Cannot connect to server, response: %s\n",buf); exit(1); } fprintf(stderr,"Connected to server\n"); stin = isatty(fileno(stdin)); while(1) { if(stin) { fprintf(stderr,"authmgr-> "); fflush(stderr); } if(fgets(buf,sizeof(buf),stdin) == (char *)0) break; if((p = rindex(buf,'\n')) != (char *)0) *p = '\0'; xc = enargv(buf,xa,sizeof(xa)/sizeof(char *),xb,sizeof(xb)); if(xc < 0) { fprintf(stderr,"Too many command parameters.\n"); continue; } if(xc == 0) continue; cp = find_command(ctab, xa[0]); if(!cp) { printf("Command \"%s\" is ambiguous.\n",xa[0]); continue; } if(cp->cnam == (char *)0) { printf("Command \"%s\" unrecognized.\n",xa[0]); continue; } if(cp->flg & FLG_LOCAL) { (*cp->cfun)(xc,xa,buf); continue; } if(auth_send(buf)) lostconn(); if(auth_recv(xb,sizeof(xb))) lostconn(); printf("%s\n",xb); } auth_close(); exit(0); } static Cmd * find_command (tab, cmd) Cmd * tab; char *cmd; { Cmd *cp, *match; int nl; nl = strlen(cmd); match = 0; for (cp = tab; cp->cnam != (char *)0; cp++) { if (!strcmp(cp->cnam, cmd)) return cp; else if (!strncasecmp(cp->cnam, cmd, nl)) { if (match && cp->cfun != match->cfun) return 0; /* ambiguous */ match = cp; } } return match ? match : cp; } static int do_quit() { auth_close(); exit(0); } static int do_help() { Cmd *cp; printf("Command List:\n"); printf("(Commands may be invoked with unique leading abbreviation)\n"); for(cp = ctab; cp->cnam != (char *)0; cp++) printf(" %s\n",cp->help); return(0); } static int do_login(ac,av,original) int ac; char *av[]; char *original; { char usrbuf[MAX_STR]; char rbuf[MAX_STR]; char pbuf[MAX_STR]; char myhostname[MAX_HOSTNAME]; struct hostent *hp; char *p; logged_in = 0; if(ac > 1) strlcpy(usrbuf,av[1], sizeof(usrbuf)); else { fprintf(stderr,"Username: "); fflush(stderr); if(fgets(usrbuf,sizeof(usrbuf),stdin) == (char *)0) do_quit(); } strtrm(usrbuf); if(gethostname(myhostname,sizeof(myhostname))) strlcpy(myhostname,"amnesiac",sizeof(myhostname)); else if ((hp = gethostbyname(myhostname)) != (struct hostent *)0) strlcpy(myhostname,hp->h_name,sizeof(myhostname)); snprintf(rbuf,sizeof(rbuf),"authorize %.32s 'authmgr %.128s/127.0.0.1'",usrbuf,myhostname); if(auth_send(rbuf)) lostconn(); while (1) { if(auth_recv(rbuf,sizeof(rbuf))) lostconn(); if(!strncmp(rbuf,"ok",2)) { break; } if(!strncmp(rbuf,"display ",8)) { fprintf(stderr,"%s",&rbuf[8]); strlcpy(rbuf,"response dummy",sizeof(rbuf)); if(auth_send(rbuf)) lostconn(); continue; } if(!strncmp(rbuf,"challenge ",10)) { char *q; fprintf(stderr,"%s",&rbuf[10]); fflush(stderr); if(fgets(pbuf,sizeof(pbuf),stdin) == (char *)0) pbuf[0] = '\0'; p = pbuf; if((q = rindex(p,'\n')) != (char *)0) *q = '\0'; } else if(!strncmp(rbuf,"chalnecho ",10)) { p = getpassword(&rbuf[10]); } else if(!strncmp(rbuf,"password",8)) { p = getpassword("Password: "); } else { fprintf(stderr,"%s",rbuf); return(1); } if(p == (char *)0) return(1); snprintf(rbuf,sizeof(rbuf),"response '%s'", p); if(auth_send(rbuf)) lostconn(); } if(stin) { if(rbuf[2] != '\0') fprintf(stderr,"Logged in %s\n",&rbuf[2]); else fprintf(stderr,"Logged in\n"); } logged_in = 1; return(0); } static int do_passwd(ac,av,original) int ac; char *av[]; char *original; { char rbuf[MAX_STR]; char *p; char *pwp1; char *pwp2; char pbuf[AUTH_PWSIZ]; char pxuf1[MAX_STR]; char pxuf2[MAX_STR]; if(!logged_in) { fprintf(stderr,"Log in, first\n"); return(0); } pwp1 = "Password:"; pwp2 = "Repeat Password:"; if(ac > 1) { snprintf(pxuf1,sizeof(pxuf1),"Password for %.24s:",av[1]); snprintf(pxuf2,sizeof(pxuf2),"Repeat Password for %.24s:",av[1]); pwp1 = pxuf1; pwp2 = pxuf2; } if(ac > 2) strlcpy(pbuf,av[2],sizeof(pbuf)); else { if((p = getpassword(pwp1)) == (char *)0) { fprintf(stderr,"Password not changed\n"); return(0); } strlcpy(pbuf,p, sizeof(pbuf)); if((p = getpassword(pwp2)) == (char *)0) { fprintf(stderr,"Password not changed\n"); return(0); } if(strcmp(p,pbuf)) { fprintf(stderr,"Passwords differ - not changed\n"); return(0); } } if(index(pbuf,'"') != (char *)0 || index(pbuf,'\'') != (char *)0) { fprintf(stderr,"Passwords cannot contain quotes - not changed\n"); return(0); } if(ac > 1) snprintf(rbuf,sizeof(rbuf),"password %.24s \"%.50s\"\n",av[1],pbuf); else snprintf(rbuf,sizeof(rbuf),"password \"%.50s\"\n",pbuf); if(auth_send(rbuf)) lostconn(); if(auth_recv(rbuf,sizeof(rbuf))) lostconn(); fprintf(stderr,"%s\n",rbuf); return(0); } /* send a whole line over intact and expect back a multiline response */ static int do_multiline(ac,av,original) int ac; char *av[]; char *original; { char rbuf[MAX_STR]; if(auth_send(original)) lostconn(); while(1) { if(auth_recv(rbuf,sizeof(rbuf))) lostconn(); if(rbuf[0] == '.' && rbuf[1] == '\0') break; if(rbuf[0] == '.') fprintf(stderr,"%s\n",&rbuf[1]); else fprintf(stderr,"%s\n",rbuf); } return(0); } void lostconn() { fprintf(stderr,"Lost connection to auth service\n"); auth_close(); exit(1); }