/* $Id: authserv.C,v 1.55 2001/08/27 03:09:20 ericp Exp $ */ /* * * Copyright (C) 1999 Michael Kaminsky (kaminsky@lcs.mit.edu) * Copyright (C) 1998, 1999 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #include "authserv.h" #include "parseopt.h" #include "rxx.h" sfssrp_parms srpglobal; ptr authsrvkey; sfs_servinfo servinfo; sfs_hash hostid; bool accepts_changes = true; bool accepts_reg = false; str sfsauthcachedir; // all in seconds int xfer_timeout = 60; int cache_expire = 7 * 24 * 60 * 60; int cache_recheck = 60; void unixaccept (ptr x, const authunix_parms *aup) { if (x) vNew authclient (x, aup); } ptr cloneaccept (int fd) { if (fd < 0) fatal ("EOF from authserv\n"); tcp_nodelay (fd); ref x = axprt_crypt::alloc (fd); vNew authclient (x); return x; } static void parseconfig (str cf) { parseargs pa (cf); bool errors = false; bool srpglobalset = false; int line; vec av; static rxx prefixrx ("^-prefix=([\\w/]+)$"); static rxx mapallrx ("^-mapall=(\\w+|[\\d,]+)$"); // XXX static rxx pubrx ("^-pub=(.+)$"); size_t ro_cnt = 0, reg_cnt = 0; while (pa.getline (&av, &line)) { if (!strcasecmp (av[0], "hostname")) { if (av.size () != 2) { errors = true; warn << cf << ":" << line << ": usage: hostname name\n"; } else if (servinfo.host.hostname != "") { errors = true; warn << cf << ":" << line << ": hostname already specified\n"; } else servinfo.host.hostname = av[1]; } else if (!strcasecmp (av[0], "keyfile")) { if (authsrvkey) { errors = true; warn << cf << ":" << line << ": keyfile already specified\n"; } else if (av.size () == 2) { str keyfile (av[1]); if (keyfile[0] != '/') keyfile = strbuf ("%s/", etc1dir) << keyfile; str key = file2wstr (keyfile); if (!key) { errors = true; warn << keyfile << ": " << strerror (errno) << "\n"; warn << cf << ":" << line << ": could not read keyfile\n"; } else if (!(authsrvkey = import_rabin_priv (key, NULL))) { errors = true; warn << cf << ":" << line << ": could not decode keyfile\n"; } } else { errors = true; warn << cf << ":" << line << ": usage: keyfile path\n"; } } else if (!strcasecmp (av[0], "userfile")) { bool r = false, reg = false; str pre, mapall, pp; if (av.size () >= 2) { for (size_t i = 1; i < av.size () - 1; i++ ) { prefixrx.search (av[i]); mapallrx.search (av[i]); pubrx.search (av[i]); if (!strcasecmp (av[i], "-ro")) { r = true; ro_cnt++; } else if (!strcasecmp (av[i], "-reg")) { reg = true; reg_cnt++; accepts_reg = true; accepts_changes = true; } else if (prefixrx.success ()) pre = prefixrx[1]; else if (mapallrx.success ()) mapall = mapallrx[1]; else if (pubrx.success ()) pp = pubrx[1]; else { errors = true; warn << cf << ":" << line << ": unknown userfile option: " << av[i] << "\n"; } } if (r && reg) { errors = true; warn << cf << ":" << line << ": conflicting userfile option"; } } else { /* not enough arguments */ errors = true; warn << cf << ":" << line << ": usage: must specify file"; } if (av[av.size () - 1][0] == '-') { errors = true; warn << cf << ":" << line << ": must specify non-option file"; } if (!errors) { str path = av[av.size () - 1]; if (path[0] != '/') path = strbuf ("%s/", etc1dir) << path; userfiles.push_back(userfile (path, pp, r, pre, mapall, reg)); } } else if (!strcasecmp (av[0], "srpfile")) { if (srpglobalset) { errors = true; warn << cf << ":" << line << ": srpfile already specified\n"; } else if (av.size () == 2) { str key = file2wstr (av[1]); if (!key) { errors = true; warn << av[1] << ": " << strerror (errno) << "\n"; warn << cf << ":" << line << ": could not read srpfile\n"; } else if (!import_srp_params (key, &srpglobal.N, &srpglobal.g)) { errors = true; warn << cf << ":" << line << ": could not decode srpfile\n"; } else srpglobalset = true; } else { errors = true; warn << cf << ":" << line << ": usage: srpfile path\n"; } } else if (!strcasecmp (av[0], "denyfile")) { if (denyfile) { errors = true; warn << cf << ":" << line << ": denyfile already specified\n"; } else if (av.size () == 2) { if (!file2str (av[1])) { errors = true; warn << av[1] << ": " << strerror (errno) << "\n"; warn << cf << ":" << line << ": could not read denyfile\n"; } else { denyfile = av[1]; if (denyfile[0] != '/') denyfile = strbuf ("%s/", etc1dir) << denyfile; } } else { errors = true; warn << cf << ":" << line << ": usage: denyfile path\n"; } } else if (!strcasecmp (av[0], "xfertimeout")) { if (!convertint (av[1], &xfer_timeout) || (xfer_timeout < 0)) { errors = true; warn << cf << ":" << line << ": usage: XferTimeout seconds\n"; } } else if (!strcasecmp (av[0], "cacheexpire")) { if (!convertint (av[1], &cache_expire) || (cache_expire < 0)) { errors = true; warn << cf << ":" << line << ": usage: CacheExpire