hash_stat hash_plugin_parse_hash(char *hashline, char *filename) { char username[HASHFILE_MAX_LINE_LENGTH]; char hash[HASHFILE_MAX_LINE_LENGTH]; char line[HASHFILE_MAX_LINE_LENGTH]; char line2[HASHFILE_MAX_LINE_LENGTH]; char myhash[200]; char mysalt[100]; int blen; char *temp_str=NULL; bzero(myhash,200); bzero(mysalt,100); if (!hashline) return hash_err; if (!strstr(hashline,"{SSHA}")) return hash_err; if (strlen(hashline)<2) return hash_err; snprintf(line, HASHFILE_MAX_LINE_LENGTH-1, "%s", hashline); if (strstr(line,":")) { strcpy(username, strtok(line, ":")); temp_str=strtok(NULL,":"); } else strcpy(username,"N/A"); if (temp_str) { strcpy(hash, temp_str); strcpy(myhash,hash); if (memcmp(myhash, "{SSHA}", 6)!=0) return hash_err; (void)hash_add_username(username); (void)hash_add_hash(myhash, 0); blen = b64_pton(hash+6, (unsigned char *)line2, HASHFILE_MAX_LINE_LENGTH); line2[blen]=0; memcpy(mysalt,line2+20,8); mysalt[8]=0; mysalt[9]=0; (void)hash_add_salt(mysalt); } else { strcpy(myhash,line); if (memcmp(myhash, "{SSHA}", 6)!=0) return hash_err; (void)hash_add_username("N/A"); (void)hash_add_hash(myhash, 0); blen = b64_pton(myhash+6, (unsigned char *)line2, HASHFILE_MAX_LINE_LENGTH); line2[blen]=0; memcpy(mysalt,line2+20,8); mysalt[8]=0; (void)hash_add_salt(mysalt); } (void)hash_add_salt2(""); return hash_ok; }
int decode_hybi(char *src, size_t srclength, u_char *target, size_t targsize) { char *start; int i = 0, j, len, sz = 0; if ((int)srclength <= 0) { return 0; } src[srclength] = '\0'; start = src; if (start[1] < 126) { start += 2 * sizeof(char); sz += 2; } else if (start[1] == 126) { start += 4 * sizeof(char); sz += 4; } else { start += 10 * sizeof(char); sz += 10; } if (src[1] & 0x80) { // we need to unmask the data //mask = ((char)start[0]) + ((char)start[1] << 8) + ((char)start[2] << 16) + ((char)start[3] << 24); i = 0; while (i < srclength - sz - 4) { j = i % 4; start[i + 4] ^= start[j]; i += 1; } start += 4 * sizeof(char); printf("%s\n", start); len = b64_pton((const char*)start, target, targsize); } else { len = b64_pton(src, target, targsize); } if (len < 0) { return len; } return len; }
/** add tsig_key contents */ void key_options_setup(region_type* region, key_options_t* key) { uint8_t data[16384]; /* 16KB */ int size; if(!key->tsig_key) { /* create it */ key->tsig_key = (tsig_key_type *) region_alloc(region, sizeof(tsig_key_type)); /* create name */ key->tsig_key->name = dname_parse(region, key->name); if(!key->tsig_key->name) { log_msg(LOG_ERR, "Failed to parse tsig key name %s", key->name); /* key and base64 were checked during syntax parse */ exit(1); } key->tsig_key->size = 0; key->tsig_key->data = NULL; } size = b64_pton(key->secret, data, sizeof(data)); if(size == -1) { log_msg(LOG_ERR, "Failed to parse tsig key data %s", key->name); /* key and base64 were checked during syntax parse */ exit(1); } key->tsig_key->size = size; key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size); }
int decode_hixie(char *src, size_t srclength, u_char *target, size_t targsize) { char *start, *end, cntstr[4]; int len, framecount = 0, retlen = 0; if ((src[0] != '\x00') || (src[srclength-1] != '\xff')) { handler_emsg("WebSocket framing error\n"); return -1; } start = src+1; // Skip '\x00' start do { /* We may have more than one frame */ end = (char *)memchr(start, '\xff', srclength); *end = '\x00'; len = b64_pton(start, target+retlen, targsize-retlen); if (len < 0) { return len; } retlen += len; start = end + 2; // Skip '\xff' end and '\x00' start framecount++; } while (end < (src+srclength-1)); if (framecount > 1) { snprintf(cntstr, 3, "%d", framecount); traffic(cntstr); } return retlen; }
int py_ersatz_hash(char *password, char *ersatz_salt, char *out_hash) { /* todo: check the ersatz size */ char hmac_digest[HMAC_LEN]; int ret = py_hsm_hmac(password, hmac_digest); if(ret != HSM_HMAC_OK) return ERSATZ_HASH_FAIL; int i; char decoded_salt[SALT_SIZE ]; /* convert back from . to + */ for(i = 0; i < SALT_SIZE; i++) if(ersatz_salt[i] == '.') ersatz_salt[i] = '+'; /* base64 decode ersatz salt */ b64_pton((unsigned char *) ersatz_salt, decoded_salt, SALT_SIZE); /* xor the hmac digest with the salt */ for(i = 0; i < SALT_SIZE; i++) hmac_digest[i] = hmac_digest[i] ^ decoded_salt[i]; for(i = 0; i < SALT_SIZE; i++) if(ersatz_salt[i] == '+') ersatz_salt[i] = '.'; /* take a sha-512 hash */ crypt_set_format("sha512"); strcpy(out_hash, crypt(hmac_digest, ersatz_salt)); return ERSATZ_HASH_OK; }
static bool asignify_pubkey_try_obsd(const char *buf, size_t buflen, struct asignify_public_data **pk) { struct obsd_pubkey opk; struct asignify_public_data *res; if (buflen >= sizeof(OBSD_COMMENTHDR) - 1 && memcmp(buf, OBSD_COMMENTHDR, sizeof(OBSD_COMMENTHDR) - 1) == 0) { /* Skip comments */ return (true); } if (b64_pton(buf, (unsigned char *)&opk, sizeof(opk)) == sizeof(opk)) { if (memcmp(opk.pkalg, OBSD_PKALG, sizeof(opk.pkalg)) == 0) { res = xmalloc(sizeof(*res)); /* OpenBSD version code */ res->version = 0; res->data_len = sizeof(opk.pubkey); res->id_len = sizeof(opk.keynum); asignify_alloc_public_data_fields(res); memcpy(res->data, opk.pubkey, res->data_len); memcpy(res->id, opk.keynum, res->id_len); *pk = res; } } /* * We stop processing on the first non-comment line. If we have a key, * then we set *pk to some openbsd key, otherwise this variable is not * touched */ return (false); }
int sshbuf_b64tod(struct sshbuf *buf, const char *b64) { size_t plen = strlen(b64); int nlen, r; u_char *p; if (plen == 0) return 0; if ((p = malloc(plen)) == NULL) return SSH_ERR_ALLOC_FAIL; if ((nlen = b64_pton(b64, p, plen)) < 0) { bzero(p, plen); free(p); return SSH_ERR_INVALID_FORMAT; } if ((r = sshbuf_put(buf, p, nlen)) < 0) { bzero(p, plen); free(p); return r; } bzero(p, plen); free(p); return 0; }
int dst_s_conv_bignum_b64_to_u8(const char **buf, u_char *loc, const unsigned loclen) { unsigned blen; char *bp; u_char bstr[RAW_KEY_SIZE]; int res = 0; if (buf == NULL || *buf == NULL) { /* error checks */ EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n")); return (0); } bp = strchr(*buf, '\n'); /* find length of input line */ if (bp != NULL) *bp = '\0'; res = b64_pton(*buf, bstr, sizeof(bstr)); if (res <= 0) { EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n")); return (0); } blen = (unsigned) res; if (loclen < blen) { EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n")); return (0); } if (bp) *buf = bp; /* advancing buffer past \n */ memset(loc, 0, loclen - blen); /* clearing unused output area */ memcpy(loc + loclen - blen, bstr, blen); /* write last blen bytes */ return (blen); }
void key_options_tsig_add(nsd_options_t* opt) { key_options_t* optkey; uint8_t data[4000]; tsig_key_type* tsigkey; const dname_type* dname; int size; for(optkey = opt->keys; optkey; optkey = optkey->next) { dname = dname_parse(opt->region, optkey->name); if(!dname) { log_msg(LOG_ERR, "Failed to parse tsig key name %s", optkey->name); continue; } size = b64_pton(optkey->secret, data, sizeof(data)); if(size == -1) { log_msg(LOG_ERR, "Failed to parse tsig key data %s", optkey->name); continue; } tsigkey = (tsig_key_type *) region_alloc(opt->region, sizeof(tsig_key_type)); tsigkey->name = dname; tsigkey->size = size; tsigkey->data = (uint8_t *) region_alloc_init(opt->region, data, tsigkey->size); tsig_add_key(tsigkey); optkey->tsig_key = tsigkey; } }
/* * read user's pubkeyring file to allow lookup by ident */ static const struct pubkey * findpubkey(const char *ident) { static struct { char ident[IDENTLEN]; struct pubkey pubkey; } *keys; static int numkeys; static int done; int i; const char *beginreop = "-----BEGIN REOP PUBLIC KEY----\n"; const char *endreop = "-----END REOP PUBLIC KEY-----\n"; if (!done) { char line[1024]; char buf[1024]; int identline; FILE *fp; done = 1; fp = fopen(gethomefile("pubkeyring"), "r"); if (!fp) return NULL; while (fgets(line, sizeof(line), fp)) { buf[0] = 0; identline = 1; if (line[0] == 0 || line[0] == '\n') continue; if (strncmp(line, beginreop, strlen(beginreop)) != 0) errx(1, "invalid keyring line: %s", line); if (!(keys = realloc(keys, sizeof(*keys) * (numkeys + 1)))) err(1, "realloc keyring"); while (1) { if (!fgets(line, sizeof(line), fp)) errx(1, "premature pubkeyring EOF"); if (identline) { readident(line, keys[numkeys].ident); identline = 0; continue; } if (strncmp(line, endreop, strlen(endreop)) == 0) break; strlcat(buf, line, sizeof(buf)); } if (b64_pton(buf, (void *)&keys[numkeys].pubkey, sizeof(keys[0].pubkey)) != sizeof(keys[0].pubkey)) errx(1, "invalid keyring b64 encoding"); if (numkeys++ > 1000000) errx(1, "too many keys"); } } for (i = 0; i < numkeys; i++) { if (strcmp(ident, keys[i].ident) == 0) return &keys[i].pubkey; } return NULL; }
static void unbase64(uint8_t dstkey[32], const char *srckey) { uint8_t buf[33]; if (b64_pton(srckey, buf, 33) != 32) { fprintf(stderr, "Could not parse base64 key: %s\n", srckey); exit(EINVAL); } memcpy(dstkey, buf, 32); }
TEST(resolv, b64_pton_28035006) { // Test data from https://groups.google.com/forum/#!topic/mailing.openbsd.tech/w3ACIlklJkI. const char* data = "p1v3+nehH3N3n+/OokzXpsyGF2VVpxIxkjSn3Mv/Sq74OE1iFuVU+K4bQImuVj" "S55RB2fpCpbB8Nye7tzrt6h9YPP3yyJfqORDETGmIB4lveZXA4KDxx50F9rYrO" "dFbTLyWfNBb/8Q2TnD72eY/3Y5P9qwtJwyDL25Tleic8G3g="; // This buffer is exactly the right size, but old versions of the BSD code // incorrectly required an extra byte. http://b/28035006. uint8_t buf[128]; ASSERT_EQ(128, b64_pton(data, buf, sizeof(buf))); }
/* Base64 decode string. */ char * imap_base64_decode(char *in) { char *out; size_t size; size = (strlen(in) * 4) + 1; out = xcalloc(1, size); if (b64_pton(in, out, size) < 0) { xfree(out); return (NULL); } return (out); }
static int urlsafe_base64_decode(const char *base64, u_char *buffer, size_t bufferlen) { // U2F uses urlsafe base64, which replaces + with - and / with _, so we // need to revert that before base64 decoding. char *replaced; char *pos; replaced = xstrdup(base64); while ((pos = strchr(replaced, '-')) != NULL) *pos = '+'; while ((pos = strchr(replaced, '_')) != NULL) *pos = '/'; return b64_pton(replaced, buffer, bufferlen); }
/* * message followed by signature in one file */ static void verifyembedded(const char *pubkeyfile, const char *sigfile, int quiet) { char ident[IDENTLEN]; struct sig sig; struct pubkey pubkey; uint8_t *msg; unsigned long long msglen; uint8_t *msgdata; unsigned long long msgdatalen; char *begin, *end; const char *beginreopmsg = "-----BEGIN REOP SIGNED MESSAGE-----\n"; const char *beginreopsig = "-----BEGIN REOP SIGNATURE-----\n"; const char *endreopmsg = "-----END REOP SIGNED MESSAGE-----\n"; msgdata = readall(sigfile, &msgdatalen); if (strncmp(msgdata, beginreopmsg, strlen(beginreopmsg)) != 0) goto fail; begin = msgdata + 36; if (!(end = strstr(begin, beginreopsig))) goto fail; *end = 0; msg = begin; msglen = end - begin; begin = end + 31; if (!(end = strstr(begin, endreopmsg))) goto fail; *end = 0; begin = readident(begin, ident); if (b64_pton(begin, (void *)&sig, sizeof(sig)) != sizeof(sig)) goto fail; getpubkey(pubkeyfile, ident, &pubkey); verifymsg(&pubkey, msg, msglen, &sig, quiet); free(msgdata); return; fail: errx(1, "invalid signature: %s", sigfile); }
uint16_t * zparser_conv_b64(region_type *region, const char *b64) { uint8_t buffer[B64BUFSIZE]; uint16_t *r = NULL; int i; if(strcmp(b64, "0") == 0) { /* single 0 represents empty buffer */ return alloc_rdata(region, 0); } i = b64_pton(b64, buffer, B64BUFSIZE); if (i == -1) { zc_error_prev_line("invalid base64 data"); } else { r = alloc_rdata_init(region, buffer, i); } return r; }
/* * Verify an SHA cancel key against a cancel lock. * Returns 0 on success, nonzero on failure. */ int md5_verify(unsigned char *key, unsigned char *lock) { unsigned char binkey[MD5_LENGTH + 4]; unsigned char templock[BUFFSIZE]; unsigned char hmacbuff[MD5_LENGTH]; MD5_CTX hash_ctx; int verified; /* Convert the key back into binary */ (void) b64_pton(key, binkey, (MD5_LENGTH + 4)); MD5Init(&hash_ctx); MD5Update(&hash_ctx, key, strlen(key)); MD5Final(hmacbuff, &hash_ctx); (void) b64_ntop(hmacbuff, MD5_LENGTH, templock, BUFFSIZE); verified = strcmp(templock, lock); return (verified); }
int decode_hixie(char *src, size_t srclength, u_char *target, size_t targsize, unsigned int *opcode, unsigned int *left) { char *start, *end, cntstr[4]; int i, len, framecount = 0, retlen = 0; unsigned char chr; if ((src[0] != '\x00') || (src[srclength-1] != '\xff')) { handler_emsg("WebSocket framing error\n"); return -1; } *left = srclength; if (srclength == 2 && (src[0] == '\xff') && (src[1] == '\x00')) { // client sent orderly close frame *opcode = 0x8; // Close frame return 0; } *opcode = 0x1; // Text frame start = src+1; // Skip '\x00' start do { /* We may have more than one frame */ end = (char *)memchr(start, '\xff', srclength); *end = '\x00'; len = b64_pton(start, target+retlen, targsize-retlen); if (len < 0) { return len; } retlen += len; start = end + 2; // Skip '\xff' end and '\x00' start framecount++; } while (end < (src+srclength-1)); if (framecount > 1) { snprintf(cntstr, 3, "%d", framecount); traffic(cntstr); } *left = 0; return retlen; }
static int dst_hmac_md5_key_from_file_format(DST_KEY *dkey, const char *buff, const int buff_len) { const char *p = buff, *eol; u_char key[HMAC_LEN+1]; /* b64_pton needs more than 64 bytes do decode * it should probably be fixed rather than doing * this */ u_char *tmp; int key_len, len; if (dkey == NULL) return (-2); if (buff == NULL || buff_len < 0) return (-1); memset(key, 0, sizeof(key)); if (!dst_s_verify_str(&p, "Key: ")) return (-3); eol = strchr(p, '\n'); if (eol == NULL) return (-4); len = eol - p; tmp = malloc(len + 2); if (tmp == NULL) return (-5); memcpy(tmp, p, len); *(tmp + len) = 0x0; key_len = b64_pton((char *)tmp, key, HMAC_LEN+1); /*%< see above */ SAFE_FREE2(tmp, len + 2); if (dst_buffer_to_hmac_md5(dkey, key, key_len) < 0) { return (-6); } return (0); }
static int chap_b642bin(const char *b64, void **binp, size_t *bin_lenp) { char *bin; int b64_len, bin_len; b64_len = strlen(b64); bin_len = (b64_len + 3) / 4 * 3; bin = calloc(bin_len, 1); if (bin == NULL) log_err(1, "calloc"); bin_len = b64_pton(b64, bin, bin_len); if (bin_len < 0) { log_warnx("malformed base64 variable"); free(bin); return (-1); } *binp = bin; *bin_lenp = bin_len; return (0); }
static void putb64(FILE *out, const char *inb, size_t *inblen) { char inbuf[5] = { 0 }; unsigned char outbuf[3]; ssize_t outbuflen; if (*inblen == 0) return; assert(*inblen <= 4); memcpy(inbuf, inb, *inblen); outbuflen = b64_pton(inbuf, outbuf, sizeof outbuf); if (outbuflen <= 0) { DPRINTF("invalid Base64 data"); die(1); } if (fwrite(outbuf, outbuflen, 1, out) != 1) { perror("fwrite"); die(1); } *inblen = 0; }
/* * try to read a few different kinds of files */ static void readkeyfile(const char *filename, void *key, size_t keylen, char *ident) { char *keydata; unsigned long long keydatalen; char *begin, *end; const char *beginreop = "-----BEGIN REOP"; const char *endreop = "-----END REOP"; keydata = readall(filename, &keydatalen); if (strncmp(keydata, beginreop, strlen(beginreop)) != 0 || !(end = strstr(keydata, endreop))) errx(1, "invalid key: %s", filename); *end = 0; if (!(begin = strchr(keydata, '\n'))) errx(1, "invalid key: %s", filename); begin = readident(begin + 1, ident); *end = 0; if (b64_pton(begin, key, keylen) != keylen) errx(1, "invalid b64 encoding: %s", filename); xfree(keydata, keydatalen); }
void switch_value(lua_State *L, int index, bson_t* bson, int level, const char* key) { switch(lua_type(L, index)) { case LUA_TTABLE: { int is_a=is_array(L, index); if (is_a) { bson_t child; //start array BSON_APPEND_ARRAY_BEGIN(bson, key, &child); iterate_table(L, index, &child, 0, level+1, NULL); bson_append_array_end(bson, &child); } else { bson_t child; //start map BSON_APPEND_DOCUMENT_BEGIN(bson, key, &child); iterate_table(L, index, &child, 1, level+1, NULL); bson_append_document_end(bson, &child); } break; } case LUA_TNIL: { BSON_APPEND_NULL(bson, key); break; } case LUA_TNUMBER: { BSON_APPEND_DOUBLE(bson, key, lua_tonumber(L, index)); break; } case LUA_TBOOLEAN: { BSON_APPEND_BOOL(bson, key, lua_toboolean(L, index)); break; } case LUA_TSTRING: { BSON_APPEND_UTF8(bson, key, lua_tostring(L, index)); break; } case LUA_TUSERDATA: { // switch userdata type if (luaL_checkudata_ex(L, index, REGEX_METATABLE)) { cbson_regex_t* regex = check_cbson_regex(L, index); BSON_APPEND_REGEX (bson, key, regex->regex, regex->options); } else if (luaL_checkudata_ex(L, index, OID_METATABLE)) { cbson_oid_t* oid = check_cbson_oid(L, index); bson_oid_t boid; bson_oid_init_from_string (&boid, oid->oid); BSON_APPEND_OID (bson, key, &boid); } else if (luaL_checkudata_ex(L, index, BINARY_METATABLE)) { cbson_binary_t* bin = check_cbson_binary(L, index); size_t binary_len = b64_pton (bin->data, NULL, 0); unsigned char* buf=malloc(binary_len+1); b64_pton(bin->data, buf, binary_len+1); BSON_APPEND_BINARY(bson, key, bin->type, buf, binary_len); free(buf); } else if (luaL_checkudata_ex(L, index, SYMBOL_METATABLE)) { cbson_symbol_t* sym = check_cbson_symbol(L, index); BSON_APPEND_SYMBOL(bson, key, sym->symbol); } else if (luaL_checkudata_ex(L, index, REF_METATABLE)) { cbson_ref_t* ref = check_cbson_ref(L, index); bson_oid_t boid; bson_oid_init_from_string (&boid, ref->id); BSON_APPEND_DBPOINTER(bson, key, ref->ref, &boid); } else if (luaL_checkudata_ex(L, index, MINKEY_METATABLE)) { check_cbson_minkey(L, index); BSON_APPEND_MINKEY(bson, key); } else if (luaL_checkudata_ex(L, index, MAXKEY_METATABLE)) { check_cbson_maxkey(L, index); BSON_APPEND_MAXKEY(bson, key); } else if (luaL_checkudata_ex(L, index, TIMESTAMP_METATABLE)) { cbson_timestamp_t* time = check_cbson_timestamp(L, index); BSON_APPEND_TIMESTAMP(bson, key, time->timestamp, time->increment); } else if (luaL_checkudata_ex(L, index, INT64_METATABLE) || luaL_checkudata_ex(L, index, UINT64_METATABLE)) { cbson_int64_t i = cbson_int64_check(L, index); if (i < INT32_MIN || i > INT32_MAX) { BSON_APPEND_INT64(bson, key, i); } else { BSON_APPEND_INT32(bson, key, (int32_t)i); } } else if (luaL_checkudata_ex(L, index, CODE_METATABLE)) { cbson_code_t* code = check_cbson_code(L, index); BSON_APPEND_CODE(bson, key, code->code); } else if (luaL_checkudata_ex(L, index, CODEWSCOPE_METATABLE)) { cbson_codewscope_t* code = check_cbson_codewscope(L, index); BSON_APPEND_CODE_WITH_SCOPE(bson, key, code->code, NULL); } else if (luaL_checkudata_ex(L, index, UNDEFINED_METATABLE)) { check_cbson_undefined(L, index); BSON_APPEND_UNDEFINED(bson, key); } else if (luaL_checkudata_ex(L, index, DATE_METATABLE)) { BSON_APPEND_DATE_TIME(bson, key, cbson_date_check(L, index)); } break; } case LUA_TFUNCTION: case LUA_TTHREAD: case LUA_TLIGHTUSERDATA: default: break; // or bail out? } }
static int _bson_json_read_string (void *_ctx, /* IN */ const unsigned char *val, /* IN */ size_t vlen) /* IN */ { bson_json_read_state_t rs; bson_json_read_bson_state_t bs; BASIC_YAJL_CB_PREAMBLE; rs = bson->read_state; bs = bson->bson_state; if (rs == BSON_JSON_REGULAR) { bson_append_utf8 (STACK_BSON_CHILD, key, (int)len, (const char *)val, (int)vlen); } else if (rs == BSON_JSON_IN_BSON_TYPE || rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) { const char *val_w_null; _bson_json_buf_set (&bson->bson_type_buf[2], val, vlen, true); val_w_null = (const char *)bson->bson_type_buf[2].buf; switch (bs) { case BSON_JSON_LF_REGEX: bson->bson_type_data.regex.has_regex = true; _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen, true); break; case BSON_JSON_LF_OPTIONS: bson->bson_type_data.regex.has_options = true; _bson_json_buf_set (&bson->bson_type_buf[1], val, vlen, true); break; case BSON_JSON_LF_OID: if (vlen != 24) { goto BAD_PARSE; } bson->bson_type_data.oid.has_oid = true; bson_oid_init_from_string (&bson->bson_type_data.oid.oid, val_w_null); break; case BSON_JSON_LF_TYPE: bson->bson_type_data.binary.has_subtype = true; #ifdef _WIN32 # define SSCANF sscanf_s #else # define SSCANF sscanf #endif if (SSCANF (val_w_null, "%02x", &bson->bson_type_data.binary.type) != 1) { goto BAD_PARSE; } #undef SSCANF break; case BSON_JSON_LF_BINARY: { /* TODO: error handling for pton */ int binary_len; bson->bson_type_data.binary.has_binary = true; binary_len = b64_pton (val_w_null, NULL, 0); _bson_json_buf_ensure (&bson->bson_type_buf[0], binary_len + 1); b64_pton ((char *)bson->bson_type_buf[2].buf, bson->bson_type_buf[0].buf, binary_len + 1); bson->bson_type_buf[0].len = binary_len; break; } case BSON_JSON_LF_REF: bson->bson_type_data.ref.has_ref = true; _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen, true); break; case BSON_JSON_LF_ID: if (vlen != 24) { goto BAD_PARSE; } bson->bson_type_data.ref.has_id = true; bson_oid_init_from_string (&bson->bson_type_data.ref.id, val_w_null); break; case BSON_JSON_LF_INT64: { int64_t v64; char *endptr = NULL; errno = 0; v64 = bson_ascii_strtoll ((const char *)val, &endptr, 10); if (((v64 == INT64_MIN) || (v64 == INT64_MAX)) && (errno == ERANGE)) { goto BAD_PARSE; } if (endptr != ((const char *)val + vlen)) { goto BAD_PARSE; } bson_append_int64 (STACK_BSON_CHILD, key, (int)len, v64); } break; case BSON_JSON_LF_DATE: case BSON_JSON_LF_TIMESTAMP_T: case BSON_JSON_LF_TIMESTAMP_I: case BSON_JSON_LF_UNDEFINED: case BSON_JSON_LF_MINKEY: case BSON_JSON_LF_MAXKEY: default: goto BAD_PARSE; } return 1; BAD_PARSE: _bson_json_read_set_error (reader, "Invalid input string %s, looking for %d", val_w_null, bs); return 0; } else { _bson_json_read_set_error (reader, "Invalid state to look for string %d", rs); return 0; } return 1; }
int decode_hybi(unsigned char *src, size_t srclength, u_char *target, size_t targsize, unsigned int *opcode, unsigned int *left) { unsigned char *frame, *mask, *payload, save_char, cntstr[4];; int masked = 0; int i = 0, len, framecount = 0; size_t remaining; unsigned int target_offset = 0, hdr_length = 0, payload_length = 0; *left = srclength; frame = src; //printf("Deocde new frame\n"); while (1) { // Need at least two bytes of the header // Find beginning of next frame. First time hdr_length, masked and // payload_length are zero frame += hdr_length + 4*masked + payload_length; //printf("frame[0..3]: 0x%x 0x%x 0x%x 0x%x (tot: %d)\n", // (unsigned char) frame[0], // (unsigned char) frame[1], // (unsigned char) frame[2], // (unsigned char) frame[3], srclength); if (frame > src + srclength) { //printf("Truncated frame from client, need %d more bytes\n", frame - (src + srclength) ); break; } remaining = (src + srclength) - frame; if (remaining < 2) { //printf("Truncated frame header from client\n"); break; } framecount ++; *opcode = frame[0] & 0x0f; masked = (frame[1] & 0x80) >> 7; if (*opcode == 0x8) { // client sent orderly close frame break; } payload_length = frame[1] & 0x7f; if (payload_length < 126) { hdr_length = 2; //frame += 2 * sizeof(char); } else if (payload_length == 126) { payload_length = (frame[2] << 8) + frame[3]; hdr_length = 4; } else { handler_emsg("Receiving frames larger than 65535 bytes not supported\n"); return -1; } if ((hdr_length + 4*masked + payload_length) > remaining) { continue; } //printf(" payload_length: %u, raw remaining: %u\n", payload_length, remaining); payload = frame + hdr_length + 4*masked; if (*opcode != 1 && *opcode != 2) { handler_msg("Ignoring non-data frame, opcode 0x%x\n", *opcode); continue; } if (payload_length == 0) { handler_msg("Ignoring empty frame\n"); continue; } if ((payload_length > 0) && (!masked)) { handler_emsg("Received unmasked payload from client\n"); return -1; } // Terminate with a null for base64 decode save_char = payload[payload_length]; payload[payload_length] = '\0'; // unmask the data mask = payload - 4; for (i = 0; i < payload_length; i++) { payload[i] ^= mask[i%4]; } // base64 decode the data len = b64_pton((const char*)payload, target+target_offset, targsize); // Restore the first character of the next frame payload[payload_length] = save_char; if (len < 0) { handler_emsg("Base64 decode error code %d", len); return len; } target_offset += len; //printf(" len %d, raw %s\n", len, frame); } if (framecount > 1) { snprintf(cntstr, 3, "%d", framecount); traffic(cntstr); } *left = remaining; return target_offset; }
static DST_KEY * dst_s_read_public_key(const char *in_name, const u_int16_t in_id, int in_alg) { int flags, proto, alg, len, dlen; int c; char name[PATH_MAX], enckey[RAW_KEY_SIZE], *notspace; u_char deckey[RAW_KEY_SIZE]; FILE *fp; if (in_name == NULL) { EREPORT(("dst_read_public_key(): No key name given\n")); return (NULL); } if (dst_s_build_filename(name, in_name, in_id, in_alg, PUBLIC_KEY, PATH_MAX) == -1) { EREPORT(("dst_read_public_key(): Cannot make filename from %s, %d, and %s\n", in_name, in_id, PUBLIC_KEY)); return (NULL); } /* * Open the file and read it's formatted contents up to key * File format: * domain.name [ttl] [IN] KEY <flags> <protocol> <algorithm> <key> * flags, proto, alg stored as decimal (or hex numbers FIXME). * (FIXME: handle parentheses for line continuation.) */ if ((fp = dst_s_fopen(name, "r", 0)) == NULL) { EREPORT(("dst_read_public_key(): Public Key not found %s\n", name)); return (NULL); } /* Skip domain name, which ends at first blank */ while ((c = getc(fp)) != EOF) if (isspace(c)) break; /* Skip blank to get to next field */ while ((c = getc(fp)) != EOF) if (!isspace(c)) break; /* Skip optional TTL -- if initial digit, skip whole word. */ if (isdigit(c)) { while ((c = getc(fp)) != EOF) if (isspace(c)) break; while ((c = getc(fp)) != EOF) if (!isspace(c)) break; } /* Skip optional "IN" */ if (c == 'I' || c == 'i') { while ((c = getc(fp)) != EOF) if (isspace(c)) break; while ((c = getc(fp)) != EOF) if (!isspace(c)) break; } /* Locate and skip "KEY" */ if (c != 'K' && c != 'k') { EREPORT(("\"KEY\" doesn't appear in file: %s", name)); return NULL; } while ((c = getc(fp)) != EOF) if (isspace(c)) break; while ((c = getc(fp)) != EOF) if (!isspace(c)) break; ungetc(c, fp); /*%< return the charcter to the input field */ /* Handle hex!! FIXME. */ if (fscanf(fp, "%d %d %d", &flags, &proto, &alg) != 3) { EREPORT(("dst_read_public_key(): Can not read flag/proto/alg field from %s\n" ,name)); return (NULL); } /* read in the key string */ fgets(enckey, sizeof(enckey), fp); /* If we aren't at end-of-file, something is wrong. */ while ((c = getc(fp)) != EOF) if (!isspace(c)) break; if (!feof(fp)) { EREPORT(("Key too long in file: %s", name)); return NULL; } fclose(fp); if ((len = strlen(enckey)) <= 0) return (NULL); /* discard \n */ enckey[--len] = '\0'; /* remove leading spaces */ for (notspace = (char *) enckey; isspace((*notspace)&0xff); len--) notspace++; dlen = b64_pton(notspace, deckey, sizeof(deckey)); if (dlen < 0) { EREPORT(("dst_read_public_key: bad return from b64_pton = %d", dlen)); return (NULL); } /* store key and info in a key structure that is returned */ /* return dst_store_public_key(in_name, alg, proto, 666, flags, deckey, dlen);*/ return dst_buffer_to_key(in_name, alg, flags, proto, deckey, dlen); }
/* Print to stdout detailed session summary */ hash_stat print_session_detailed(char *sessionname) { #ifdef HAVE_JSON_JSON_H FILE *sesfile; struct passwd *pwd; char sesname[1024]; int cnt=0; char username[HASHFILE_MAX_LINE_LENGTH]; char hash[HASHFILE_MAX_LINE_LENGTH]; char rawhash[HASHFILE_MAX_LINE_LENGTH]; char rawhash2[HASHFILE_MAX_LINE_LENGTH*2]; char plugin_used[HASHFILE_MAX_LINE_LENGTH*2]; char salt[HASHFILE_MAX_LINE_LENGTH]; int flag = 0; json_object *jobj; printf("\nDetailed information about session: %s\n" "-----------------------------------------------\n",sessionname); pwd = getpwuid(getuid()); snprintf(sesname, 1024, "%s/.hashkill/sessions/%s.session", pwd->pw_dir, sessionname); /* Parse the <session>..</session> info */ sesfile = fopen(sesname, "r"); if (!sesfile) { elog("Cannot open session file : %s\n",sesname); return hash_err; } printf("Session file: \t%s\n",sesname); fclose(sesfile); root_node = json_object_from_file(sesname); main_header_node = json_object_object_get(root_node,"main"); switch (json_object_get_int(json_object_object_get(main_header_node,"attacktype"))) { case attack_method_simple_bruteforce: printf("Attack type: \tBruteforce\n"); break; case attack_method_markov: printf("Attack type: \tMarkov\n"); break; case attack_method_rule: printf("Attack type: \tRule-based\n"); break; default: printf("Attack type: \tUNKNOWN!\n"); break; } attack_method=json_object_get_int(json_object_object_get(main_header_node,"attacktype")); printf("Plugin: \t%s\n",json_object_get_string(json_object_object_get(main_header_node,"plugin"))); printf("Progress: \t%d%%\n",json_object_get_int(json_object_object_get(main_header_node,"progress"))); printf("Session ends: \t%s",json_object_get_string(json_object_object_get(main_header_node,"timestamp"))); printf("Hashlist file: \t%s\n",json_object_get_string(json_object_object_get(main_header_node,"hashlistfile"))); printf("Command line: \t%s\n",json_object_get_string(json_object_object_get(main_header_node,"commandline"))); switch (attack_method) { case attack_method_simple_bruteforce: attack_header_node = json_object_object_get(root_node,"bruteforce"); printf("\nBruteforce attack parameters:\n" "-----------------------------\n"); printf("Start length: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"start"))); printf("End length: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"end"))); printf("Charset: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"charset"))); printf("Current str: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"currentstr"))); break; case attack_method_markov: attack_header_node = json_object_object_get(root_node,"markov"); printf("\nMarkov attack parameters:\n" "-------------------------\n"); printf("Statfile: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"statfile"))); printf("Threshold: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"threshold"))); printf("End length: \t%d\n",json_object_get_int(json_object_object_get(attack_header_node,"maxlen"))); printf("Current str: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"currentstr"))); break; case attack_method_rule: attack_header_node = json_object_object_get(root_node,"rule"); printf("\nRule attack parameters:\n" "-----------------------\n"); printf("Rule file: \t%s\n",json_object_get_string(json_object_object_get(attack_header_node,"rulefile"))); break; } printf("\nHashes list (username:hash:salt):\n---------------------------------\n"); hash_list_node = json_object_object_get(root_node,"hashlist"); flag = json_object_array_length(hash_list_node); for (cnt=0;cnt<flag;cnt++) { jobj = json_object_array_get_idx(hash_list_node, cnt); strcpy(username, json_object_get_string(json_object_object_get(jobj,"username"))); strcpy(hash, json_object_get_string(json_object_object_get(jobj,"hash"))); strcpy(salt, json_object_get_string(json_object_object_get(jobj,"salt"))); // This is idiotic I know if ((strncmp(plugin_used,"md5unix",8)==0) || (strncmp(plugin_used,"sha512unix",10)==0) ||(strncmp(plugin_used,"phpbb3",6)==0) || (strncmp(plugin_used,"wordpress",9)==0) || (strncmp(plugin_used,"apr1",4)==0)) { b64_pton(hash,(unsigned char *)rawhash,512); printf("%s:%s%s\n", username, salt, rawhash); } else if ( (strncmp(plugin_used,"desunix",7)==0) || (strncmp(plugin_used,"ldap-sha",8)==0) || (strncmp(plugin_used,"ldap-ssha",9)==0)) { b64_pton(hash,(unsigned char *)rawhash,512); printf("%s:%s:%s\n", username, rawhash, salt); } else { str2hex(rawhash,rawhash2, (strlen(hash)*100)/147); printf("%s:%s:%s\n", username, rawhash2, salt); } } cracked_list_node = json_object_object_get(root_node,"crackedlist"); if (cracked_list_node) { cnt = json_object_array_length(cracked_list_node); } else { cnt=0; } printf("\n%d passwords cracked.\n",cnt); printf("\n"); hlog("Session %s dumped successfully\n\n", sessionname); return hash_ok; #else wlog("This build does not support sessions. Please reconfigure with --with-json and rebuild%s\n",""); return hash_err; #endif }
TEST(resolv, b64_pton) { u_char buf[128]; memset(buf, 'x', sizeof(buf)); ASSERT_EQ(static_cast<int>(strlen("hello")), b64_pton("aGVsbG8=", buf, sizeof(buf))); ASSERT_STREQ(reinterpret_cast<char*>(buf), "hello"); }
int main(int argc, char **argv) { short port = htons(NAMESERVER_PORT); short lport; /* Wierd stuff for SPARC alignment, hurts nothing else. */ union { HEADER header_; u_char packet_[PACKETSZ]; } packet_; #define header (packet_.header_) #define packet (packet_.packet_) union { HEADER u; u_char b[NS_MAXMSG]; } answer; int n; char doping[90]; char pingstr[50]; char *afile; char *addrc, *addrend, *addrbegin; time_t exectime; struct timeval tv1, tv2, start_time, end_time, query_time; char *srv; int anyflag = 0; int sticky = 0; int tmp; int qtypeSet; ns_type xfr = ns_t_invalid; int bytes_out, bytes_in; char cmd[512]; char domain[MAXDNAME]; char msg[120], **vtmp; char *args[DIG_MAXARGS]; char **ax; int once = 1, dofile = 0; /* batch -vs- interactive control */ char fileq[384]; int fp; int wait=0, delay; int envset=0, envsave=0; struct __res_state res_x, res_t; int r; struct in6_addr in6; ns_tsig_key key; char *keyfile = NULL, *keyname = NULL; const char *pingfmt = NULL; UNUSED(argc); res_ninit(&res); res.pfcode = PRF_DEF; qtypeSet = 0; memset(domain, 0, sizeof domain); gethostname(myhostname, (sizeof myhostname)); #ifdef HAVE_SA_LEN myaddress.sin_len = sizeof(struct sockaddr_in); #endif myaddress.sin_family = AF_INET; myaddress.sin_addr.s_addr = INADDR_ANY; myaddress.sin_port = 0; /*INPORT_ANY*/; #ifdef HAVE_SA_LEN myaddress6.sin6_len = sizeof(struct sockaddr_in6); #endif myaddress6.sin6_family = AF_INET6; myaddress6.sin6_addr = in6addr_any; myaddress6.sin6_port = 0; /*INPORT_ANY*/; res_x = res; /* * If LOCALDEF in environment, should point to file * containing local favourite defaults. Also look for file * DiG.env (i.e. SAVEENV) in local directory. */ if ((((afile = (char *) getenv("LOCALDEF")) != (char *) NULL) && ((fp = open(afile, O_RDONLY)) > 0)) || ((fp = open(SAVEENV, O_RDONLY)) > 0)) { read(fp, (char *)&res_x, (sizeof res_x)); close(fp); res = res_x; } /* * Check for batch-mode DiG; also pre-scan for 'help'. */ vtmp = argv; ax = args; while (*vtmp != NULL) { if (strcmp(*vtmp, "-h") == 0 || strcmp(*vtmp, "-help") == 0 || strcmp(*vtmp, "-usage") == 0 || strcmp(*vtmp, "help") == 0) { Usage(); exit(0); } if (strcmp(*vtmp, "-f") == 0) { dofile++; once=0; if ((qfp = fopen(*++vtmp, "r")) == NULL) { fflush(stdout); perror("file open"); fflush(stderr); exit(10); } } else { if (ax - args == DIG_MAXARGS) { fprintf(stderr, "dig: too many arguments\n"); exit(10); } *ax++ = *vtmp; } vtmp++; } gettimeofday(&tv1, NULL); /* * Main section: once if cmd-line query * while !EOF if batch mode */ *fileq = '\0'; while ((dofile && fgets(fileq, sizeof fileq, qfp) != NULL) || (!dofile && once--)) { if (*fileq == '\n' || *fileq == '#' || *fileq==';') { printf("%s", fileq); /* echo but otherwise ignore */ continue; /* blank lines and comments */ } /* * "Sticky" requests that before current parsing args * return to current "working" environment (X******). */ if (sticky) { printf(";; (using sticky settings)\n"); res = res_x; } /* * Concat cmd-line and file args. */ stackarg(fileq, ax); /* defaults */ queryType = ns_t_ns; queryClass = ns_c_in; xfr = ns_t_invalid; *pingstr = 0; srv = NULL; sprintf(cmd, "\n; <<>> DiG %s (libbind %d) <<>> ", VSTRING, __RES); argv = args; /* argc = ax - args; */ /* * More cmd-line options than anyone should ever have to * deal with .... */ while (*(++argv) != NULL && **argv != '\0') { if (strlen(cmd) + strlen(*argv) + 2 > sizeof (cmd)) { fprintf(stderr, "Argument too large for input buffer\n"); exit(1); } strcat(cmd, *argv); strcat(cmd, " "); if (**argv == '@') { srv = (*argv+1); continue; } if (**argv == '%') continue; if (**argv == '+') { setopt(*argv+1); continue; } if (**argv == '=') { ixfr_serial = strtoul(*argv+1, NULL, 0); continue; } if (strncmp(*argv, "-nost", 5) == 0) { sticky = 0; continue; } else if (strncmp(*argv, "-st", 3) == 0) { sticky++; continue; } else if (strncmp(*argv, "-envsa", 6) == 0) { envsave++; continue; } else if (strncmp(*argv, "-envse", 6) == 0) { envset++; continue; } if (**argv == '-') { switch (argv[0][1]) { case 'T': if (*++argv == NULL) printf("; no arg for -T?\n"); else wait = atoi(*argv); break; case 'c': if(*++argv == NULL) printf("; no arg for -c?\n"); else if ((tmp = atoi(*argv)) || *argv[0] == '0') { queryClass = tmp; } else if ((tmp = StringToClass(*argv, 0, NULL) ) != 0) { queryClass = tmp; } else { printf( "; invalid class specified\n" ); } break; case 't': if (*++argv == NULL) printf("; no arg for -t?\n"); else if ((tmp = atoi(*argv)) || *argv[0]=='0') { if (ns_t_xfr_p(tmp)) { xfr = tmp; } else { queryType = tmp; qtypeSet++; } } else if ((tmp = StringToType(*argv, 0, NULL) ) != 0) { if (ns_t_xfr_p(tmp)) { xfr = tmp; } else { queryType = tmp; qtypeSet++; } } else { printf( "; invalid type specified\n" ); } break; case 'x': if (!qtypeSet) { queryType = T_ANY; qtypeSet++; } if ((addrc = *++argv) == NULL) { printf("; no arg for -x?\n"); break; } r = inet_pton(AF_INET6, addrc, &in6); if (r > 0) { reverse6(domain, &in6); break; } addrend = addrc + strlen(addrc); if (*addrend == '.') *addrend = '\0'; *domain = '\0'; while ((addrbegin = strrchr(addrc,'.'))) { strcat(domain, addrbegin+1); strcat(domain, "."); *addrbegin = '\0'; } strcat(domain, addrc); strcat(domain, ".in-addr.arpa."); break; case 'p': if (argv[0][2] != '\0') port = htons(atoi(argv[0]+2)); else if (*++argv == NULL) printf("; no arg for -p?\n"); else port = htons(atoi(*argv)); break; case 'P': if (argv[0][2] != '\0') { strcpy(pingstr, argv[0]+2); pingfmt = "%s %s 56 3 | %s -3"; } else { strcpy(pingstr, DIG_PING); pingfmt = DIG_PINGFMT; } break; case 'n': if (argv[0][2] != '\0') res.ndots = atoi(argv[0]+2); else if (*++argv == NULL) printf("; no arg for -n?\n"); else res.ndots = atoi(*argv); break; case 'b': { char *a, *p; if (argv[0][2] != '\0') a = argv[0]+2; else if (*++argv == NULL) { printf("; no arg for -b?\n"); break; } else a = *argv; if ((p = strchr(a, ':')) != NULL) { *p++ = '\0'; lport = htons(atoi(p)); } else lport = htons(0); if (inet_pton(AF_INET6, a, &myaddress6.sin6_addr) == 1) { myaddress6.sin6_port = lport; } else if (!inet_aton(a, &myaddress.sin_addr)) { fprintf(stderr, ";; bad -b addr\n"); exit(1); } else myaddress.sin_port = lport; } break; case 'k': /* -k keydir:keyname */ if (argv[0][2] != '\0') keyfile = argv[0]+2; else if (*++argv == NULL) { printf("; no arg for -k?\n"); break; } else keyfile = *argv; keyname = strchr(keyfile, ':'); if (keyname == NULL) { fprintf(stderr, "key option argument should be keydir:keyname\n"); exit(1); } *keyname++='\0'; break; } /* switch - */ continue; } /* if '-' */ if ((tmp = StringToType(*argv, -1, NULL)) != -1) { if ((T_ANY == tmp) && anyflag++) { queryClass = C_ANY; continue; } if (ns_t_xfr_p(tmp) && (tmp == ns_t_axfr || (res.options & RES_USEVC) != 0) ) { res.pfcode = PRF_ZONE; xfr = (ns_type)tmp; } else { queryType = tmp; qtypeSet++; } } else if ((tmp = StringToClass(*argv, -1, NULL)) != -1) { queryClass = tmp; } else { memset(domain, 0, sizeof domain); sprintf(domain,"%s",*argv); } } /* while argv remains */ /* process key options */ if (keyfile) { #ifdef PARSE_KEYFILE int i, n1; char buf[BUFSIZ], *p; FILE *fp = NULL; int file_major, file_minor, alg; fp = fopen(keyfile, "r"); if (fp == NULL) { perror(keyfile); exit(1); } /* Now read the header info from the file. */ i = fread(buf, 1, BUFSIZ, fp); if (i < 5) { fclose(fp); exit(1); } fclose(fp); p = buf; n=strlen(p); /* get length of strings */ n1=strlen("Private-key-format: v"); if (n1 > n || strncmp(buf, "Private-key-format: v", n1)) { fprintf(stderr, "Invalid key file format\n"); exit(1); /* not a match */ } p+=n1; /* advance pointer */ sscanf((char *)p, "%d.%d", &file_major, &file_minor); /* should do some error checking with these someday */ while (*p++!='\n'); /* skip to end of line */ n=strlen(p); /* get length of strings */ n1=strlen("Algorithm: "); if (n1 > n || strncmp(p, "Algorithm: ", n1)) { fprintf(stderr, "Invalid key file format\n"); exit(1); /* not a match */ } p+=n1; /* advance pointer */ if (sscanf((char *)p, "%d", &alg)!=1) { fprintf(stderr, "Invalid key file format\n"); exit(1); } while (*p++!='\n'); /* skip to end of line */ n=strlen(p); /* get length of strings */ n1=strlen("Key: "); if (n1 > n || strncmp(p, "Key: ", n1)) { fprintf(stderr, "Invalid key file format\n"); exit(1); /* not a match */ } p+=n1; /* advance pointer */ pp=p; while (*pp++!='\n'); /* skip to end of line, * terminate it */ *--pp='\0'; key.data=malloc(1024*sizeof(char)); key.len=b64_pton(p, key.data, 1024); strcpy(key.name, keyname); strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT"); #else /* use the dst* routines to parse the key files * * This requires that both the .key and the .private * files exist in your cwd, so the keyfile parmeter * here is assumed to be a path in which the * K*.{key,private} files exist. */ DST_KEY *dst_key; char cwd[PATH_MAX+1]; if (getcwd(cwd, PATH_MAX)==NULL) { perror("unable to get current directory"); exit(1); } if (chdir(keyfile)<0) { fprintf(stderr, "unable to chdir to %s: %s\n", keyfile, strerror(errno)); exit(1); } dst_init(); dst_key = dst_read_key(keyname, 0 /* not used for priv keys */, KEY_HMAC_MD5, DST_PRIVATE); if (!dst_key) { fprintf(stderr, "dst_read_key: error reading key\n"); exit(1); } key.data=malloc(1024*sizeof(char)); dst_key_to_buffer(dst_key, key.data, 1024); key.len=dst_key->dk_key_size; strcpy(key.name, keyname); strcpy(key.alg, "HMAC-MD5.SIG-ALG.REG.INT"); if (chdir(cwd)<0) { fprintf(stderr, "unable to chdir to %s: %s\n", cwd, strerror(errno)); exit(1); } #endif } if (res.pfcode & 0x80000) printf("; pfcode: %08lx, options: %08lx\n", (unsigned long)res.pfcode, (unsigned long)res.options); /* * Current env. (after this parse) is to become the * new "working" environmnet. Used in conj. with sticky. */ if (envset) { res_x = res; envset = 0; } /* * Current env. (after this parse) is to become the * new default saved environmnet. Save in user specified * file if exists else is SAVEENV (== "DiG.env"). */ if (envsave) { afile = (char *) getenv("LOCALDEF"); if ((afile && ((fp = open(afile, O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) > 0)) || ((fp = open(SAVEENV, O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE)) > 0)) { write(fp, (char *)&res, (sizeof res)); close(fp); } envsave = 0; } if (res.pfcode & RES_PRF_CMD) printf("%s\n", cmd); anyflag = 0; /* * Find address of server to query. If not dot-notation, then * try to resolve domain-name (if so, save and turn off print * options, this domain-query is not the one we want. Restore * user options when done. * Things get a bit wierd since we need to use resolver to be * able to "put the resolver to work". */ if (srv != NULL) { int nscount = 0; union res_sockaddr_union u[MAXNS]; struct addrinfo *answer = NULL; struct addrinfo *cur = NULL; struct addrinfo hint; memset(u, 0, sizeof(u)); res_t = res; res_ninit(&res); res.pfcode = 0; res.options = RES_DEFAULT; memset(&hint, 0, sizeof(hint)); hint.ai_socktype = SOCK_DGRAM; if (!getaddrinfo(srv, NULL, &hint, &answer)) { res = res_t; cur = answer; for (cur = answer; cur != NULL; cur = cur->ai_next) { if (nscount == MAXNS) break; switch (cur->ai_addr->sa_family) { case AF_INET6: u[nscount].sin6 = *(struct sockaddr_in6*)cur->ai_addr; u[nscount++].sin6.sin6_port = port; break; case AF_INET: u[nscount].sin = *(struct sockaddr_in*)cur->ai_addr; u[nscount++].sin.sin_port = port; break; } } if (nscount != 0) res_setservers(&res, u, nscount); freeaddrinfo(answer); } else { res = res_t; fflush(stdout); fprintf(stderr, "; Bad server: %s -- using default server and timer opts\n", srv); fflush(stderr); srv = NULL; } printf("; (%d server%s found)\n", res.nscount, (res.nscount==1)?"":"s"); res.id += res.retry; } if (ns_t_xfr_p(xfr)) { int i; int nscount; union res_sockaddr_union u[MAXNS]; nscount = res_getservers(&res, u, MAXNS); for (i = 0; i < nscount; i++) { int x; if (keyfile) x = printZone(xfr, domain, &u[i].sin, &key); else x = printZone(xfr, domain, &u[i].sin, NULL); if (res.pfcode & RES_PRF_STATS) { exectime = time(NULL); printf(";; FROM: %s to SERVER: %s\n", myhostname, p_sockun(u[i], ubuf, sizeof(ubuf))); printf(";; WHEN: %s", ctime(&exectime)); } if (!x) break; /* success */ } fflush(stdout); continue; } if (*domain && !qtypeSet) { queryType = T_A; qtypeSet++; } bytes_out = n = res_nmkquery(&res, QUERY, domain, queryClass, queryType, NULL, 0, NULL, packet, sizeof packet); if (n < 0) { fflush(stderr); printf(";; res_nmkquery: buffer too small\n\n"); fflush(stdout); continue; } if (queryType == T_IXFR) { HEADER *hp = (HEADER *) packet; u_char *cpp = packet + bytes_out; hp->nscount = htons(1+ntohs(hp->nscount)); n = dn_comp(domain, cpp, (sizeof packet) - (cpp - packet), NULL, NULL); cpp += n; PUTSHORT(T_SOA, cpp); /* type */ PUTSHORT(C_IN, cpp); /* class */ PUTLONG(0, cpp); /* ttl */ PUTSHORT(22, cpp); /* dlen */ *cpp++ = 0; /* mname */ *cpp++ = 0; /* rname */ PUTLONG(ixfr_serial, cpp); PUTLONG(0xDEAD, cpp); /* Refresh */ PUTLONG(0xBEEF, cpp); /* Retry */ PUTLONG(0xABCD, cpp); /* Expire */ PUTLONG(0x1776, cpp); /* Min TTL */ bytes_out = n = cpp - packet; }; #if defined(RES_USE_EDNS0) && defined(RES_USE_DNSSEC) if (n > 0 && (res.options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) bytes_out = n = res_nopt(&res, n, packet, sizeof(packet), 4096); #endif eecode = 0; if (res.pfcode & RES_PRF_HEAD1) fp_resstat(&res, stdout); (void) gettimeofday(&start_time, NULL); if (keyfile) n = res_nsendsigned(&res, packet, n, &key, answer.b, sizeof(answer.b)); else n = res_nsend(&res, packet, n, answer.b, sizeof(answer.b)); if ((bytes_in = n) < 0) { fflush(stdout); n = 0 - n; if (keyfile) strcpy(msg, ";; res_nsendsigned"); else strcpy(msg, ";; res_nsend"); perror(msg); fflush(stderr); if (!dofile) { if (eecode) exit(eecode); else exit(9); } } (void) gettimeofday(&end_time, NULL); if (res.pfcode & RES_PRF_STATS) { union res_sockaddr_union u[MAXNS]; (void) res_getservers(&res, u, MAXNS); query_time = difftv(start_time, end_time); printf(";; Total query time: "); prnttime(query_time); putchar('\n'); exectime = time(NULL); printf(";; FROM: %s to SERVER: %s\n", myhostname, p_sockun(u[RES_GETLAST(res)], ubuf, sizeof(ubuf))); printf(";; WHEN: %s", ctime(&exectime)); printf(";; MSG SIZE sent: %d rcvd: %d\n", bytes_out, bytes_in); } fflush(stdout); /* * Argh ... not particularly elegant. Should put in *real* ping code. * Would necessitate root priviledges for icmp port though! */ if (*pingstr && srv != NULL) { sprintf(doping, pingfmt, pingstr, srv, DIG_TAIL); system(doping); } putchar('\n'); /* * Fairly crude method and low overhead method of keeping two * batches started at different sites somewhat synchronized. */ gettimeofday(&tv2, NULL); delay = (int)(tv2.tv_sec - tv1.tv_sec); if (delay < wait) { sleep(wait - delay); } tv1 = tv2; } return (eecode); }
/*% * Form update packets. * Returns the size of the resulting packet if no error * * On error, * returns *\li -1 if error in reading a word/number in rdata * portion for update packets *\li -2 if length of buffer passed is insufficient *\li -3 if zone section is not the first section in * the linked list, or section order has a problem *\li -4 on a number overflow *\li -5 unknown operation or no records */ int res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) { ns_updrec *rrecp_start = rrecp_in; HEADER *hp; u_char *cp, *sp2, *startp, *endp; int n, i, soanum, multiline; ns_updrec *rrecp; struct in_addr ina; struct in6_addr in6a; char buf2[MAXDNAME]; u_char buf3[MAXDNAME]; int section, numrrs = 0, counts[ns_s_max]; u_int16_t rtype, rclass; u_int32_t n1, rttl; u_char *dnptrs[20], **dpp, **lastdnptr; int siglen, keylen, certlen; /* * Initialize header fields. */ if ((buf == NULL) || (buflen < HFIXEDSZ)) return (-1); memset(buf, 0, HFIXEDSZ); hp = (HEADER *) buf; hp->id = htons(++statp->id); hp->opcode = ns_o_update; hp->rcode = NOERROR; cp = buf + HFIXEDSZ; buflen -= HFIXEDSZ; dpp = dnptrs; *dpp++ = buf; *dpp++ = NULL; lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; if (rrecp_start == NULL) return (-5); else if (rrecp_start->r_section != S_ZONE) return (-3); memset(counts, 0, sizeof counts); for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) { numrrs++; section = rrecp->r_section; if (section < 0 || section >= ns_s_max) return (-1); counts[section]++; for (i = section + 1; i < ns_s_max; i++) if (counts[i]) return (-3); rtype = rrecp->r_type; rclass = rrecp->r_class; rttl = rrecp->r_ttl; /* overload class and type */ if (section == S_PREREQ) { rttl = 0; switch (rrecp->r_opcode) { case YXDOMAIN: rclass = C_ANY; rtype = T_ANY; rrecp->r_size = 0; break; case NXDOMAIN: rclass = C_NONE; rtype = T_ANY; rrecp->r_size = 0; break; case NXRRSET: rclass = C_NONE; rrecp->r_size = 0; break; case YXRRSET: if (rrecp->r_size == 0) rclass = C_ANY; break; default: fprintf(stderr, "res_mkupdate: incorrect opcode: %d\n", rrecp->r_opcode); fflush(stderr); return (-1); } } else if (section == S_UPDATE) { switch (rrecp->r_opcode) { case DELETE: rclass = rrecp->r_size == 0 ? C_ANY : C_NONE; break; case ADD: break; default: fprintf(stderr, "res_mkupdate: incorrect opcode: %d\n", rrecp->r_opcode); fflush(stderr); return (-1); } } /* * XXX appending default domain to owner name is omitted, * fqdn must be provided */ if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs, lastdnptr)) < 0) return (-1); cp += n; ShrinkBuffer(n + 2*INT16SZ); PUTSHORT(rtype, cp); PUTSHORT(rclass, cp); if (section == S_ZONE) { if (numrrs != 1 || rrecp->r_type != T_SOA) return (-3); continue; } ShrinkBuffer(INT32SZ + INT16SZ); PUTLONG(rttl, cp); sp2 = cp; /*%< save pointer to length byte */ cp += INT16SZ; if (rrecp->r_size == 0) { if (section == S_UPDATE && rclass != C_ANY) return (-1); else { PUTSHORT(0, sp2); continue; } } startp = rrecp->r_data; endp = startp + rrecp->r_size - 1; /* XXX this should be done centrally. */ switch (rrecp->r_type) { case T_A: if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); if (!inet_aton(buf2, &ina)) return (-1); n1 = ntohl(ina.s_addr); ShrinkBuffer(INT32SZ); PUTLONG(n1, cp); break; case T_CNAME: case T_MB: case T_MG: case T_MR: case T_NS: case T_PTR: case ns_t_dname: if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); break; case T_MINFO: case T_SOA: case T_RP: for (i = 0; i < 2; i++) { if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); } if (rrecp->r_type == T_SOA) { ShrinkBuffer(5 * INT32SZ); while (isspace(*startp) || !*startp) startp++; if (*startp == '(') { multiline = 1; startp++; } else multiline = 0; /* serial, refresh, retry, expire, minimum */ for (i = 0; i < 5; i++) { soanum = getnum_str(&startp, endp); if (soanum < 0) return (-1); PUTLONG(soanum, cp); } if (multiline) { while (isspace(*startp) || !*startp) startp++; if (*startp != ')') return (-1); } } break; case T_MX: case T_AFSDB: case T_RT: n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); break; case T_SRV: n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, NULL, NULL); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); break; case T_PX: n = getnum_str(&startp, endp); if (n < 0) return (-1); PUTSHORT(n, cp); ShrinkBuffer(INT16SZ); for (i = 0; i < 2; i++) { if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); } break; case T_WKS: { char bm[MAXPORT/8]; unsigned int maxbm = 0; if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); if (!inet_aton(buf2, &ina)) return (-1); n1 = ntohl(ina.s_addr); ShrinkBuffer(INT32SZ); PUTLONG(n1, cp); if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); if ((i = res_protocolnumber(buf2)) < 0) return (-1); ShrinkBuffer(1); *cp++ = i & 0xff; for (i = 0; i < MAXPORT/8 ; i++) bm[i] = 0; while (getword_str(buf2, sizeof buf2, &startp, endp)) { if ((n = res_servicenumber(buf2)) <= 0) return (-1); if (n < MAXPORT) { bm[n/8] |= (0x80>>(n%8)); if ((unsigned)n > maxbm) maxbm = n; } else return (-1); } maxbm = maxbm/8 + 1; ShrinkBuffer(maxbm); memcpy(cp, bm, maxbm); cp += maxbm; break; } case T_HINFO: for (i = 0; i < 2; i++) { if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) return (-1); if (n > 255) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; } break; case T_TXT: for (;;) { if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) { if (cp != (sp2 + INT16SZ)) break; return (-1); } if (n > 255) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; } break; case T_X25: /* RFC1183 */ if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) return (-1); if (n > 255) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; break; case T_ISDN: /* RFC1183 */ if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) return (-1); if ((n > 255) || (n == 0)) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) n = 0; if (n > 255) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; break; case T_NSAP: if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) { ShrinkBuffer(n); memcpy(cp, buf2, n); cp += n; } else { return (-1); } break; case T_LOC: if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) { ShrinkBuffer(n); memcpy(cp, buf2, n); cp += n; } else return (-1); break; case ns_t_sig: { int sig_type, success, dateerror; u_int32_t exptime, timesigned; /* type */ if ((n = getword_str(buf2, sizeof buf2, &startp, endp)) < 0) return (-1); sig_type = sym_ston(__p_type_syms, buf2, &success); if (!success || sig_type == ns_t_any) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(sig_type, cp); /* alg */ n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(1); *cp++ = n; /* labels */ n = getnum_str(&startp, endp); if (n <= 0 || n > 255) return (-1); ShrinkBuffer(1); *cp++ = n; /* ottl & expire */ if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); exptime = ns_datetosecs(buf2, &dateerror); if (!dateerror) { ShrinkBuffer(INT32SZ); PUTLONG(rttl, cp); } else { char *ulendp; u_int32_t ottl; errno = 0; ottl = strtoul(buf2, &ulendp, 10); if (errno != 0 || (ulendp != NULL && *ulendp != '\0')) return (-1); ShrinkBuffer(INT32SZ); PUTLONG(ottl, cp); if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); exptime = ns_datetosecs(buf2, &dateerror); if (dateerror) return (-1); } /* expire */ ShrinkBuffer(INT32SZ); PUTLONG(exptime, cp); /* timesigned */ if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); timesigned = ns_datetosecs(buf2, &dateerror); if (!dateerror) { ShrinkBuffer(INT32SZ); PUTLONG(timesigned, cp); } else return (-1); /* footprint */ n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); /* signer name */ if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); /* sig */ if ((n = getword_str(buf2, sizeof buf2, &startp, endp)) < 0) return (-1); siglen = b64_pton(buf2, buf3, sizeof(buf3)); if (siglen < 0) return (-1); ShrinkBuffer(siglen); memcpy(cp, buf3, siglen); cp += siglen; break; } case ns_t_key: /* flags */ n = gethexnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); /* proto */ n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(1); *cp++ = n; /* alg */ n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(1); *cp++ = n; /* key */ if ((n = getword_str(buf2, sizeof buf2, &startp, endp)) < 0) return (-1); keylen = b64_pton(buf2, buf3, sizeof(buf3)); if (keylen < 0) return (-1); ShrinkBuffer(keylen); memcpy(cp, buf3, keylen); cp += keylen; break; case ns_t_nxt: { int success, nxt_type; u_char data[32]; int maxtype; /* next name */ if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, NULL, NULL); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); maxtype = 0; memset(data, 0, sizeof data); for (;;) { if (!getword_str(buf2, sizeof buf2, &startp, endp)) break; nxt_type = sym_ston(__p_type_syms, buf2, &success); if (!success || !ns_t_rr_p(nxt_type)) return (-1); NS_NXT_BIT_SET(nxt_type, data); if (nxt_type > maxtype) maxtype = nxt_type; } n = maxtype/NS_NXT_BITS+1; ShrinkBuffer(n); memcpy(cp, data, n); cp += n; break; } case ns_t_cert: /* type */ n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); /* key tag */ n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); /* alg */ n = getnum_str(&startp, endp); if (n < 0) return (-1); ShrinkBuffer(1); *cp++ = n; /* cert */ if ((n = getword_str(buf2, sizeof buf2, &startp, endp)) < 0) return (-1); certlen = b64_pton(buf2, buf3, sizeof(buf3)); if (certlen < 0) return (-1); ShrinkBuffer(certlen); memcpy(cp, buf3, certlen); cp += certlen; break; case ns_t_aaaa: if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); if (inet_pton(AF_INET6, buf2, &in6a) <= 0) return (-1); ShrinkBuffer(NS_IN6ADDRSZ); memcpy(cp, &in6a, NS_IN6ADDRSZ); cp += NS_IN6ADDRSZ; break; case ns_t_naptr: /* Order Preference Flags Service Replacement Regexp */ /* Order */ n = getnum_str(&startp, endp); if (n < 0 || n > 65535) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); /* Preference */ n = getnum_str(&startp, endp); if (n < 0 || n > 65535) return (-1); ShrinkBuffer(INT16SZ); PUTSHORT(n, cp); /* Flags */ if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) { return (-1); } if (n > 255) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; /* Service Classes */ if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) { return (-1); } if (n > 255) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; /* Pattern */ if ((n = getstr_str(buf2, sizeof buf2, &startp, endp)) < 0) { return (-1); } if (n > 255) return (-1); ShrinkBuffer(n+1); *cp++ = n; memcpy(cp, buf2, n); cp += n; /* Replacement */ if (!getword_str(buf2, sizeof buf2, &startp, endp)) return (-1); n = dn_comp(buf2, cp, buflen, NULL, NULL); if (n < 0) return (-1); cp += n; ShrinkBuffer(n); break; default: return (-1); } /*switch*/