Exemplo n.º 1
0
/*
 * for some weird reason T2queryall() returns share names
 * in lower case so we have to do an extra test against
 * our share table to validate filename case.
 *
 * on top of this here (snell & Wilcox) most of our
 * redirections point to a share of the same name,
 * but some do not, thus the tail of the filename
 * returned by T2queryall() is not the same as
 * the name we wanted.
 *
 * We work around this by not validating the names
 * or files which resolve to share names as they must
 * be correct, having been enforced in the dfs layer.
 */
static int
validfile(char *found, char *want, char *winpath, Share *sp)
{
	char *share;

	if(strcmp(want, "..") == 0)
		return 1;
	if(strcmp(winpath, "/") == 0){
		share = trimshare(sp->name);
		if(cistrcmp(want, share) == 0)
			return strcmp(want, share) == 0;
		/*
		 * OK, a DFS redirection points us from a directory XXX
		 * to a share named YYY.  There is no case checking we can
		 * do so we allow either case - it's all we can do.
		 */
		return 1;
	}
	if(cistrcmp(found, want) != 0)
		return 0;
	if(!Checkcase)
		return 1;
	if(strcmp(found, want) == 0)
		return 1;
	return 0;
}
Exemplo n.º 2
0
void
msgheadline(Biobuf *bin, int n, Biobuf *bout)
{
	char *p, *q;
	char *date;
	char *from;
	char *subject;

	date = nil;
	from = nil;
	subject = nil;
	while(p = Brdline(bin, '\n')){
		p[Blinelen(bin)-1] = '\0';
		if((q = strchr(p, ':')) == nil)
			continue;
		*q++ = '\0';
		if(cistrcmp(p, "from")==0)
			from = fixfrom(skipwhite(q));
		else if(cistrcmp(p, "subject")==0)
			subject = estrdup(skipwhite(q));
		else if(cistrcmp(p, "date")==0)
			date = fixdate(skipwhite(q));
	}

	Bprint(bout, "%d/\t%s", n, from ? from : "");
	if(date)
		Bprint(bout, "\t%s", date);
	if(subject)
		Bprint(bout, "\n\t%s", subject);
	Bprint(bout, "\n");

	free(date);
	free(from);
	free(subject);
}
Exemplo n.º 3
0
/*
 *  true if a name is in our area
 */
Area*
inmyarea(char *name)
{
	int len;
	Area *s, *d;

	len = strlen(name);
	for(s = owned; s; s = s->next){
		if(s->len > len)
			continue;
		if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0)
			if(len == s->len || name[len - s->len - 1] == '.')
				break;
	}
	if(s == 0)
		return 0;

	for(d = delegated; d; d = d->next){
		if(d->len > len)
			continue;
		if(cistrcmp(d->soarr->owner->name, name + len - d->len) == 0)
			if(len == d->len || name[len - d->len - 1] == '.')
				return 0;
	}

	return s;
}
Exemplo n.º 4
0
int
hcheckcontent(HContent *me, HContent *oks, char *list, int size)
{
	HContent *ok;

	if(oks == nil || me == nil)
		return 1;
	for(ok = oks; ok != nil; ok = ok->next){
		if((cistrcmp(ok->generic, me->generic) == 0 || strcmp(ok->generic, "*") == 0)
		&& (me->specific == nil || cistrcmp(ok->specific, me->specific) == 0 || strcmp(ok->specific, "*") == 0)){
			if(ok->mxb > 0 && size > ok->mxb)
				return 0;
			return 1;
		}
	}

	USED(list);
	if(0){
		fprint(2, "list: %s/%s not found\n", me->generic, me->specific);
		for(; oks != nil; oks = oks->next){
			if(oks->specific)
				fprint(2, "\t%s/%s\n", oks->generic, oks->specific);
			else
				fprint(2, "\t%s\n", oks->generic);
		}
	}
	return 0;
}
Exemplo n.º 5
0
/*
 * genaudiovolwrite modifies the buffer that gets passed to it. this
 * is ok as long as it is called from inside Audio.volwrite() because
 * audiowrite() copies the data to Audiochan.buf[] and inserts a
 * terminating \0 byte before calling Audio.volwrite().
 */
long
genaudiovolwrite(Audio *adev, void *a, long n, vlong,
	Volume *vol, int (*volset)(Audio *, int, int *), ulong caps)
{
	int ntok, i, j, v[2];
	char *p, *e, *x, *tok[4];

	p = a;
	e = p + n;

	for(;p < e; p = x){
		if(x = strchr(p, '\n'))
			*x++ = 0;
		else
			x = e;
		ntok = tokenize(p, tok, 4);
		if(ntok <= 0)
			continue;
		if(ntok == 1){
			tok[1] = tok[0];
			tok[0] = "master";
			ntok = 2;
		}
		for(i = 0; vol[i].name != 0; i++){
			if(vol[i].cap && (vol[i].cap & caps) == 0)
				continue;
			if(cistrcmp(vol[i].name, tok[0]))
				continue;
	
			if((ntok>2) && (!cistrcmp(tok[1], "out") || !cistrcmp(tok[1], "in")))
				memmove(tok+1, tok+2, --ntok);

			v[0] = 0;
			v[1] = 0;
			if(ntok > 1)
				v[0] = v[1] = atoi(tok[1]);
			if(ntok > 2)
				v[1] = atoi(tok[2]);
			if(vol[i].type == Absolute)
				(*volset)(adev, i, v);
			else {
				for(j=0; j<2; j++){
					v[j] = (50+(v[j]*vol[i].range))/100;
					if(v[j] < 0)
						v[j] = 0;
					if(v[j] > vol[i].range)
						v[j] = vol[i].range;
				}
				(*volset)(adev, i, v);
			}
			break;
		}
		if(vol[i].name == nil)
			error(Evolume);
	}

	return n;
}
Exemplo n.º 6
0
static int
incountries(char *s, Country *cp)
{
	for(; cp->code != 0; cp++)
		if(cistrcmp(s, cp->code) == 0
		|| cistrcmp(s, cp->name) == 0)
			return 1;
	return 0;
}
Exemplo n.º 7
0
SmbService *
smbservicefind(SmbSession *s, char *uncpath, char *servicetype,
	       uint8_t *errclassp,
	       uint16_t *errorp)
{
	char *p, *q;
	if ((uncpath[0] == '/' && uncpath[1] == '/')
	||  (uncpath[0] == '\\' && uncpath[1] == '\\')) {
		/* check that the server name matches mine */
		p = uncpath + 2;
		q = strchr(p, uncpath[0]);
		if (q == nil)
			goto bad;
		*q++ = 0;
//		if (cistrcmp(p, smbglobals.serverinfo.name) != 0)
//			goto bad;
	}
	else
		q = uncpath + 1;
	if (strcmp(servicetype, "?????") == 0 && strcmp(q, "IPC$") == 0)
		return &ipc;
	if ((strcmp(servicetype, "?????") == 0 || strcmp(servicetype, "A:") == 0)) {
		SmbService *serv;
		if (cistrcmp(q, local.name) == 0)
			return &local;
		/* try the session specific list */
		for (serv = s->serv; serv; serv = serv->next)
			if (cistrcmp(q, serv->name) == 0)
				return serv;
		/* exec "9fs q" in case it invents /n/q */
		for (p = q; *p; p++)
			if (*p >= 'A' && *p <= 'Z')
				*p = tolower(*p);
		if (run9fs(q) >= 0) {
			serv = smbemallocz(sizeof(*serv), 1);
			serv->name = smbestrdup(q);
			serv->type = smbestrdup("A:");
			serv->stype = STYPE_DISKTREE;
			smbstringprint(&serv->remark, "9fs %s", q);
			smbstringprint(&serv->path, "/n/%s", q);
			serv->next = s->serv;
			s->serv = serv;
			return serv;
		}
	}
bad:
	*errclassp = ERRDOS;
	*errorp = ERRbadpath;
	return nil;
}
Exemplo n.º 8
0
static int
casestrcmp(int isplan9, char *a, char *b)
{
	if(isplan9)
		return strcmp(a, b);
	return cistrcmp(a, b);
}
Exemplo n.º 9
0
int find (char *word, keytab_entry keytab[], int numkeys)     

/*
  Find looks up a word in a keyword table. It uses binary search and is
  insensitive to case.

  Parameters:
    word:	pointer to the word to be looked up
    keytab:	pointer to the array of keywords
    numkeys:	length of the keyword table

  Return value: 
    Normal     token number associated with the keyword
    Otherwise  -1 if the keyword cannot be found
	       
*/

{ int high,low,mid,place ;

  low = 0 ;
  high = numkeys-1 ;
  while (low <= high) 
  { mid = (high+low)/2 ;
    place = cistrcmp(word,keytab[mid].keyword) ;
    switch (place)
    { case -1:
        high = mid-1 ;
        break ;
      case 0:
	return (keytab[mid].token) ;
      case 1:
	low = mid+1 ;
	break ; } }
  return (-1) ; }
Exemplo n.º 10
0
static SmbProcessResult
netserverenum2(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
{
	uint16_t level, rbl;
	char *domain;
	uint32_t servertype;
	SmbProcessResult pr;
	SmbServerInfo *si[3];
	SmbServerInfo domainsi;
	int entries;

	/* WrLehDz
	 * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ENTCOUNT pcEntriesRead, ushort *pcTotalAvail,
	 * ulong fServerType, char *pszDomain
	*/

	if (!smbbuffergets(inparam, &level)
		|| !smbbuffergets(inparam, &rbl)
		|| !smbbuffergetl(inparam, &servertype)
		|| !smbbuffergetstr(inparam, 0, &domain)) {
	fmtfail:
		pr = SmbProcessResultFormat;
		goto done;
	}
	
	smblogprintif(smbglobals.log.rap2, "netserverenum2(%lud, %lud, 0x%.8lux, %s)\n",
		level, smbbufferwritespace(outdata), servertype, domain);

	if (level > 1)
		goto fmtfail;

	if (servertype == 0xffffffff)
		servertype &= ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY);

	if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0 && (servertype & SV_TYPE_DOMAIN_ENUM) == 0) 
		servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);

	entries = 0;

	if ((servertype & SV_TYPE_SERVER) != 0
		&& (domain[0] == 0 || cistrcmp(domain, smbglobals.primarydomain) == 0)) {
		si[entries++] = &smbglobals.serverinfo;
	}

	if ((servertype & SV_TYPE_DOMAIN_ENUM) != 0) {
		/* there's only one that I know about */
		memset(&domainsi, 0, sizeof(domainsi));
		domainsi.name = smbglobals.primarydomain;
		domainsi.stype = SV_TYPE_DOMAIN_ENUM;
		si[entries++] = &domainsi;
	}
	si[entries] = 0;

	pr = thingfill(outparam, outdata, &serverinfo, level, si);
			
done:
	free(domain);
	return pr;
}
Exemplo n.º 11
0
static int
indomains(char *s, char **dp)
{
	for(; *dp != nil; dp++)
		if(cistrcmp(s, *dp) == 0)
			return 1;

	return 0;
}
Exemplo n.º 12
0
int
smbslut(SmbSlut *s, char *pat)
{
	while (s->name) {
		if (cistrcmp(s->name, pat) == 0)
			return s->val;
		s++;
	}
	return -1;
}
Exemplo n.º 13
0
Arquivo: date.c Projeto: keedon/harvey
static int
dateindex(char *d, char **tab, int n)
{
	int i;

	for(i = 0; i < n; i++)
		if(cistrcmp(d, tab[i]) == 0)
			return i;
	return -1;
}
Exemplo n.º 14
0
static int
getmon(char *s)
{
	int i;

	for(i=0; i<nelem(months); i++)
		if(cistrcmp(months[i], s) == 0)
			return i;
	return -1;
}
Exemplo n.º 15
0
char*
getconf(char *name)
{
	int i;

	for(i = 0; i < nconf; i++)
		if(cistrcmp(confname[i], name) == 0)
			return confval[i];
	return 0;
}
Exemplo n.º 16
0
int
whichheader(char *h)
{
	int i;

	for(i=0; headers[i]!=nil; i++)
		if(cistrcmp(h, headers[i]) == 0)
			return i;
	return -1;
}
Exemplo n.º 17
0
static int
findconf(char *name)
{
	int i;

	for(i = 0; i < nconf; i++)
		if(cistrcmp(confname[i], name) == 0)
			return i;
	return -1;
}
Exemplo n.º 18
0
Arquivo: main.c Projeto: 99years/plan9
char*
getconf(char *name)
{
	int i;

	for(i = 0; i < nconf; i++)
		if(cistrcmp(name, plan9ini[i].name) == 0)
			return plan9ini[i].val;
	return nil;
}
Exemplo n.º 19
0
static int
s**t(S**t *s, char *pat)
{
	while (s->name) {
		if (cistrcmp(s->name, pat) == 0)
			return s->val;
		s++;
	}
	Bprint(&bout, "%s unrecognised\n", pat);
	return -1;	
}
Exemplo n.º 20
0
char *
getconf(char *name)
{
	int n;

	for(n = 0; n < nconf; n++)
		if(cistrcmp(confname[n], name) == 0) {
			return confval[n];
		}
	return 0;
}
Exemplo n.º 21
0
/*
 * copy the contents of one mailbox to another
 * either truncates or removes the source box if it succeeds.
 */
int
copyBox(char *from, char *to, int doremove)
{
	MbLock *ml;
	char *fimp, *timp;
	int ffd, tfd, ok;

	if(cistrcmp(from, "inbox") == 0)
		from = "mbox";

	ml = mbLock();
	if(ml == nil)
		return 0;
	ffd = openLocked(mboxDir, from, OREAD);
	if(ffd < 0){
		mbUnlock(ml);
		return 0;
	}
	tfd = createBox(to, 0);
	if(tfd < 0){
		mbUnlock(ml);
		close(ffd);
		return 0;
	}

	ok = copyData(ffd, tfd, ml);
	close(ffd);
	close(tfd);
	if(!ok){
		mbUnlock(ml);
		return 0;
	}

	fimp = impName(from);
	timp = impName(to);
	if(fimp != nil && timp != nil){
		ffd = cdOpen(mboxDir, fimp, OREAD);
		if(ffd >= 0){
			tfd = cdCreate(mboxDir, timp, OWRITE, 0664);
			if(tfd >= 0){
				copyData(ffd, tfd, ml);
				close(tfd);
			}
			close(ffd);
		}
	}
	cdRemove(mboxDir, fimp);
	if(doremove)
		cdRemove(mboxDir, from);
	else
		close(cdOpen(mboxDir, from, OWRITE|OTRUNC));
	mbUnlock(ml);
	return 1;
}
Exemplo n.º 22
0
static void
mga4xxblank(VGAscr *scr, int blank)
{
	char *cp;
	uchar *mga;
	uchar seq1, crtcext1;
	
	/* blank = 0 -> turn screen on */
	/* blank = 1 -> turn screen off */

	if(scr->mmio == 0)
		return;
	mga = (uchar*)scr->mmio;	

	if(blank == 0){
		seq1 = 0x00;
		crtcext1 = 0x00;
	} else {
		seq1 = 0x20;
		crtcext1 = 0x10;			/* Default value ... : standby */
		cp = getconf("*dpms");
		if(cp){
			if(cistrcmp(cp, "standby") == 0)
				crtcext1 = 0x10;
			else if(cistrcmp(cp, "suspend") == 0)
				crtcext1 = 0x20;
			else if(cistrcmp(cp, "off") == 0)
				crtcext1 = 0x30;
		}
	}

	*(mga + 0x1fc4) = 1;
	seq1 |= *(mga + 0x1fc5) & ~0x20;
	*(mga + 0x1fc5) = seq1;

	*(mga + 0x1fde) = 1;
	crtcext1 |= *(mga + 0x1fdf) & ~0x30;
	*(mga + 0x1fdf) = crtcext1;
}
Exemplo n.º 23
0
Arquivo: main.c Projeto: phylolvb/lvb
int main(void)
{
    /* strings that are the same, considered case-insensitively */
    static char s1[] = "`1234567890-=!\"$%^&*("
     ")_+qwertyuiopasdfghjklzxcvbnm[]{};'#:@~,./<>? \t\n\r";
    static char s2[] = "`1234567890-=!\"$%^&*("
     ")_+QWERTYUIOPASDFGHJKLZXCVBNM[]{};'#:@~,./<>? \t\n\r";

    /* string that is almost the same but actually different */
    static char s3[] = "`1234567890-=!\"$%^&*("
     ")_+QWERTYUIOPASDFGHJKLZXCVBNN[]{};'#:@~,./<>? \t\n\r";

    lvb_initialize();

    lvb_assert(cistrcmp(s1, s1) == 0);
    lvb_assert(cistrcmp(s3 + 5, s3) != 0);
    lvb_assert(cistrcmp(s1, s2) == 0);
    lvb_assert(cistrcmp(s2, s3) != 0);

    printf("test passed\n");
    return 0;
}
Exemplo n.º 24
0
Arquivo: dfs.c Projeto: Requaos/harvey
int
mapshare(char *path, Share **osp)
{
	int i;
	Share *sp;
	Dfscache *cp;
	char *s, *try;
	char *tail[] = { "", "$" };

	if((cp = lookup(path, nil)) == nil)
		return 0;

	for(sp = Shares; sp < Shares+Nshares; sp++){
		s = trimshare(sp->name);
		if(cistrcmp(cp->share, s) != 0)
			continue;
		if(Checkcase && strcmp(cp->share, s) != 0)
			continue;
		if(Debug && strstr(Debug, "dfs") != nil)
			print("mapshare, already connected, src=%q => dst=%q\n", path, sp->name);
		*osp = sp;
		return 0;
	}
	/*
	 * Try to autoconnect to share if it is not known.  Note even if you
	 * didn't specify any shares and let the system autoconnect you may
	 * not already have the share you need as RAP (which we use) throws
	 * away names > 12 chars long.  If we where to use RPC then this block
	 * of code would be less important, though it would still be useful
	 * to catch Shares added since cifs(1) was started.
	 */
	sp = Shares + Nshares;
	for(i = 0; i < 2; i++){
		try = smprint("%s%s", cp->share, tail[i]);
		if(CIFStreeconnect(Sess, Sess->cname, try, sp) == 0){
			sp->name = try;
			*osp = sp;
			Nshares++;
			if(Debug && strstr(Debug, "dfs") != nil)
				print("mapshare connected, src=%q dst=%q\n",
					path, cp->share);
			return 0;
		}
		free(try);
	}

	if(Debug && strstr(Debug, "dfs") != nil)
		print("mapshare failed src=%s\n", path);
	werrstr("not found");
	return -1;
}
Exemplo n.º 25
0
char*
impName(char *name)
{
	char *s;
	int n;

	if(cistrcmp(name, "inbox") == 0)
		name = "mbox";
	n = strlen(name) + STRLEN(".imp") + 1;
	s = binalloc(&parseBin, n, 0);
	if(s == nil)
		return nil;
	snprint(s, n, "%s.imp", name);
	return s;
}
Exemplo n.º 26
0
Arquivo: console.c Projeto: 8l/inferno
void
consinit(char* name, char* speed)
{
	int baud, port;

	if(name == nil || cistrcmp(name, "cga") == 0)
		return;
	port = strtoul(name, 0, 0);
	if(port < 0 || port > 1)
		return;
	if(speed == nil || (baud = strtoul(speed, 0, 0)) == 0)
		baud = 9600;

	qinit(&consoq);

	uartspecial(port, kbdchar, consputc, baud);
	useuart = 1;
	uartputs(&consoq, "\n", 1);
}
Exemplo n.º 27
0
static SmbProcessResult
netsharegetinfo(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
{
	char *netname;
	uint16_t level;
	SmbProcessResult pr;
	SmbService *serv;

	/*
	 * zWrLh
	 * char *pszNetName, ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ushort *pcbTotalAvail
	*/

	if (!smbbuffergetstrinline(inparam, &netname)
		|| !smbbuffergets(inparam, &level)) {
	fmtfail:
		pr = SmbProcessResultFormat;
		goto done;
	}
	
	smblogprintif(smbglobals.log.rap2, "netsharegetinfo(%s, %lud, %lud)\n",
		netname, level, smbbufferwritespace(outdata));

	if (level > 2)
		goto fmtfail;

	for (serv = smbservices; serv; serv = serv->next)
		if (cistrcmp(serv->name, netname) == 0)
			break;

	if (serv == nil) {
		smblogprint(-1, "netsharegetinfo: service %s unimplemented\n", netname);
		pr = SmbProcessResultUnimp;
		goto done;
	}

	pr = onethingfill(outparam, outdata, &shareinfo, level, serv);

done:
	return pr;
}
Exemplo n.º 28
0
int
nntpxcmdprobe(Netbuf *n)
{
	int i;
	char *p;

	n->extended = 0;
	if (nntpcmd(n, "LIST EXTENSIONS", 0) < 0 || n->code != 202)
		return 0;

	while((p = Nrdline(n)) != nil) {
		if (strcmp(p, ".") == 0)
			break;

		for(i=0; extensions[i].s != nil; i++)
			if (cistrcmp(extensions[i].s, p) == 0) {
				n->extended |= extensions[i].n;
				break;
			}
	}
	return 0;
}
Exemplo n.º 29
0
void
hello(String *himp, int extended)
{
	char **mynames;
	char *ldot, *rdot;

	him = s_to_c(himp);
	syslog(0, "smtpd", "%s from %s as %s", extended? "ehlo": "helo",
		nci->rsys, him);
	if(rejectcheck())
		return;

	if (strchr(him, '.') && nci && !trusted && fflag &&
	    strcmp(nci->rsys, nci->lsys) != 0){
		/*
		 * We don't care if he lies about who he is, but it is
		 * not okay to pretend to be us.  Many viruses do this,
		 * just parroting back what we say in the greeting.
		 */
		if(strcmp(him, dom) == 0)
			goto Liarliar;
		for(mynames = sysnames_read(); mynames && *mynames; mynames++){
			if(cistrcmp(*mynames, him) == 0){
Liarliar:
				syslog(0, "smtpd",
					"Hung up on %s; claimed to be %s",
					nci->rsys, him);
				if(Dflag)
					sleep(delaysecs()*1000);
				reply("554 5.7.0 Liar!\r\n");
				exits("client pretended to be us");
				return;
			}
		}
	}

	/*
	 * it is unacceptable to claim any string that doesn't look like
	 * a domain name (e.g., has at least one dot in it), but
	 * Microsoft mail client software gets this wrong, so let trusted
	 * (local) clients omit the dot.
	 */
	rdot = strrchr(him, '.');
	if (rdot && rdot[1] == '\0') {
		*rdot = '\0';			/* clobber trailing dot */
		rdot = strrchr(him, '.');	/* try again */
	}
	if (!trusted && rdot == nil)
		goto Liarliar;
	/*
	 * Reject obviously bogus domains and those reserved by RFC 2606.
	 */
	if (rdot == nil)
		rdot = him;
	else
		rdot++;
	if (!trusted && (cistrcmp(rdot, "localdomain") == 0 ||
	    cistrcmp(rdot, "localhost") == 0 ||
	    cistrcmp(rdot, "example") == 0 ||
	    cistrcmp(rdot, "invalid") == 0 ||
	    cistrcmp(rdot, "test") == 0))
		goto Liarliar;			/* bad top-level domain */
	/* check second-level RFC 2606 domains: example\.(com|net|org) */
	if (rdot != him)
		*--rdot = '\0';
	ldot = strrchr(him, '.');
	if (rdot != him)
		*rdot = '.';
	if (ldot == nil)
		ldot = him;
	else
		ldot++;
	if (cistrcmp(ldot, "example.com") == 0 ||
	    cistrcmp(ldot, "example.net") == 0 ||
	    cistrcmp(ldot, "example.org") == 0)
		goto Liarliar;

	/*
	 * similarly, if the claimed domain is not an address-literal,
	 * require at least one letter, which there will be in
	 * at least the last component (e.g., .com, .net) if it's real.
	 * this rejects non-address-literal IP addresses,
	 * among other bogosities.
	 */
	if (!trusted && him[0] != '[') {
		char *p;

		for (p = him; *p != '\0'; p++)
			if (isascii(*p) && isalpha(*p))
				break;
		if (*p == '\0')
			goto Liarliar;
	}
	if(strchr(him, '.') == 0 && nci != nil && strchr(nci->rsys, '.') != nil)
		him = nci->rsys;

	if(Dflag)
		sleep(delaysecs()*1000);
	reply("250%c%s you are %s\r\n", extended ? '-' : ' ', dom, him);
	if (extended) {
		reply("250-ENHANCEDSTATUSCODES\r\n");	/* RFCs 2034 and 3463 */
		if(tlscert != nil)
			reply("250-STARTTLS\r\n");
		if (passwordinclear)
			reply("250 AUTH CRAM-MD5 PLAIN LOGIN\r\n");
		else
			reply("250 AUTH CRAM-MD5\r\n");
	}
}
Exemplo n.º 30
0
void
auth(String *mech, String *resp)
{
	char *user, *pass, *scratch = nil;
	AuthInfo *ai = nil;
	Chalstate *chs = nil;
	String *s_resp1_64 = nil, *s_resp2_64 = nil, *s_resp1 = nil;
	String *s_resp2 = nil;

	if (rejectcheck())
		goto bomb_out;

	syslog(0, "smtpd", "auth(%s, %s) from %s", s_to_c(mech),
		"(protected)", him);

	if (authenticated) {
	bad_sequence:
		rejectcount++;
		reply("503 5.5.2 Bad sequence of commands\r\n");
		goto bomb_out;
	}
	if (cistrcmp(s_to_c(mech), "plain") == 0) {
		if (!passwordinclear) {
			rejectcount++;
			reply("538 5.7.1 Encryption required for requested "
				"authentication mechanism\r\n");
			goto bomb_out;
		}
		s_resp1_64 = resp;
		if (s_resp1_64 == nil) {
			reply("334 \r\n");
			s_resp1_64 = s_new();
			if (getcrnl(s_resp1_64, &bin) <= 0)
				goto bad_sequence;
		}
		s_resp1 = s_dec64(s_resp1_64);
		if (s_resp1 == nil) {
			rejectcount++;
			reply("501 5.5.4 Cannot decode base64\r\n");
			goto bomb_out;
		}
		memset(s_to_c(s_resp1_64), 'X', s_len(s_resp1_64));
		user = s_to_c(s_resp1) + strlen(s_to_c(s_resp1)) + 1;
		pass = user + strlen(user) + 1;
		ai = auth_userpasswd(user, pass);
		authenticated = ai != nil;
		memset(pass, 'X', strlen(pass));
		goto windup;
	}
	else if (cistrcmp(s_to_c(mech), "login") == 0) {
		if (!passwordinclear) {
			rejectcount++;
			reply("538 5.7.1 Encryption required for requested "
				"authentication mechanism\r\n");
			goto bomb_out;
		}
		if (resp == nil) {
			reply("334 VXNlcm5hbWU6\r\n");
			s_resp1_64 = s_new();
			if (getcrnl(s_resp1_64, &bin) <= 0)
				goto bad_sequence;
		}
		reply("334 UGFzc3dvcmQ6\r\n");
		s_resp2_64 = s_new();
		if (getcrnl(s_resp2_64, &bin) <= 0)
			goto bad_sequence;
		s_resp1 = s_dec64(s_resp1_64);
		s_resp2 = s_dec64(s_resp2_64);
		memset(s_to_c(s_resp2_64), 'X', s_len(s_resp2_64));
		if (s_resp1 == nil || s_resp2 == nil) {
			rejectcount++;
			reply("501 5.5.4 Cannot decode base64\r\n");
			goto bomb_out;
		}
		ai = auth_userpasswd(s_to_c(s_resp1), s_to_c(s_resp2));
		authenticated = ai != nil;
		memset(s_to_c(s_resp2), 'X', s_len(s_resp2));
windup:
		if (authenticated) {
			/* if you authenticated, we trust you despite your IP */
			trusted = 1;
			reply("235 2.0.0 Authentication successful\r\n");
		} else {
			rejectcount++;
			reply("535 5.7.1 Authentication failed\r\n");
			syslog(0, "smtpd", "authentication failed: %r");
		}
		goto bomb_out;
	}
	else if (cistrcmp(s_to_c(mech), "cram-md5") == 0) {
		int chal64n;
		char *resp, *t;

		chs = auth_challenge("proto=cram role=server");
		if (chs == nil) {
			rejectcount++;
			reply("501 5.7.5 Couldn't get CRAM-MD5 challenge\r\n");
			goto bomb_out;
		}
		scratch = malloc(chs->nchal * 2 + 1);
		chal64n = enc64(scratch, chs->nchal * 2, (uchar *)chs->chal,
			chs->nchal);
		scratch[chal64n] = 0;
		reply("334 %s\r\n", scratch);
		s_resp1_64 = s_new();
		if (getcrnl(s_resp1_64, &bin) <= 0)
			goto bad_sequence;
		s_resp1 = s_dec64(s_resp1_64);
		if (s_resp1 == nil) {
			rejectcount++;
			reply("501 5.5.4 Cannot decode base64\r\n");
			goto bomb_out;
		}
		/* should be of form <user><space><response> */
		resp = s_to_c(s_resp1);
		t = strchr(resp, ' ');
		if (t == nil) {
			rejectcount++;
			reply("501 5.5.4 Poorly formed CRAM-MD5 response\r\n");
			goto bomb_out;
		}
		*t++ = 0;
		chs->user = resp;
		chs->resp = t;
		chs->nresp = strlen(t);
		ai = auth_response(chs);
		authenticated = ai != nil;
		goto windup;
	}
	rejectcount++;
	reply("501 5.5.1 Unrecognised authentication type %s\r\n", s_to_c(mech));
bomb_out:
	if (ai)
		auth_freeAI(ai);
	if (chs)
		auth_freechal(chs);
	if (scratch)
		free(scratch);
	if (s_resp1)
		s_free(s_resp1);
	if (s_resp2)
		s_free(s_resp2);
	if (s_resp1_64)
		s_free(s_resp1_64);
	if (s_resp2_64)
		s_free(s_resp2_64);
}