/* list the (name mtime size sum) of regular, readable files in path */ char * dirls(char *path) { char *list, *date, dig[30], buf[128]; int m, nmwid, lenwid; long i, n, ndir, len; Dir *dirbuf; if(path==nil || (ndir = ls(path, &dirbuf)) < 0) return nil; qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(void *, void *))compare); for(nmwid=lenwid=i=0; i<ndir; i++){ if((m = strlen(dirbuf[i].name)) > nmwid) nmwid = m; snprint(buf, sizeof(buf), "%ulld", dirbuf[i].length); if((m = strlen(buf)) > lenwid) lenwid = m; } for(list=nil, len=0, i=0; i<ndir; i++){ date = ctime(dirbuf[i].mtime); date[28] = 0; // trim newline n = snprint(buf, sizeof buf, "%*ulld %s", lenwid, dirbuf[i].length, date+4); n += enc64(dig, sizeof dig, sha1file(path, dirbuf[i].name), SHA1dlen); n += nmwid+3+strlen(dirbuf[i].name); list = erealloc(list, len+n+1); len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig); } free(dirbuf); return list; }
/* * create a change uid capability */ char* mkcap(char *from, char *to) { uchar rand[20]; char *cap; char *key; int nfrom, nto; uchar hash[SHA1dlen]; if(caphashfd < 0) return nil; /* create the capability */ nto = strlen(to); nfrom = strlen(from); cap = emalloc(nfrom+1+nto+1+sizeof(rand)*3+1); sprint(cap, "%s@%s", from, to); genrandom(rand, sizeof(rand)); key = cap+nfrom+1+nto+1; enc64(key, sizeof(rand)*3, rand, sizeof(rand)); /* hash the capability */ hmac_sha1((uchar*)cap, strlen(cap), (uchar*)key, strlen(key), hash, nil); /* give the kernel the hash */ key[-1] = '@'; if(write(caphashfd, hash, SHA1dlen) < 0){ free(cap); return nil; } return cap; }
EXTERN value md5sum(value str) /* ML */ { byte *buf; byte digest[16], pr64[25]; int n, len, start; MD5state *s; s = nil; len = string_length(str); start = 0; buf = calloc(256,64); for(;;){ if (len - start < 128*64) n = len - start; else n = 128*64; bcopy(&Byte(str, start), buf, n); start += n; if(n <= 0 || n & 0x3f) break; s = md5(buf, n, 0, s); } md5(buf, n, digest, s); enc64(pr64,digest,sizeof(digest)); pr64[22] = '\0'; /* chop trailing == */ free(buf); return copy_string((char *)pr64); }
void sum(FILE *fd, char *name) { byte *buf; byte digest[16]; char pr64[25]; int i, n; MD5state *s; s = nil; n = 0; buf = calloc(256,64); for(;;){ i = fread(buf+n, 1, 128*64-n, fd); if(i <= 0) break; n += i; if(n & 0x3f) continue; s = md5(buf, n, 0, s); n = 0; } md5(buf, n, digest, s); if(hex){ for(i=0;i<16;i++) printf("%.2X", digest[i]); }else{ enc64(pr64,digest,sizeof(digest)); pr64[22] = '\0'; /* chop trailing == */ printf("%s",pr64); } if(name) printf("\t%s", name); printf("\n"); free(buf); }
void wwwauthenticate(HttpState *hs, char *line) { char cred[64], *user, *pass, *realm, *s, *spec, *name; Fmt fmt; UserPasswd *up; spec = nil; up = nil; cred[0] = 0; hs->autherror[0] = 0; if(cistrncmp(line, "basic ", 6) != 0){ werrstr("unknown auth: %s", line); goto error; } line += 6; if(cistrncmp(line, "realm=", 6) != 0){ werrstr("missing realm: %s", line); goto error; } line += 6; user = hs->c->url->user; pass = hs->c->url->passwd; if(user==nil || pass==nil){ realm = unquote(line, &line); fmtstrinit(&fmt); name = servername(hs->netaddr); fmtprint(&fmt, "proto=pass service=http server=%q realm=%q", name, realm); free(name); if(hs->c->url->user) fmtprint(&fmt, " user=%q", hs->c->url->user); spec = fmtstrflush(&fmt); if(spec == nil) goto error; if((up = auth_getuserpasswd(nil, "%s", spec)) == nil) goto error; user = up->user; pass = up->passwd; } if((s = smprint("%s:%s", user, pass)) == nil) goto error; free(up); enc64(cred, sizeof(cred), (uint8_t*)s, strlen(s)); memset(s, 0, strlen(s)); free(s); hs->credentials = smprint("Basic %s", cred); if(hs->credentials == nil) goto error; return; error: free(up); free(spec); snprint(hs->autherror, sizeof hs->autherror, "%r"); fprint(2, "%s: Authentication failed: %r\n", argv0); }
void main(int argc, char **argv) { char *buf, *cbuf; int fd; long n, tot; int len; char *tag, *file; ARGBEGIN{ default: usage(); }ARGEND if(argc != 1 && argc != 2) usage(); tag = argv[0]; if(argc == 2) file = argv[1]; else file = "#d/0"; if((fd = open(file, OREAD)) < 0) sysfatal("open %s: %r", file); buf = nil; tot = 0; for(;;){ buf = realloc(buf, tot+8192); if(buf == nil) sysfatal("realloc: %r"); if((n = read(fd, buf+tot, 8192)) < 0) sysfatal("read: %r"); if(n == 0) break; tot += n; } buf[tot] = 0; cbuf = malloc(2*tot); if(cbuf == nil) sysfatal("malloc: %r"); len = enc64(cbuf, 2*tot, (uchar*)buf, tot); print("-----BEGIN %s-----\n", tag); while(len > 0){ print("%.64s\n", cbuf); cbuf += 64; len -= 64; } print("-----END %s-----\n", tag); exits(0); }
char* md5pickle(MD5state *s) { char *p; int m, n; m = 17+4*9+4*((s->blen+3)/3 + 1); p = malloc(m); if(p == nil) return p; n = sprint(p, "%16.16llux %8.8ux %8.8ux %8.8ux %8.8ux ", s->len, s->state[0], s->state[1], s->state[2], s->state[3]); enc64(p+n, m-n, s->buf, s->blen); return p; }
/* * rfc 2195 cram-md5 authentication */ char* cramauth(void) { AuthInfo *ai; Chalstate *cs; char *s, *t; int n; if((cs = auth_challenge("proto=cram role=server")) == nil) return "couldn't get cram challenge"; n = cs->nchal; s = binalloc(&parseBin, n * 2, 0); n = enc64(s, n * 2, (uint8_t*)cs->chal, n); Bprint(&bout, "+ "); Bwrite(&bout, s, n); Bprint(&bout, "\r\n"); if(Bflush(&bout) < 0) writeErr(); s = authresp(); if(s == nil) return "client cancelled authentication"; t = strchr(s, ' '); if(t == nil) bye("bad auth response"); *t++ = '\0'; strncpy(username, s, UserNameLen); username[UserNameLen-1] = '\0'; cs->user = username; cs->resp = t; cs->nresp = strlen(t); if((ai = auth_response(cs)) == nil) return "login failed"; auth_freechal(cs); setupuser(ai); return nil; }
/* * Create a public key in the form of a null-terminated C string. * This string contains an encoded version of all of our ivars except for * privGiant. * * See ByteRep.doc for info on the format of the public key string and blobs; * PLEASE UPDATE THIS DOCUMENT WHEN YOU MAKE CHANGES TO THE STRING FORMAT. */ feeReturn feePubKeyCreateKeyString(feePubKey pubKey, char **pubKeyString, /* RETURNED */ unsigned *pubKeyStringLen) /* RETURNED */ { unsigned char *blob; unsigned blobLen; feeReturn frtn; pubKeyInst *pkinst = (pubKeyInst *)pubKey; /* get binary pub blob, encode the blob, free the blob */ frtn = createKeyBlob(pkinst, 0, // isPrivate &blob, &blobLen); if(frtn) { return frtn; } *pubKeyString = (char *)enc64(blob, blobLen, pubKeyStringLen); ffree(blob); return FR_Success; }
int encodefmt(Fmt *f) { char *out; char *buf, *p; int len; int ilen; int rv; uchar *b; char obuf[64]; /* rsc optimization */ b = va_arg(f->args, uchar*); if(b == 0) return fmtstrcpy(f, "<nil>"); ilen = f->prec; f->prec = 0; if(!(f->flags&FmtPrec) || ilen < 0) goto error; f->flags &= ~FmtPrec; switch(f->r){ case '<': len = (8*ilen+4)/5 + 3; break; case '[': len = (8*ilen+5)/6 + 4; break; case 'H': len = 2*ilen + 1; break; default: goto error; } if(len > sizeof(obuf)){ buf = malloc(len); if(buf == nil) goto error; } else buf = obuf; /* convert */ out = buf; switch(f->r){ case '<': rv = enc32(out, len, b, ilen); break; case '[': rv = enc64(out, len, b, ilen); break; case 'H': rv = enc16(out, len, b, ilen); if(rv >= 0 && (f->flags & FmtLong)) for(p = buf; *p; p++) *p = tolower((uchar)*p); break; default: rv = -1; break; } if(rv < 0) goto error; fmtstrcpy(f, buf); if(buf != obuf) free(buf); return 0; error: return fmtstrcpy(f, "<encodefmt>"); }
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); }
/* * Create a cipherfile of specified cipherFileEncrType. */ feeReturn createCipherFile(feePubKey sendPrivKey, feePubKey recvPubKey, cipherFileEncrType encrType, const unsigned char *plainText, unsigned plainTextLen, int genSig, // 1 ==> generate signature int doEnc64, // 1 ==> perform enc64 unsigned userData, // for caller's convenience unsigned char **cipherFileData, // RETURNED unsigned *cipherFileDataLen) // RETURNED { feeReturn frtn = FR_Success; feeCipherFile cipherFile = NULL; unsigned char *cipherData = NULL; unsigned cipherDataLen; /* * Dispatch to encrType-specific code. */ switch(encrType) { case CFE_RandDES: frtn = createRandDES(sendPrivKey, recvPubKey, plainText, plainTextLen, genSig, userData, &cipherFile); break; case CFE_PublicDES: frtn = createPubDES(sendPrivKey, recvPubKey, plainText, plainTextLen, genSig, userData, &cipherFile); break; case CFE_FEED: frtn = createFEED(sendPrivKey, recvPubKey, plainText, plainTextLen, genSig, userData, &cipherFile); break; case CFE_FEEDExp: frtn = createFEEDExp(sendPrivKey, recvPubKey, plainText, plainTextLen, genSig, userData, &cipherFile); break; default: frtn = FR_Unimplemented; break; } if(frtn) { goto out; } /* * Common logic for all encrTypes */ /* * Get the cipherfile's raw data */ frtn = feeCFileDataRepresentation(cipherFile, (const unsigned char **)&cipherData, &cipherDataLen); if(frtn) { goto out; } /* * Optionally encode in 64-char ASCII */ if(doEnc64) { *cipherFileData = enc64(cipherData, cipherDataLen, cipherFileDataLen); ffree(cipherData); if(*cipherFileData == NULL) { frtn = FR_Internal; ffree(cipherData); goto out; } } else { *cipherFileData = cipherData; *cipherFileDataLen = cipherDataLen; } out: /* free stuff */ if(cipherFile) { feeCFileFree(cipherFile); } return frtn; }
static char * doauth(char *methods) { char *buf, *base64; int n; DS ds; UserPasswd *p; dial_string_parse(ddomain, &ds); if(user != nil) p = auth_getuserpasswd(nil, "proto=pass service=smtp server=%q user=%q", ds.host, user); else p = auth_getuserpasswd(nil, "proto=pass service=smtp server=%q", ds.host); if (p == nil) return Giveup; if (strstr(methods, "LOGIN")){ dBprint("AUTH LOGIN\r\n"); if (getreply() != 3) return Retry; n = strlen(p->user); base64 = malloc(2*n); if (base64 == nil) return Retry; /* Out of memory */ enc64(base64, 2*n, (uchar *)p->user, n); dBprint("%s\r\n", base64); if (getreply() != 3) return Retry; n = strlen(p->passwd); base64 = malloc(2*n); if (base64 == nil) return Retry; /* Out of memory */ enc64(base64, 2*n, (uchar *)p->passwd, n); dBprint("%s\r\n", base64); if (getreply() != 2) return Retry; free(base64); } else if (strstr(methods, "PLAIN")){ n = strlen(p->user) + strlen(p->passwd) + 3; buf = malloc(n); base64 = malloc(2 * n); if (buf == nil || base64 == nil) { free(buf); return Retry; /* Out of memory */ } snprint(buf, n, "%c%s%c%s", 0, p->user, 0, p->passwd); enc64(base64, 2 * n, (uchar *)buf, n - 1); free(buf); dBprint("AUTH PLAIN %s\r\n", base64); free(base64); if (getreply() != 2) return Retry; } else return "No supported AUTH method"; return(0); }