Mercurial > notdcc
view dcclib/parse_srvr_nm.c @ 0:c7f6b056b673
First import of vendor version
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 13:49:58 +0100 |
parents | |
children |
line wrap: on
line source
/* Distributed Checksum Clearinghouse * * Copyright (c) 2008 by Rhyolite Software, LLC * * This agreement is not applicable to any entity which sells anti-spam * solutions to others or provides an anti-spam solution as part of a * security solution sold to other entities, or to a private network * which employs the DCC or uses data provided by operation of the DCC * but does not provide corresponding data to other users. * * Permission to use, copy, modify, and distribute this software without * changes for any purpose with or without fee is hereby granted, provided * that the above copyright notice and this permission notice appear in all * copies and any distributed versions or copies are either unchanged * or not called anything similar to "DCC" or "Distributed Checksum * Clearinghouse". * * Parties not eligible to receive a license under this agreement can * obtain a commercial license to use DCC by contacting Rhyolite Software * at sales@rhyolite.com. * * A commercial license would be for Distributed Checksum and Reputation * Clearinghouse software. That software includes additional features. This * free license for Distributed ChecksumClearinghouse Software does not in any * way grant permision to use Distributed Checksum and Reputation Clearinghouse * software * * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * * Rhyolite Software DCC 1.3.103-1.47 $Revision$ */ #include "dcc_clnt.h" /* open a file of server names, ports, and so forth */ FILE * dcc_open_srvr_nm(DCC_EMSG emsg, const char *nm) { FILE *f; DCC_PATH path; f = fopen(nm, "r"); if (!f) { dcc_pemsg(EX_NOINPUT, emsg, "fopen(%s): %s", fnm2abs_err(path, nm), ERROR_STR()); return 0; } /* the file contains passwords, * so refuse to use it if everyone can read it */ if (!dcc_ck_private(emsg, 0, nm, fileno(f))) { fclose(f); return 0; } return f; } /* get "hostname,port" string from the start of a line */ const char * /* 0=bad, rest of line if ok */ dcc_parse_nm_port(DCC_EMSG emsg, const char *line0, u_int def_port, /* default or DCC_GET_PORT_INVALID */ char *hostname, /* put host name here */ u_int hostname_len, u_int16_t *portp, /* put port # in network byte order */ char *portname, /* put port name here */ u_int portname_len, const char *fnm, int lno) /* configuration file source */ { DCC_FNM_LNO_BUF fnm_buf; char buf[DCC_MAXDOMAINLEN+1+MAXPORTNAMELEN+1]; /* "name,#\0" */ const char *line; const char *pstr; u_int port; u_int hlen; /* get both parameters */ line = dcc_parse_word(emsg, buf, sizeof(buf), line0, "hostname,port", fnm, lno); if (!line) return 0; /* get the hostname and separate the port number */ pstr = strchr(buf, ','); if (!pstr) { if (def_port == DCC_GET_PORT_INVALID) { dcc_pemsg(EX_USAGE, emsg, "missing port in \"%s\"%s", buf, fnm_lno(&fnm_buf, fnm, lno)); return 0; } hlen = strlen(buf); pstr = "-"; } else { hlen = pstr++ - buf; } if (hostname_len) { memset(hostname, 0, hostname_len); if (hlen >= hostname_len) { dcc_pemsg(EX_NOHOST, emsg, "hostname \"%.16s...\" too long%s", buf, fnm_lno(&fnm_buf, fnm, lno)); return 0; } if (hlen) memcpy(hostname, buf, hlen); } if (portname_len) { memset(portname, 0, portname_len); hlen = strlen(pstr); if (hlen >= portname_len) hlen = portname_len-1; if (hlen) memcpy(portname, pstr, hlen); } /* get the port number */ port = dcc_get_port(emsg, pstr, def_port, fnm, lno); if (port == DCC_GET_PORT_INVALID) return 0; if (portp) *portp = port; return line; } /* parse a line of the following form * hostname[,port-#] [RTT+adj] [Greylist] [client-ID [password]] * The port-# can be "-" to specifiy the default DCC server port. * If both the client-ID and the password are absent, then the anonymous * client-ID is used. * A null string is assumed if the password is missing. */ int /* 1=parsed, 0=bad, -1=unknown name */ dcc_parse_srvr_nm(DCC_EMSG emsg, DCC_SRVR_NM *nmp, /* build this entry */ u_char *pgrey, /* 1=for greylisting */ const char *line, /* from this string */ const char *fnm, int lno) /* that came from here */ { DCC_FNM_LNO_BUF fnm_buf; char id_buf[12]; char port_buf[3]; char *p; long l; memset(nmp, 0, sizeof(DCC_SRVR_NM)); line = dcc_parse_nm_port(emsg, line, DCC_GREY2PORT(pgrey && *pgrey), nmp->hostname, sizeof(nmp->hostname), &nmp->port, port_buf, sizeof(port_buf), fnm, lno); if (!line) return 0; for (;;) { /* look for greylist flag */ if (!CLITCMP(line, "greylist") && (line[LITZ("greylist")] == '\0' || line[LITZ("greylist")] == ' ' || line[LITZ("greylist")] == '\t')) { line += LITZ("greylist")+strspn(line+LITZ("greylist"), DCC_WHITESPACE); if (pgrey) *pgrey = 1; if (port_buf[0] == '\0' || !strcmp(port_buf, "-")) nmp->port = htons(DCC_GREY_PORT); continue; } /* look for optional RTT adjustment */ if (CLITCMP(line, "rtt")) break; line += LITZ("rtt")+strspn(line+LITZ("rtt"), DCC_WHITESPACE); l = strtol(line, &p, 10); if (p != line) { int wsp = strspn(p, DCC_WHITESPACE); if (!CLITCMP(p+wsp, "ms")) p += wsp+LITZ("ms"); } if (p == line || (*p != '\0' && *p != ' ' && *p != '\t')) { dcc_pemsg(EX_DATAERR, emsg, "invalid RTT adjustment%s", fnm_lno(&fnm_buf, fnm, lno)); return 0; } if (l < -DCC_RTT_ADJ_MAX/1000) { l = -DCC_RTT_ADJ_MAX/1000; } else if (l > DCC_RTT_ADJ_MAX/1000) { l = DCC_RTT_ADJ_MAX/1000; } nmp->rtt_adj = l*1000; line = p+strspn(p, DCC_WHITESPACE); } /* get the client-ID */ line = dcc_parse_word(emsg, id_buf, sizeof(id_buf), line, "client-ID", fnm, lno); if (!line) return 0; if (id_buf[0] == '\0') { nmp->clnt_id = DCC_ID_ANON; } else { nmp->clnt_id = dcc_get_id(emsg, id_buf, fnm, lno); if (nmp->clnt_id == DCC_ID_INVALID) return 0; if (nmp->clnt_id < DCC_CLNT_ID_MIN && nmp->clnt_id != DCC_ID_ANON) { dcc_pemsg(EX_DATAERR, emsg, "server-ID %d is not a client-ID", nmp->clnt_id); return 0; } } /* allow null password only for anonymous clients * clients of greylist servers cannot be anonymous */ if (nmp->clnt_id == DCC_ID_ANON) { if (*line != '\0') { dcc_pemsg(EX_DATAERR, emsg, "password invalid for %s" " with anonymous client-ID%s", nmp->hostname, fnm_lno(&fnm_buf, fnm, lno)); return 0; } return 1; } if (*line == '\0') { dcc_pemsg(EX_DATAERR, emsg, "invalid null password for client-ID %d for %s%s", nmp->clnt_id, nmp->hostname, fnm_lno(&fnm_buf, fnm, lno)); return 0; } line = parse_passwd(emsg, nmp->passwd, line, "passwd", fnm, lno); if (!line) return 0; if (nmp->passwd[0] == '\0' || *line != '\0') { dcc_pemsg(EX_DATAERR, emsg, "invalid password server %s, client-ID %d%s", nmp->hostname, nmp->clnt_id, fnm_lno(&fnm_buf, fnm, lno)); return 0; } return 1; }