/********************************************************************* * * Main Bacula Tray Monitor -- User Interface Program * */ int main(int argc, char *argv[]) { int ch; DIRRES s_dird; CLIENT s_filed; STORE s_stored; char host[250]; char daemon[20]; char monitorname[100]; char pw[200]; int port = 0; char answer[1024]; int retcode = STATE_UNKNOWN; unsigned int i, j; struct MD5Context md5c; unsigned char signature[16]; struct sigaction sigignore; sigignore.sa_flags = 0; sigignore.sa_handler = SIG_IGN; sigfillset(&sigignore.sa_mask); sigaction(SIGPIPE, &sigignore, NULL); strcpy (pw, ""); init_stack_dump(); my_name_is(argc, argv, "check_bacula"); textdomain("bacula"); init_msg(NULL, NULL); while ((ch = getopt(argc, argv, "H:D:M:P:K:d:h?")) != -1) { switch (ch) { case 'H': strcpy (host, optarg); break; case 'D': strcpy (daemon, optarg); break; case 'M': strcpy (monitorname, optarg); break; case 'P': port = atoi(optarg); break; case 'K': strcpy (pw, optarg); break; case 'd': debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } break; case 'h': case '?': default: usage(); exit(1); } } argc -= optind; //argv += optind; if (argc) { usage(); exit(STATE_UNKNOWN); } lmgr_init_thread(); char sig[100]; MD5Init(&md5c); MD5Update(&md5c, (unsigned char *) pw, strlen(pw)); MD5Final(signature, &md5c); for (i = j = 0; i < sizeof(signature); i++) { sprintf(&sig[j], "%02x", signature[i]); j += 2; } /* director ? */ if (strcmp (daemon, "dir") == 0) { if (port != 0) s_dird.DIRport = port; else s_dird.DIRport = 9101; s_dird.address = host; s_dird.password = sig; s_dird.hdr.name = monitorname; mitem.type = R_DIRECTOR; mitem.resource = &s_dird; mitem.D_sock = NULL; } else if (strcmp (daemon, "sd") == 0) { if (port != 0) s_stored.SDport = port; else s_stored.SDport = 9103; s_stored.address = host; s_stored.password = sig; s_stored.hdr.name = monitorname; mitem.type = R_STORAGE; mitem.resource = &s_stored; mitem.D_sock = NULL; } else if (strcmp (daemon, "fd") == 0) { if (port != 0) s_filed.FDport = port; else s_filed.FDport = 9102; s_filed.address = host; s_filed.password = sig; s_filed.hdr.name = monitorname; mitem.type = R_CLIENT; mitem.resource = &s_filed; mitem.D_sock = NULL; } else { usage(); exit(1); } if (mitem.type == R_DIRECTOR) retcode = docmd(&mitem, ".status dir current\n", answer); else retcode = docmd(&mitem, ".status current\n", answer); if (mitem.D_sock) { mitem.D_sock->signal(BNET_TERMINATE); /* send EOF */ mitem.D_sock->close(); } printf ("%s\n", answer); return retcode; }
/* this function sends a packet do TACACS+ server, asking * for validation of given username and password * * return value: * 0 : success * < 0 : error status code, see LIBTAC_STATUS_... * LIBTAC_STATUS_WRITE_ERR * LIBTAC_STATUS_WRITE_TIMEOUT * LIBTAC_STATUS_ASSEMBLY_ERR */ int tac_authen_send(int fd, const char *user, char *pass, char *tty, char *r_addr) { HDR *th; /* TACACS+ packet header */ struct authen_start tb; /* message body */ int user_len, port_len, chal_len, mdp_len, token_len, bodylength, w; int r_addr_len; int pkt_len = 0; int ret = 0; char *chal = "1234123412341234"; char digest[MD5_LEN]; char *token = NULL; u_char *pkt = NULL, *mdp = NULL; MD5_CTX mdcontext; th=_tac_req_header(TAC_PLUS_AUTHEN, 0); /* set some header options */ if ((tac_login != NULL) && (strcmp(tac_login,"login") == 0)) { th->version = TAC_PLUS_VER_0; } else { th->version = TAC_PLUS_VER_1; } th->encryption = tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG; TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', rem_addr '%s', encrypt: %s", \ __FUNCTION__, user, tty, r_addr, \ (tac_encryption) ? "yes" : "no")) if ((tac_login != NULL) && (strcmp(tac_login,"chap") == 0)) { chal_len = strlen(chal); mdp_len = sizeof(u_char) + strlen(pass) + chal_len; mdp = (u_char *) xcalloc(1, mdp_len); mdp[0] = 5; memcpy(&mdp[1], pass, strlen(pass)); memcpy(mdp + strlen(pass) + 1, chal, chal_len); MD5Init(&mdcontext); MD5Update(&mdcontext, mdp, mdp_len); MD5Final((u_char *) digest, &mdcontext); free(mdp); token = (char*) xcalloc(1, sizeof(u_char) + 1 + chal_len + MD5_LEN); token[0] = 5; memcpy(&token[1], chal, chal_len); memcpy(token + chal_len + 1, digest, MD5_LEN); } else { token = xstrdup(pass); } /* get size of submitted data */ user_len = strlen(user); port_len = strlen(tty); r_addr_len = strlen(r_addr); token_len = strlen(token); /* fill the body of message */ tb.action = TAC_PLUS_AUTHEN_LOGIN; tb.priv_lvl = tac_priv_lvl; if (tac_login == NULL) { /* default to PAP */ tb.authen_type = TAC_PLUS_AUTHEN_TYPE_PAP; } else { if (strcmp(tac_login,"chap") == 0) { tb.authen_type = TAC_PLUS_AUTHEN_TYPE_CHAP; } else if (strcmp(tac_login,"login") == 0) { tb.authen_type = TAC_PLUS_AUTHEN_TYPE_ASCII; } else { tb.authen_type = TAC_PLUS_AUTHEN_TYPE_PAP; } } tb.service = tac_authen_service; tb.user_len = user_len; tb.port_len = port_len; tb.r_addr_len = r_addr_len; /* may be e.g Caller-ID in future */ tb.data_len = token_len; /* fill body length in header */ bodylength = sizeof(tb) + user_len + port_len + r_addr_len + token_len; th->datalength = htonl(bodylength); /* we can now write the header */ w = write(fd, th, TAC_PLUS_HDR_SIZE); if (w < 0 || w < TAC_PLUS_HDR_SIZE) { TACSYSLOG((LOG_ERR,\ "%s: short write on header, wrote %d of %d: %m",\ __FUNCTION__, w, TAC_PLUS_HDR_SIZE)) free(token); free(pkt); free(th); return LIBTAC_STATUS_WRITE_ERR; } /* build the packet */ pkt = (u_char *) xcalloc(1, bodylength+10); bcopy(&tb, pkt+pkt_len, sizeof(tb)); /* packet body beginning */ pkt_len += sizeof(tb); bcopy(user, pkt+pkt_len, user_len); /* user */ pkt_len += user_len; bcopy(tty, pkt+pkt_len, port_len); /* tty */ pkt_len += port_len; bcopy(r_addr, pkt+pkt_len, r_addr_len); /* rem addr */ pkt_len += r_addr_len; bcopy(token, pkt+pkt_len, token_len); /* password */ pkt_len += token_len; /* pkt_len == bodylength ? */ if (pkt_len != bodylength) { TACSYSLOG((LOG_ERR, "%s: bodylength %d != pkt_len %d",\ __FUNCTION__, bodylength, pkt_len)) free(token); free(pkt); free(th); return LIBTAC_STATUS_ASSEMBLY_ERR; } /* encrypt the body */ _tac_crypt(pkt, th, bodylength); w = write(fd, pkt, pkt_len); if (w < 0 || w < pkt_len) { TACSYSLOG((LOG_ERR,\ "%s: short write on body, wrote %d of %d: %m",\ __FUNCTION__, w, pkt_len)) ret = LIBTAC_STATUS_WRITE_ERR; } free(token); free(pkt); free(th); TACDEBUG((LOG_DEBUG, "%s: exit status=%d", __FUNCTION__, ret)) return ret; } /* tac_authen_send */
/* * Make a nonce (NUL terminated) * buf -- buffer for result * maxlen -- max length of result * returns final length or -1 on error */ static int digest_nonce(char *buf, int maxlen) { /* * it shouldn't matter too much if two threads step on this counter * at the same time, but mutexing it wouldn't hurt */ static int counter; char *dst; int len; struct chal_info { time_t mytime; unsigned char digest[16]; } cinfo; MD5_CTX ctx; long r; static int set_rand = 0; unsigned char *p; int j; int fd; int got_random; /* initialize challenge */ if (maxlen < 2 * sizeof (cinfo)) return (-1); dst = buf; /* get a timestamp */ time(&cinfo.mytime); /* get some randomness */ got_random = 0; fd = open("/dev/urandom", O_RDONLY); if (fd != -1) { got_random = (read(fd, &r, sizeof (r)) == sizeof (r)); close(fd); } if (!got_random) { if (set_rand == 0) { struct timeval tv; r = cinfo.mytime - (getpid() *65536) + (random() & 0xffff); gettimeofday(&tv, NULL); r ^= tv.tv_usec; r ^= gethostid(); srandom(r); set_rand = 1; } r = random(); } MD5Init(&ctx); MD5Update(&ctx, (unsigned char *) &r, sizeof (r)); MD5Update(&ctx, (unsigned char *) &counter, sizeof (counter)); ++counter; MD5Final(cinfo.digest, &ctx); /* compute hex for result */ for (j = 0, p = (unsigned char *)&cinfo; j < sizeof (cinfo); ++j) { dst[j * 2] = hextab[p[j] >> 4]; dst[j * 2 + 1] = hextab[p[j] & 0xf]; } /* take the entire time_t, plus at least 6 bytes of MD5 output */ len = ((sizeof (time_t) + 6) * 2); dst += len; maxlen -= len; *dst = '\0'; return (dst - buf); }
static Datum uuid_generate_internal(int v, unsigned char *ns, char *ptr, int len) { char strbuf[40]; switch (v) { case 0: /* constant-value uuids */ strlcpy(strbuf, ptr, 37); break; case 1: /* time/node-based uuids */ { #ifdef HAVE_UUID_E2FS uuid_t uu; uuid_generate_time(uu); uuid_unparse(uu, strbuf); /* * PTR, if set, replaces the trailing characters of the uuid; * this is to support v1mc, where a random multicast MAC is * used instead of the physical one */ if (ptr && len <= 36) strcpy(strbuf + (36 - len), ptr); #else /* BSD */ uuid_t uu; uint32_t status = uuid_s_ok; char *str = NULL; uuid_create(&uu, &status); if (status == uuid_s_ok) { uuid_to_string(&uu, &str, &status); if (status == uuid_s_ok) { strlcpy(strbuf, str, 37); /* * PTR, if set, replaces the trailing characters of * the uuid; this is to support v1mc, where a random * multicast MAC is used instead of the physical one */ if (ptr && len <= 36) strcpy(strbuf + (36 - len), ptr); } if (str) free(str); } if (status != uuid_s_ok) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("uuid library failure: %d", (int) status))); #endif break; } case 3: /* namespace-based MD5 uuids */ case 5: /* namespace-based SHA1 uuids */ { dce_uuid_t uu; #ifdef HAVE_UUID_BSD uint32_t status = uuid_s_ok; char *str = NULL; #endif if (v == 3) { MD5_CTX ctx; MD5Init(&ctx); MD5Update(&ctx, ns, sizeof(uu)); MD5Update(&ctx, (unsigned char *) ptr, len); /* we assume sizeof MD5 result is 16, same as UUID size */ MD5Final((unsigned char *) &uu, &ctx); } else { SHA1_CTX ctx; unsigned char sha1result[SHA1_RESULTLEN]; SHA1Init(&ctx); SHA1Update(&ctx, ns, sizeof(uu)); SHA1Update(&ctx, (unsigned char *) ptr, len); SHA1Final(sha1result, &ctx); memcpy(&uu, sha1result, sizeof(uu)); } /* the calculated hash is using local order */ UUID_TO_NETWORK(uu); UUID_V3_OR_V5(uu, v); #ifdef HAVE_UUID_E2FS /* uuid_unparse expects local order */ UUID_TO_LOCAL(uu); uuid_unparse((unsigned char *) &uu, strbuf); #else /* BSD */ uuid_to_string(&uu, &str, &status); if (status == uuid_s_ok) strlcpy(strbuf, str, 37); if (str) free(str); if (status != uuid_s_ok) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("uuid library failure: %d", (int) status))); #endif break; } case 4: /* random uuid */ default: { #ifdef HAVE_UUID_E2FS uuid_t uu; uuid_generate_random(uu); uuid_unparse(uu, strbuf); #else /* BSD */ snprintf(strbuf, sizeof(strbuf), "%08lx-%04x-%04x-%04x-%04x%08lx", (unsigned long) arc4random(), (unsigned) (arc4random() & 0xffff), (unsigned) ((arc4random() & 0xfff) | 0x4000), (unsigned) ((arc4random() & 0x3fff) | 0x8000), (unsigned) (arc4random() & 0xffff), (unsigned long) arc4random()); #endif break; } } return DirectFunctionCall1(uuid_in, CStringGetDatum(strbuf)); }
static void daemon_auth(std::string &user, std::string &key) { if (user == "guest") { daemon_printf( "%d\n", CODE_OK ); return; } char *buf; struct MD5Context ctx; unsigned char digest[16]; char hex[33]; if (user == "root") { std::string &root_password = stardictdMain.conf->get_str("root-user/password"); if (root_password.empty()) { daemon_printf( "%d auth denied\n", CODE_DENIED ); return; } MD5Init(&ctx); MD5Update(&ctx, (const unsigned char*)"StarDict", 8); //StarDict-Protocol 0.4, add md5 salt. MD5Update(&ctx, (const unsigned char*)root_password.c_str(), root_password.length()); MD5Final(digest, &ctx); for (int i = 0; i < 16; i++) snprintf( hex+2*i, 3, "%02x", digest[i] ); hex[32] = '\0'; buf = g_strdup_printf("%s%s", daemonStamp, hex); } else { if (init_database()) { daemon_printf( "%d Connect to MySQL failed!\n", CODE_DENIED ); return; } std::string sql; sql = "SELECT user_id, user_md5saltpassword, level FROM stardict_users WHERE username="******"%d Query failed!\n", CODE_DENIED ); return; } MySQLResult *res = stardictdMain.conn.getResult(); if (!res) { daemon_printf( "%d Get result failed!\n", CODE_DENIED ); return; } DB_ROW row = res->fetchRow(); if (!row) { res->destroy(); daemon_printf( "%d User doesn't exist!\n", CODE_DENIED ); return; } userID = row[0]; userLevel = atoi(row[2]); stardictdMain.SetUserLevel(userLevel); buf = g_strdup_printf("%s%s", daemonStamp, row[1]); res->destroy(); } MD5Init(&ctx); MD5Update(&ctx, (const unsigned char*)buf, strlen(buf)); MD5Final(digest, &ctx); for (int i = 0; i < 16; i++) snprintf( hex+2*i, 3, "%02x", digest[i] ); hex[32] = '\0'; g_free(buf); if (key != hex) { daemon_printf( "%d auth denied\n", CODE_DENIED ); return; } else { daemon_printf( "%d authenticated\n", CODE_OK ); auth_user=user; if (auth_user == "root") { stardictdMain.SetDictMask("", 0, 0); } else { std::string sql; sql = "SELECT dictmask, collatefunc, language FROM user_basic WHERE id="; sql+= userID; if (stardictdMain.conn.query(sql.c_str(), sql.length())) { daemon_printf( "%d Query failed!\n", CODE_DENIED ); return; } MySQLResult *res = stardictdMain.conn.getResult(); if (!res) { daemon_printf( "%d Get result failed!\n", CODE_DENIED ); return; } DB_ROW row = res->fetchRow(); if (row) { char *str = g_strdup_printf("level-%d-user/max_dict_count", userLevel); const int max_dict_count = stardictdMain.conf->get_int(str); g_free(str); stardictdMain.SetDictMask(row[0], max_dict_count, userLevel); bool enable_collate; if (userLevel == 0) { enable_collate = stardictdMain.conf->get_bool("level-0-user/enable_collate"); } else { enable_collate = true; } if (enable_collate) { stardictdMain.SetServerCollateFunc(atoi(row[1])); } else { stardictdMain.SetServerCollateFunc(0); } stardictdMain.SetUserLang(row[2]); } else { stardictdMain.SetDictMask("", 0, 0); stardictdMain.SetServerCollateFunc(0); } res->destroy(); } } }
int PassB(FILE *fd) { u_char *p,*q; MD5_CTX ctx; int i,j,sep,cnt; u_char *md5=0,*md5before=0,*trash=0,*name=0,*uid=0,*gid=0,*mode=0; struct CTM_Syntax *sp; FILE *b = 0; /* backup command */ u_char buf[BUFSIZ]; char md5_1[33]; int ret = 0; int match = 0; struct CTM_Filter *filter = NULL; if(Verbose>3) printf("PassB -- Backing up files which would be changed.\n"); MD5Init (&ctx); snprintf(buf, sizeof(buf), fmtcheck(TarCmd, TARCMD), BackupFile); b=popen(buf, "w"); if(!b) { warn("%s", buf); return Exit_Garbage; } GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG GETFIELD(p,' '); if(strcmp(Version,p)) WRONG GETFIELD(p,' '); if(strcmp(Name,p)) WRONG GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG for(;;) { Delete(md5); Delete(uid); Delete(gid); Delete(mode); Delete(md5before); Delete(trash); Delete(name); cnt = -1; GETFIELD(p,' '); if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG if(!strcmp(p+3,"_END")) break; for(sp=Syntax;sp->Key;sp++) if(!strcmp(p+3,sp->Key)) goto found; WRONG found: for(i=0;(j = sp->List[i]);i++) { if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes) sep = ' '; else sep = '\n'; switch (j & CTM_F_MASK) { case CTM_F_Name: GETNAMECOPY(name,sep,j, Verbose); break; case CTM_F_Uid: GETFIELDCOPY(uid,sep); break; case CTM_F_Gid: GETFIELDCOPY(gid,sep); break; case CTM_F_Mode: GETFIELDCOPY(mode,sep); break; case CTM_F_MD5: if(j & CTM_Q_MD5_Before) GETFIELDCOPY(md5before,sep); else GETFIELDCOPY(md5,sep); break; case CTM_F_Count: GETBYTECNT(cnt,sep); break; case CTM_F_Bytes: GETDATA(trash,cnt); break; default: WRONG } } /* XXX This should go away. Disallow trailing '/' */ j = strlen(name)-1; if(name[j] == '/') name[j] = '\0'; if (KeepIt && (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) continue; /* match the name against the elements of the filter list. The action associated with the last matched filter determines whether this file should be ignored or backed up. */ match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE); for (filter = FilterList; filter; filter = filter->Next) { if (0 == regexec(&filter->CompiledRegex, name, 0, 0, 0)) match = filter->Action; } if (CTM_FILTER_DISABLE == match) continue; if (!strcmp(sp->Key,"FS") || !strcmp(sp->Key,"FN") || !strcmp(sp->Key,"AS") || !strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR")) { /* send name to the archiver for a backup */ cnt = strlen(name); if (cnt != fwrite(name,1,cnt,b) || EOF == fputc('\n',b)) { warn("%s", name); pclose(b); WRONG; } } } ret = pclose(b); Delete(md5); Delete(uid); Delete(gid); Delete(mode); Delete(md5before); Delete(trash); Delete(name); q = MD5End (&ctx,md5_1); GETFIELD(p,'\n'); /* <MD5> */ if(strcmp(q,p)) WRONG if (-1 != getc(fd)) WRONG return ret; }
/* * Save an RSA key file. Return nonzero on success. */ int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase) { unsigned char buf[16384]; unsigned char keybuf[16]; struct MD5Context md5c; unsigned char *p, *estart; FILE *fp; /* * Write the initial signature. */ p = buf; memcpy(p, rsa_signature, sizeof(rsa_signature)); p += sizeof(rsa_signature); /* * One byte giving encryption type, and one reserved (zero) * uint32. */ *p++ = (passphrase ? SSH_CIPHER_3DES : 0); PUT_32BIT(p, 0); p += 4; /* * An ordinary SSH-1 public key consists of: a uint32 * containing the bit count, then two bignums containing the * modulus and exponent respectively. */ PUT_32BIT(p, bignum_bitcount(key->modulus)); p += 4; p += ssh1_write_bignum(p, key->modulus); p += ssh1_write_bignum(p, key->exponent); /* * A string containing the comment field. */ if (key->comment) { PUT_32BIT(p, strlen(key->comment)); p += 4; memcpy(p, key->comment, strlen(key->comment)); p += strlen(key->comment); } else { PUT_32BIT(p, 0); p += 4; } /* * The encrypted portion starts here. */ estart = p; /* * Two bytes, then the same two bytes repeated. */ *p++ = random_byte(); *p++ = random_byte(); p[0] = p[-2]; p[1] = p[-1]; p += 2; /* * Four more bignums: the decryption exponent, then iqmp, then * q, then p. */ p += ssh1_write_bignum(p, key->private_exponent); p += ssh1_write_bignum(p, key->iqmp); p += ssh1_write_bignum(p, key->q); p += ssh1_write_bignum(p, key->p); /* * Now write zeros until the encrypted portion is a multiple of * 8 bytes. */ while ((p - estart) % 8) *p++ = '\0'; /* * Now encrypt the encrypted portion. */ if (passphrase) { MD5Init(&md5c); MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); MD5Final(keybuf, &md5c); des3_encrypt_pubkey(keybuf, estart, p - estart); smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */ } /* * Done. Write the result to the file. */ fp = f_open(filename, "wb", TRUE); if (fp) { int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf)); if (fclose(fp)) ret = 0; return ret; } else return 0; }
int decrypt_avp (char *buf, struct tunnel *t) { /* Decrypts a hidden AVP pointed to by buf. The new header will be exptected to be two characters offset from the old */ int cnt = 0; int len, olen, flags; unsigned char digest[MD_SIG_SIZE]; char *ptr, *end; _u16 attr; struct avp_hdr *old_hdr = (struct avp_hdr *) buf; struct avp_hdr *new_hdr = (struct avp_hdr *) (buf + 2); int saved_segment_len; /* maybe less 16; may be used if the cipher is longer than 16 octets */ unsigned char saved_segment[MD_SIG_SIZE]; ptr = ((char *) old_hdr) + sizeof (struct avp_hdr); olen = old_hdr->length & 0x0FFF; end = buf + olen; if (!t->chal_us.vector) { l2tp_log (LOG_DEBUG, "decrypt_avp: Hidden bit set, but no random vector specified!\n"); return -EINVAL; } /* First, let's decrypt all the data. We're not guaranteed that it will be padded to a 16 byte boundary, so we have to be more careful than when encrypting */ attr = ntohs (old_hdr->attr); MD5Init (&t->chal_us.md5); MD5Update (&t->chal_us.md5, (void *) &attr, 2); MD5Update (&t->chal_us.md5, t->chal_us.secret, strlen ((char *)t->chal_us.secret)); MD5Update (&t->chal_us.md5, t->chal_us.vector, t->chal_us.vector_len); MD5Final (digest, &t->chal_us.md5); #ifdef DEBUG_HIDDEN l2tp_log (LOG_DEBUG, "attribute is %d and challenge is: ", attr); print_challenge (&t->chal_us); l2tp_log (LOG_DEBUG, "md5 is: "); print_md5 (digest); #endif while (ptr < end) { if (cnt >= MD_SIG_SIZE) { MD5Init (&t->chal_us.md5); MD5Update (&t->chal_us.md5, t->chal_us.secret, strlen ((char *)t->chal_us.secret)); MD5Update (&t->chal_us.md5, saved_segment, MD_SIG_SIZE); MD5Final (digest, &t->chal_us.md5); cnt = 0; } /* at the beginning of each segment, we save the current segment (16 octets or less) of cipher * so that the next round of MD5 (if there is a next round) hash could use it */ if (cnt == 0) { saved_segment_len = (end - ptr < MD_SIG_SIZE) ? (end - ptr) : MD_SIG_SIZE; memcpy (saved_segment, ptr, saved_segment_len); } *ptr = *ptr ^ digest[cnt++]; ptr++; } /* Hopefully we're all nice and decrypted now. Let's rewrite the header. First save the old flags, and get the new stuff */ flags = old_hdr->length & 0xF000 & ~HBIT; len = ntohs (new_hdr->attr) + sizeof (struct avp_hdr); if (len > olen - 2) { l2tp_log (LOG_DEBUG, "decrypt_avp: Decrypted length is too long (%d > %d)\n", len, olen - 2); return -EINVAL; } new_hdr->attr = old_hdr->attr; new_hdr->vendorid = old_hdr->vendorid; new_hdr->length = len | flags; return 0; }
// return 1 if error, 0 if ok int auth_rx(OspfPacket *pkt, OspfPacketDesc *desc) { RcpInterface *intf = rcpFindInterfaceByKIndex(shm, desc->if_index); if (!intf) return 1; uint16_t type = ntohs(pkt->header.auth_type); if (type != intf->ospf_auth_type) { trap_IfAuthFailure(desc->if_index, desc->ip_source, 1, pkt->header.type); return 1; } // simple authentication if (type == 1) { if (memcmp(pkt->header.auth_data, intf->ospf_passwd, 8)) { trap_IfAuthFailure(desc->if_index, desc->ip_source, 0, pkt->header.type); return 1; } // clear the password field before checksum memset(pkt->header.auth_data, 0, 8); } // md5 authentication else if (type == 2) { // copy md5 header OspfMd5 md5; memcpy(&md5, pkt->header.auth_data, 8); md5.seq = ntohl(md5.seq); // check key id if (md5.key_id != intf->ospf_md5_key) { trap_IfAuthFailure(desc->if_index, desc->ip_source, 0, pkt->header.type); return 1; } // check sequence number OspfNeighbor *nb = neighborFind(desc->area_id, desc->ip_source); if (nb != NULL) { if (md5.seq < nb->ospf_md5_seq) { trap_IfAuthFailure(desc->if_index, desc->ip_source, 0, pkt->header.type); return 1; } } // check digest present if (desc->rx_size != (ntohs(pkt->header.length) + 20 + md5.auth_data_len)) { trap_IfAuthFailure(desc->if_index, desc->ip_source, 0, pkt->header.type); return 1; } // store packet digest uint8_t pkt_digest[16]; uint8_t *end = (uint8_t *) &pkt->header; end += ntohs(pkt->header.length); memcpy(pkt_digest, end, 16); // copy our password at the end of the packet memcpy(end, intf->ospf_md5_passwd, 16); MD5_CTX context; uint8_t digest[16]; MD5Init(&context); MD5Update(&context, (uint8_t *) &pkt->header, ntohs(pkt->header.length) + 16); MD5Final(digest, &context); // compare if (memcmp(digest, pkt_digest, 16) != 0) { trap_IfAuthFailure(desc->if_index, desc->ip_source, 0, pkt->header.type); return 1; } // update seq in neighbor structure if (nb != NULL) nb->ospf_md5_seq = md5.seq; } return 0; }
int handle_challenge (struct tunnel *t, struct challenge *chal) { char *us; char *them; if (!t->lns && !t->lac) { l2tp_log (LOG_DEBUG, "%s: No LNS or LAC to handle challenge!\n", __FUNCTION__); return -1; } #ifdef DEBUG_AUTH l2tp_log (LOG_DEBUG, "%s: making response for tunnel: %d\n", __FUNCTION__, t->ourtid); #endif if (t->lns) { if (t->lns->hostname[0]) us = t->lns->hostname; else us = hostname; if (t->lns->peername[0]) them = t->lns->peername; else them = t->hostname; } else { if (t->lac->hostname[0]) us = t->lac->hostname; else us = hostname; if (t->lac->peername[0]) them = t->lac->peername; else them = t->hostname; } if (!get_secret (us, them, chal->secret, sizeof (chal->secret))) { l2tp_log (LOG_DEBUG, "%s: no secret found for us='%s' and them='%s'\n", __FUNCTION__, us, them); return -1; } #if DEBUG_AUTH l2tp_log (LOG_DEBUG, "*%s: Here comes the chal->ss:\n", __FUNCTION__); bufferDump (&chal->ss, 1); l2tp_log (LOG_DEBUG, "%s: Here comes the secret\n", __FUNCTION__); bufferDump (chal->secret, strlen (chal->secret)); l2tp_log (LOG_DEBUG, "%s: Here comes the challenge\n", __FUNCTION__); bufferDump (chal->challenge, chal->chal_len); #endif memset (chal->response, 0, MD_SIG_SIZE); MD5Init (&chal->md5); MD5Update (&chal->md5, &chal->ss, 1); MD5Update (&chal->md5, chal->secret, strlen ((char *)chal->secret)); MD5Update (&chal->md5, chal->challenge, chal->chal_len); MD5Final (chal->response, &chal->md5); #ifdef DEBUG_AUTH l2tp_log (LOG_DEBUG, "response is %X%X%X%X to '%s' and %X%X%X%X, %d\n", *((int *) &chal->response[0]), *((int *) &chal->response[4]), *((int *) &chal->response[8]), *((int *) &chal->response[12]), chal->secret, *((int *) &chal->challenge[0]), *((int *) &chal->challenge[4]), *((int *) &chal->challenge[8]), *((int *) &chal->challenge[12]), chal->ss); #endif chal->state = STATE_CHALLENGED; return 0; }
void encrypt_avp (struct buffer *buf, _u16 len, struct tunnel *t) { /* Encrypts an AVP of len, at data. We assume there are two "spare bytes" before the data pointer,l but otherwise this is just a normal AVP that is about to be returned from an avpsend routine */ struct avp_hdr *new_hdr = (struct avp_hdr *) (buf->start + buf->len - len); struct avp_hdr *old_hdr = (struct avp_hdr *) (buf->start + buf->len - len + 2); _u16 length, flags, attr; /* New length, old flags */ unsigned char *ptr, *end; int cnt; unsigned char digest[MD_SIG_SIZE]; unsigned char *previous_segment; /* FIXME: Should I pad more randomly? Right now I pad to nearest 16 bytes */ length = ((len - sizeof (struct avp_hdr) + 1) / 16 + 1) * 16 + sizeof (struct avp_hdr); flags = htons (old_hdr->length) & 0xF000; new_hdr->length = htons (length | flags | HBIT); new_hdr->vendorid = old_hdr->vendorid; new_hdr->attr = attr = old_hdr->attr; /* This is really the length field of the hidden sub-format */ old_hdr->attr = htons (len - sizeof (struct avp_hdr)); /* Okay, now we've rewritten the header, as it should be. Let's start encrypting the actual data now */ buf->len -= len; buf->len += length; /* Back to the beginning of real data, including the original length AVP */ MD5Init (&t->chal_them.md5); MD5Update (&t->chal_them.md5, (void *) &attr, 2); MD5Update (&t->chal_them.md5, t->chal_them.secret, strlen ((char *)t->chal_them.secret)); MD5Update (&t->chal_them.md5, t->chal_them.vector, VECTOR_SIZE); MD5Final (digest, &t->chal_them.md5); /* Though not a "MUST" in the spec, our subformat length is always a multiple of 16 */ ptr = ((unsigned char *) new_hdr) + sizeof (struct avp_hdr); end = ((unsigned char *) new_hdr) + length; previous_segment = ptr; while (ptr < end) { #if DEBUG_HIDDEN l2tp_log (LOG_DEBUG, "%s: The digest to be XOR'ed\n", __FUNCTION__); bufferDump (digest, MD_SIG_SIZE); l2tp_log (LOG_DEBUG, "%s: The plaintext to be XOR'ed\n", __FUNCTION__); bufferDump (ptr, MD_SIG_SIZE); #endif for (cnt = 0; cnt < MD_SIG_SIZE; cnt++, ptr++) { *ptr = *ptr ^ digest[cnt]; } #if DEBUG_HIDDEN l2tp_log (LOG_DEBUG, "%s: The result of XOR\n", __FUNCTION__); bufferDump (previous_segment, MD_SIG_SIZE); #endif if (ptr < end) { MD5Init (&t->chal_them.md5); MD5Update (&t->chal_them.md5, t->chal_them.secret, strlen ((char *)t->chal_them.secret)); MD5Update (&t->chal_them.md5, previous_segment, MD_SIG_SIZE); MD5Final (digest, &t->chal_them.md5); } previous_segment = ptr; } }
/* * Returns the next product signature (MD5 checksum). * * signature The buffer in which to put the MD5 checksum. */ static void nextSignature(signaturet* signature) { MD5Init(md5); MD5Update(md5, (const unsigned char*)&prodCount, sizeof(prodCount)); MD5Final((unsigned char*)*signature, md5); }
static int digest_md5_init(EVP_MD_CTX *ctx) { MD5Init(data(ctx)); return 1; }
/* Returns: TRUE if FileRow value has been changed */ static gboolean update_file_md5sum (FileRow *row, const gchar *complete_filename) { gboolean changed = TRUE; GValue *value = NULL; /* MD5 computation */ MD5_CTX context; unsigned char digest[16]; /* Flawfinder: ignore */ GString *md5str; gint i; int fd; gpointer map; guint length; HANDLE view; /* file mapping in mem */ length = g_value_get_uint (row->size_value); if (length == 0) goto md5end; fd = open (complete_filename, O_RDONLY); /* Flawfinder: ignore */ if (fd < 0) goto md5end; #ifndef G_OS_WIN32 map = mmap (NULL, length, PROT_READ, MAP_PRIVATE, fd, 0); if (map == MAP_FAILED) { close (fd); goto md5end; } #else view = CreateFileMapping ((HANDLE) fd, NULL, PAGE_READONLY|SEC_COMMIT, 0,0 , NULL); if (!view) { close (fd); goto md5end; } map = MapViewOfFile (view, FILE_MAP_READ, 0, 0, length); if (!map) { close (fd); goto md5end; } #endif /* !G_OS_WIN32 */ MD5Init (&context); MD5Update (&context, map, length); MD5Final (digest, &context); md5str = g_string_new (""); for (i = 0; i < 16; i++) g_string_append_printf (md5str, "%02x", digest[i]); value = gda_value_new (G_TYPE_STRING); g_value_take_string (value, md5str->str); g_string_free (md5str, FALSE); #ifndef G_OS_WIN32 munmap (map, length); #else UnmapViewOfFile (map); #endif /* !G_OS_WIN32 */ close (fd); md5end: if (value) { if (row->md5sum_value && (G_VALUE_TYPE (row->md5sum_value) == G_TYPE_STRING) && !gda_value_compare (row->md5sum_value, value)) changed = FALSE; else { if (row->md5sum_value) gda_value_free (row->md5sum_value); row->md5sum_value = value; } } else { if (row->md5sum_value && gda_value_is_null (row->md5sum_value)) changed = FALSE; else { if (row->md5sum_value) gda_value_free (row->md5sum_value); row->md5sum_value = gda_value_new_null (); } } return changed; }
/** * UtilSaltedMd5 * * Computes the MD5 hash of a given string and returns * a string representation of the hash. * * @param String the string which should be hashed * @param Salt the salt value * @param BrokenAlgo whether to use the broken algorithm */ const char *UtilMd5(const char *String, const char *Salt, bool BrokenAlgo) { #ifdef HAVE_LIBSSL MD5_CTX context; #else /* HAVE_LIBSSL */ sMD5_CTX context; #endif /* HAVE_LIBSSL */ broken_sMD5_CTX broken_context; unsigned char digest[16]; char *StringAndSalt, *StringPtr; static char *SaltAndResult = NULL; int rc; free(SaltAndResult); if (Salt != NULL) { rc = asprintf(&StringAndSalt, "%s%s", String, Salt); } else { rc = asprintf(&StringAndSalt, "%s", String); } if (RcFailed(rc)) { g_Bouncer->Fatal(); } if (!BrokenAlgo) { #ifdef HAVE_LIBSSL MD5_Init(&context); MD5_Update(&context, (unsigned char *)StringAndSalt, strlen(StringAndSalt)); MD5_Final(digest, &context); #else /* HAVE_LIBSSL */ MD5Init(&context); MD5Update(&context, (unsigned char *)StringAndSalt, strlen(StringAndSalt)); MD5Final(digest, &context); #endif /* HAVE_LIBSSL */ } else { broken_MD5Init(&broken_context); broken_MD5Update(&broken_context, (unsigned char *)StringAndSalt, strlen(StringAndSalt)); broken_MD5Final(digest, &broken_context); } free(StringAndSalt); if (Salt != NULL) { SaltAndResult = (char *)malloc(strlen(Salt) + 50); if (AllocFailed(SaltAndResult)) { g_Bouncer->Fatal(); } strmcpy(SaltAndResult, Salt, strlen(Salt) + 50); strmcat(SaltAndResult, "$", strlen(Salt) + 50); StringPtr = SaltAndResult + strlen(SaltAndResult); } else { StringPtr = SaltAndResult = (char *)malloc(50); if (AllocFailed(SaltAndResult)) { g_Bouncer->Fatal(); } } for (int i = 0; i < 16; i++) { /* TODO: don't use sprintf */ sprintf(StringPtr + i * 2, "%02x", digest[i]); } return SaltAndResult; }
/* MD5 Low Level Interface */ int md5_low_init(MD5_CTX *context) { MD5Init(context); return 0; }
/* * Takes a WMO format product which is a * SAO, SYNOP, SHIP, METAR, or SPECI message, splits it into * individual observations. The observations are each encapsulated in a * new product which inherits most of its description from the * original product. * The new product pkey is derived from the observation type * and has the following form: * * SAO - "sao tt ccc ddhhmm" * where: * tt is SA, SP or RS * ccc is the station ID like SFO, LXV, etc * ddhhmm is the time stamp. * * SYNOP - "aaxx nnnnn ddhhmm" * where: * nnnnn is the WMO station id (5 digit number) * * SHIP - "bbxx c* ddhhmm" * where: * c* is the call sign * * METAR - "metar cccc ddhhmm" * where: * cccc is the call sign * * SPECI - "speci cccc ddhhmm" * * The new product sequence number is original sequence number times 1000 * plus the sequence of the individual observation within the product. * * 'doit' is called on each of the new products. It is presumed * this function return zero upon success. * * Returns the number of successful calls to 'doit', eg, the * number of splits. Returns -1 on error. */ int surf_split(const prod_info *infop, const void *datap, int (*doit)(const prod_info *, const void *)) { wmo_header_t hdr; message_type_t mtype; dtime dt; xbuf buf[1]; static unsigned char* dbuf = NULL; static size_t dbufSize = 0; char header[50]; int nsplit = 0; enum { SURFACE_BOGUS , AAXX, US_AAXX, BBXX, SAO, sMETAR, sSPECI } subtype = SURFACE_BOGUS; hdr.time = &dt; if(infop->sz > dbufSize || dbuf == NULL) { size_t size = infop->sz != 0 ? infop->sz : 1; if (dbuf != NULL) free(dbuf); dbuf = malloc(size); if (dbuf == NULL) { serror("surf_split(): Couldn't allocate %lu-byte buffer", (unsigned long)size); dbufSize = 0; return -1; } dbufSize = size; } memcpy(dbuf, datap, infop->sz); if( cbuftoxbuf(buf, dbuf, infop->sz) == NULL) return -1; skipline(buf, 4); /* SOH */ skipline(buf, 12); /* start */ /* inspect header as a string to see if to use PIL processing or not */ if(infop->sz > 48 ) { memcpy( header, datap, 48 ); header[48] = '\0'; } else { memcpy( header, datap, infop->sz ); header[infop->sz] = '\0'; } if( strstr( header, "METAR\r" ) || strstr( header, "SPECI\r" ) || strstr( header, "MTR" ) || strstr( header, "METAR \r" ) || strstr( header, "SPECI \r" ) || strstr( header, "BOYC" )) { usePil = 1; } else { usePil = 0; } if( get_wmo_header(buf, &hdr) == NULL) { uerror("get_wmo_header: hdr: %s\n", hdr); return -1; } usePil = 1; #if DEBUG fputs("\t", stderr); fprint_wmo_header(stderr, &hdr); fputs("\n", stderr); #endif mtype = decode_type(hdr.TT,hdr.AA,hdr.PIL); /* #### */ { char cbuf[8]; int digit; dtime time; wind_units_t wind_units = WIND_UNAVAIL; time = *hdr.time; /* default the ob time to the time in the header */ /* delve into section 0 */ switch(mtype) { case SYNOP : if(get_wstr(buf, cbuf, 1) < 0 ) return -1; if(cbuf[0] == 'A') { subtype = AAXX; if(get_str(buf, &cbuf[1], 3) < 0 ) return -1; if( cbuf[3] != 'X' ) { /* punt */ uerror("surface_split: Unknown SYNOP type: %s\n", cbuf); return 0; } if(get_yygg(buf, &time) < 0 ) return -1; /* YYGG */ if(dget_num(buf, &digit, 1) < 0 ) return -1; /* isubw */ if(digit >= 0 && digit <= 4) wind_units = (wind_units_t)digit; } else if(isascii(cbuf[0]) && isdigit(cbuf[0])) /* US Stations 7NNNN */ { unnextc(buf,cbuf[0]); subtype = US_AAXX; /* * Some US reports leave off AAXX YYGGisubw, so we use the * time from the wmo header. */ wind_units = KNOTS; } else { unnextc(buf,cbuf[0]); return 0; /* ?? */ } break; case SHIP : if (hdr.PIL[0] != '\0' && whasSTR(buf, "BOYC")) { skipline(buf, 4); } if(get_wstr(buf, cbuf, 4) < 0 ) return -1; if(cbuf[0] == 'B') { if( cbuf[3] != 'X' ) { /* punt */ uerror("surface_split: Unknown SHIP type: %s\n", cbuf); return 0; } subtype = BBXX; /* get time below */ } else { unnextc(buf,cbuf[0]); return 0; } break; case METAR : if( hdr.PIL[0] != '\0' && (! strstr(hdr.PIL, "METAR") || !strstr(hdr.PIL, "MTR"))){ subtype = sMETAR; } else if(whasSTR(buf, "METAR")) { subtype = sMETAR; get_wyyggZ(buf, &time); } else if(whasSTR(buf, "SPECI")) { subtype = sSPECI; get_wyyggZ(buf, &time); } else { subtype = SAO; /* may actually be a METAR, check below */ } break; case SPECI : if(whasSTR(buf, "SPECI")) { subtype = sSPECI; get_wyyggZ(buf, &time); } break; default : uerror("surface_split: Can't handle %s", sMessage_type(mtype) ); uerror("HDR + PIL: %s%s %s", hdr.TT, hdr.AA, hdr.PIL ) ; return -1; } { /* while block */ static char newkey[KEYSIZE]; xbuf subbuf[1]; prod_info newinfo = *infop; #define MAX_SURF_LEN 511 #undef MIN #define MIN(a,b) ((a) <= (b) ? (a) : (b)) char pbuf[MAX_SURF_LEN + 1]; int l1, l2; static char ident[CALL_SIGN_LEN+1]; static char type[4]; char *stype; u_int subseq = infop->seqno * 1000; unsigned char *pp; while( get_weqxbuf(buf, subbuf) > 0 ) { (void)memset(newkey,0,KEYSIZE); (void)memset(pbuf,0,MAX_SURF_LEN + 1); (void)memset(ident,0,CALL_SIGN_LEN+1); pp = subbuf->base; switch(subtype) { case AAXX : case US_AAXX : strcpy(newkey, "aaxx "); strcpy(pbuf, "AAXX"); sprintf(&pbuf[strlen(pbuf)], " %02d%02d%1d\r\r\n", time.mday, time.hour, (int)wind_units); /* WMO station no. */ if(get_wstr(subbuf, ident, 5) < 0) continue; strcat(newkey, ident); break; case BBXX : strcpy(newkey, "bbxx "); strcpy(pbuf, "BBXX\r\r\n"); /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; strcat(newkey, ident); if(get_yygg(subbuf, &time) < 0) continue; /* YYGG */ break; case sSPECI : /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; stype = "SPECI"; if(strcmp(ident, "METAR") == 0 || strcmp(ident, "SPECI") == 0) { if( strcmp(ident, "METAR") == 0) { stype = "METAR"; } /* They package each ob with a tag */ pp = (subbuf->get +1); if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; } if(!whas_yyggZ(subbuf)) { /* Have to insert the date */ sprintf(pbuf, "%s\r\r\n%s %02d%02dZ ", stype, ident, time.hour, time.min); pp = subbuf->get; } else { strcpy(pbuf, stype); strcat(pbuf, "\r\r\n"); } if(strcmp(stype, "METAR") == 0 ) { strcpy(newkey, "metar "); } else { strcpy(newkey, "speci "); } strcat(newkey, ident); break; case sMETAR : if(has_NIL(subbuf)) continue; /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) { continue; } stype = "METAR"; if(strcmp(ident, "METAR") == 0 || strcmp(ident, "SPECI") == 0) { if( strcmp(ident, "SPECI") == 0) { stype = "SPECI"; } /* They package each ob with a tag */ pp = (subbuf->get +1); if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; } if(!whas_yyggZ(subbuf)) { /* Have to insert the date */ sprintf(pbuf, "%s\r\r\n%s %02d%02dZ ", stype, ident, time.hour, time.min); pp = subbuf->get; } else { strcpy(pbuf, stype); strcat(pbuf, "\r\r\n"); } if(strcmp(stype, "METAR") == 0 ) { strcpy(newkey, "metar "); } else { strcpy(newkey, "speci "); } strcat(newkey, ident); break; case SAO : /* call sign */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; if(hdr.AA[0] == 'U' && hdr.AA[1] == 'S' && strlen(ident) == 6) { /* skip 6 char US "AFOS code" */ if(get_wstr(subbuf, ident, CALL_SIGN_LEN) < 0) continue; } /* SA, SP, RS, USP or XP */ if(get_wstr(subbuf, type, 3) < 0) continue; if((type[0] == 'S' && (type[1] == 'A' || type[1] == 'P')) || (type[0] == 'R' && type[1] == 'S') || (type[0] == 'U' && type[1] == 'S' && type[2] == 'P') || (type[0] == 'X' && type[1] == 'P') || (type[0] == 'T' && (type[1] == 'A' || type[1] == 'S')) ) { strcpy(newkey, "sao "); strcat(newkey, type); strcat(newkey, " "); strcat(newkey, ident); } else if(isdigit(type[0]) && isdigit(type[1])) { /* it is a METAR really */ subtype = sMETAR; strcpy(newkey, "metar "); strcat(newkey, ident); strcpy(pbuf, "METAR\r\r\n"); } else continue; /* don't know what it is, "NIL=" */ break; } /* safety net */ if(strlen(ident) == 0) { continue; } /* else */ sprintf(&newkey[strlen(newkey)], " %02d%02d%02d", time.mday, time.hour, time.min); if(hdr.retransmit != ORIGINAL) sprintf(&newkey[strlen(newkey)], " %s", sRetransmit(&hdr)); newinfo.ident = newkey; newinfo.seqno = ++subseq; l1 = strlen(pbuf); l2 = MIN(MAX_SURF_LEN - l1 - 4, subbuf->bufsiz - (pp - subbuf->base)); /* N.B.: silent truncation */ strncat(pbuf, (char *)pp, l2 ); strcat(pbuf,"=\r\r\n"); newinfo.sz = l1 + l2 + 4; #if DEBUG fprintf(stderr,"\t\t%s\n", newinfo.ident); #endif #if PRINT { char *cp = pbuf; char *end = &cp[newinfo.sz]; while(cp < end) { putc(*cp, stderr); cp++; } } putc('\n', stderr); #endif MD5Init(md5ctxp); MD5Update(md5ctxp, (const unsigned char *)pbuf, newinfo.sz); MD5Final((unsigned char*)newinfo.signature, md5ctxp); /* * process the single ob in the requested fashion */ if((*doit)(&newinfo, pbuf) == 0) nsplit++; } /* end while */ #if PRINT putc('\n', stderr); #endif } /* end while block */ } /* end #### block */ return nsplit; }
int compare_module(struct xmp_module *mod, FILE *f) { char line[1024]; char *s; int i, j, x; /* Check title and format */ read_line(line, 1024, f); fail_unless(!strcmp(line, mod->name), "module name"); read_line(line, 1024, f); fail_unless(!strcmp(line, mod->type), "module type"); /* Check module attributes */ read_line(line, 1024, f); x = strtoul(line, &s, 0); fail_unless(x == mod->pat, "number of patterns"); x = strtoul(s, &s, 0); fail_unless(x == mod->trk, "number of tracks"); x = strtoul(s, &s, 0); fail_unless(x == mod->chn, "number of channels"); x = strtoul(s, &s, 0); fail_unless(x == mod->ins, "number of instruments"); x = strtoul(s, &s, 0); fail_unless(x == mod->smp, "number of samples"); x = strtoul(s, &s, 0); fail_unless(x == mod->spd, "initial speed"); x = strtoul(s, &s, 0); fail_unless(x == mod->bpm, "initial tempo"); x = strtoul(s, &s, 0); fail_unless(x == mod->len, "module length"); x = strtoul(s, &s, 0); fail_unless(x == mod->rst, "restart position"); x = strtoul(s, &s, 0); fail_unless(x == mod->gvl, "global volume"); /* Check orders */ if (mod->len > 0) { read_line(line, 1024, f); s = line; for (i = 0; i < mod->len; i++) { x = strtoul(s, &s, 0); fail_unless(x == mod->xxo[i], "orders"); } } /* Check instruments */ for (i = 0; i < mod->ins; i++) { struct xmp_instrument *xxi = &mod->xxi[i]; read_line(line, 1024, f); x = strtoul(line, &s, 0); fail_unless(x == xxi->vol, "instrument volume"); x = strtoul(s, &s, 0); fail_unless(x == xxi->nsm, "number of subinstruments"); x = strtoul(s, &s, 0); fail_unless(x == xxi->rls, "instrument release"); x = strncmp(++s, xxi->name, 32); fail_unless(x == 0, "instrument name"); /* check envelopes */ check_envelope(&xxi->aei, line, f); check_envelope(&xxi->fei, line, f); check_envelope(&xxi->pei, line, f); /* check mapping */ read_line(line, 1024, f); s = line; for (j = 0; j < XMP_MAX_KEYS; j++) { x = strtoul(s, &s, 0); fail_unless(x == xxi->map[j].ins, "instrument map"); } read_line(line, 1024, f); s = line; for (j = 0; j < XMP_MAX_KEYS; j++) { x = strtoul(s, &s, 0); fail_unless(x == xxi->map[j].xpo, "transpose map"); } /* check subinstruments */ for (j = 0; j < xxi->nsm; j++) { struct xmp_subinstrument *sub = &xxi->sub[j]; read_line(line, 1024, f); x = strtoul(line, &s, 0); fail_unless(x == sub->vol, "subinst volume"); x = strtoul(s, &s, 0); fail_unless(x == sub->gvl, "subinst gl volume"); x = strtoul(s, &s, 0); fail_unless(x == sub->pan, "subinst pan"); x = strtoul(s, &s, 0); fail_unless(x == sub->xpo, "subinst transpose"); x = strtoul(s, &s, 0); fail_unless(x == sub->fin, "subinst finetune"); x = strtoul(s, &s, 0); fail_unless(x == sub->vwf, "subinst vibr wf"); x = strtoul(s, &s, 0); fail_unless(x == sub->vde, "subinst vibr depth"); x = strtoul(s, &s, 0); fail_unless(x == sub->vra, "subinst vibr rate"); x = strtoul(s, &s, 0); fail_unless(x == sub->vsw, "subinst vibr sweep"); x = strtoul(s, &s, 0); fail_unless(x == sub->rvv, "subinst vol var"); x = strtoul(s, &s, 0); fail_unless(x == sub->sid, "subinst sample nr"); x = strtoul(s, &s, 0); fail_unless(x == sub->nna, "subinst NNA"); x = strtoul(s, &s, 0); fail_unless(x == sub->dct, "subinst DCT"); x = strtoul(s, &s, 0); fail_unless(x == sub->dca, "subinst DCA"); x = strtoul(s, &s, 0); fail_unless(x == sub->ifc, "subinst cutoff"); x = strtoul(s, &s, 0); fail_unless(x == sub->ifr, "subinst resonance"); } } /* Check patterns */ for (i = 0; i < mod->pat; i++) { struct xmp_pattern *xxp = mod->xxp[i]; read_line(line, 1024, f); x = strtoul(line, &s, 0); fail_unless(x == xxp->rows, "pattern rows"); for (j = 0; j < mod->chn; j++) { x = strtoul(s, &s, 0); fail_unless(x == xxp->index[j], "pattern index"); } } /* Check tracks */ for (i = 0; i < mod->trk; i++) { struct xmp_track *xxt = mod->xxt[i]; unsigned char d[16]; MD5_CTX ctx; read_line(line, 1024, f); x = strtoul(line, &s, 0); fail_unless(x == xxt->rows, "track rows"); MD5Init(&ctx); MD5Update(&ctx, (const unsigned char *)xxt->event, xxt->rows * sizeof (struct xmp_event)); MD5Final(d, &ctx); fail_unless(compare_md5(d, ++s) == 0, "track data"); } /* Check samples */ for (i = 0; i < mod->smp; i++) { struct xmp_sample *xxs = &mod->xxs[i]; unsigned char d[16]; MD5_CTX ctx; int len = xxs->len; if (xxs->flg & XMP_SAMPLE_16BIT) len *= 2; read_line(line, 1024, f); x = strtoul(line, &s, 0); fail_unless(x == xxs->len, "sample length"); x = strtoul(s, &s, 0); fail_unless(x == xxs->lps, "sample loop start"); x = strtoul(s, &s, 0); fail_unless(x == xxs->lpe, "sample loop end"); x = strtoul(s, &s, 0); fail_unless(x == xxs->flg, "sample flags"); s++; if (len > 0 && xxs->data != NULL) { MD5Init(&ctx); MD5Update(&ctx, xxs->data, len); MD5Final(d, &ctx); fail_unless(compare_md5(d, s) == 0, "sample data"); } s += 32; fail_unless(strcmp(xxs->name, ++s) == 0, "sample name"); } /* Check channels */ for (i = 0; i < mod->chn; i++) { struct xmp_channel *xxc = &mod->xxc[i]; read_line(line, 1024, f); x = strtoul(line, &s, 0); fail_unless(x == xxc->pan, "channel pan"); x = strtoul(s, &s, 0); fail_unless(x == xxc->vol, "channel volume"); x = strtoul(s, &s, 0); fail_unless(x == xxc->flg, "channel flags"); } return 0; }
static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, char **commentptr, char *passphrase, const char **error) { unsigned char buf[16384]; unsigned char keybuf[16]; int len; int i, j, ciphertype; int ret = 0; struct MD5Context md5c; char *comment; *error = NULL; /* Slurp the whole file (minus the header) into a buffer. */ len = fread(buf, 1, sizeof(buf), fp); fclose(fp); if (len < 0 || len == sizeof(buf)) { *error = "error reading file"; goto end; /* file too big or not read */ } i = 0; *error = "file format error"; /* * A zero byte. (The signature includes a terminating NUL.) */ if (len - i < 1 || buf[i] != 0) goto end; i++; /* One byte giving encryption type, and one reserved uint32. */ if (len - i < 1) goto end; ciphertype = buf[i]; if (ciphertype != 0 && ciphertype != SSH_CIPHER_3DES) goto end; i++; if (len - i < 4) goto end; /* reserved field not present */ if (buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0 || buf[i + 3] != 0) goto end; /* reserved field nonzero, panic! */ i += 4; /* Now the serious stuff. An ordinary SSH-1 public key. */ j = makekey(buf + i, len, key, NULL, 1); if (j < 0) goto end; /* overran */ i += j; /* Next, the comment field. */ j = toint(GET_32BIT(buf + i)); i += 4; if (j < 0 || len - i < j) goto end; comment = snewn(j + 1, char); if (comment) { memcpy(comment, buf + i, j); comment[j] = '\0'; } i += j; if (commentptr) *commentptr = dupstr(comment); if (key) key->comment = comment; else sfree(comment); if (pub_only) { ret = 1; goto end; } if (!key) { ret = ciphertype != 0; *error = NULL; goto end; } /* * Decrypt remainder of buffer. */ if (ciphertype) { MD5Init(&md5c); MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); MD5Final(keybuf, &md5c); des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7); smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */ } /* * We are now in the secret part of the key. The first four * bytes should be of the form a, b, a, b. */ if (len - i < 4) goto end; if (buf[i] != buf[i + 2] || buf[i + 1] != buf[i + 3]) { *error = "wrong passphrase"; ret = -1; goto end; } i += 4; /* * After that, we have one further bignum which is our * decryption exponent, and then the three auxiliary values * (iqmp, q, p). */ j = makeprivate(buf + i, len - i, key); if (j < 0) goto end; i += j; j = ssh1_read_bignum(buf + i, len - i, &key->iqmp); if (j < 0) goto end; i += j; j = ssh1_read_bignum(buf + i, len - i, &key->q); if (j < 0) goto end; i += j; j = ssh1_read_bignum(buf + i, len - i, &key->p); if (j < 0) goto end; i += j; if (!rsa_verify(key)) { *error = "rsa_verify failed"; freersakey(key); ret = 0; } else ret = 1; end: smemclr(buf, sizeof(buf)); /* burn the evidence */ return ret; }
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode) { print_line("open and parse!"); ERR_FAIL_COND_V(file!=NULL,ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER); pos=0; eofed=false; if (p_mode==MODE_WRITE_AES256) { data.clear(); writing=true; file=p_base; mode=p_mode; key=p_key; } else if (p_mode==MODE_READ) { writing=false; key=p_key; uint32_t magic = p_base->get_32(); print_line("MAGIC: "+itos(magic)); ERR_FAIL_COND_V(magic!=COMP_MAGIC,ERR_FILE_UNRECOGNIZED); mode=Mode(p_base->get_32()); ERR_FAIL_INDEX_V(mode,MODE_MAX,ERR_FILE_CORRUPT); ERR_FAIL_COND_V(mode==0,ERR_FILE_CORRUPT); print_line("MODE: "+itos(mode)); unsigned char md5d[16]; p_base->get_buffer(md5d,16); length=p_base->get_64(); base=p_base->get_pos(); ERR_FAIL_COND_V(p_base->get_len() < base+length, ERR_FILE_CORRUPT ); int ds = length; if (ds % 16) { ds+=16-(ds % 16); } data.resize(ds); int blen = p_base->get_buffer(data.ptr(),ds); ERR_FAIL_COND_V(blen!=ds,ERR_FILE_CORRUPT); aes256_context ctx; aes256_init(&ctx,key.ptr()); for(size_t i=0;i<ds;i+=16) { aes256_decrypt_ecb(&ctx,&data[i]); } aes256_done(&ctx); data.resize(length); MD5_CTX md5; MD5Init(&md5); MD5Update(&md5,data.ptr(),data.size()); MD5Final(&md5); ERR_FAIL_COND_V(String::md5(md5.digest)!=String::md5(md5d),ERR_FILE_CORRUPT) ; file=p_base; } return OK; }
//----------------------------------------------------------------------------- // Purpose: // Input : digest[16] - // *pszFileName - // bSeed - // seed[4] - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool MD5_Hash_File(unsigned char digest[16], char *pszFileName, bool bSeed /* = FALSE */, unsigned int seed[4] /* = NULL */) { FileHandle_t fp; byte chunk[1024]; int nBytesRead; MD5Context_t ctx; int nSize; nSize = COM_OpenFile( pszFileName, &fp ); if ( !fp || ( nSize == -1 ) ) return false; memset(&ctx, 0, sizeof(MD5Context_t)); MD5Init(&ctx); if (bSeed) { // Seed the hash with the seed value MD5Update( &ctx, (const unsigned char *)&seed[0], 16 ); } // Now read in 1K chunks while (nSize > 0) { if (nSize > 1024) nBytesRead = g_pFileSystem->Read(chunk, 1024, fp); else nBytesRead = g_pFileSystem->Read(chunk, nSize, fp); // If any data was received, CRC it. if (nBytesRead > 0) { nSize -= nBytesRead; MD5Update(&ctx, chunk, nBytesRead); } // We we are end of file, break loop and return if ( g_pFileSystem->EndOfFile( fp ) ) { g_pFileSystem->Close( fp ); fp = NULL; break; } // If there was a disk error, indicate failure. else if ( !g_pFileSystem->IsOk(fp) ) { if ( fp ) g_pFileSystem->Close(fp); return FALSE; } } if ( fp ) g_pFileSystem->Close(fp); MD5Final(digest, &ctx); return TRUE; }
int CHashManager::HashFile(char *pszFile) { FILE *fp = NULL; unsigned char pBuf[SIZE_HASH_BUFFER]; unsigned long uRead = 0; unsigned char pTemp[256]; char szTemp[RH_MAX_BUFFER]; int i = 0; printf("File: <"); printf(pszFile); printf(">"); printf(CPS_NEWLINE); fp = fopen(pszFile, "rb"); if(fp == NULL) return RH_CANNOT_OPEN_FILE; if(m_bAlgorithm[HASHID_CRC16]) crc16_init(&m_crc16); if(m_bAlgorithm[HASHID_CRC16CCITT]) crc16ccitt_init(&m_crc16ccitt); if(m_bAlgorithm[HASHID_CRC32]) crc32Init(&m_crc32); if(m_bAlgorithm[HASHID_FCS_16]) fcs16_init(&m_fcs16); if(m_bAlgorithm[HASHID_FCS_32]) fcs32_init(&m_fcs32); if(m_bAlgorithm[HASHID_GHASH_32_3] || m_bAlgorithm[HASHID_GHASH_32_5]) m_ghash.Init(); if(m_bAlgorithm[HASHID_GOST]) gosthash_reset(&m_gost); if(m_bAlgorithm[HASHID_HAVAL]) haval_start(&m_haval); if(m_bAlgorithm[HASHID_MD2]) m_md2.Init(); if(m_bAlgorithm[HASHID_MD4]) MD4Init(&m_md4); if(m_bAlgorithm[HASHID_MD5]) MD5Init(&m_md5, 0); if(m_bAlgorithm[HASHID_SHA1]) sha1_begin(&m_sha1); if(m_bAlgorithm[HASHID_SHA2_256]) sha256_begin(&m_sha256); if(m_bAlgorithm[HASHID_SHA2_384]) sha384_begin(&m_sha384); if(m_bAlgorithm[HASHID_SHA2_512]) sha512_begin(&m_sha512); if(m_bAlgorithm[HASHID_SIZE_32]) sizehash32_begin(&m_uSizeHash32); if(m_bAlgorithm[HASHID_TIGER]) tiger_init(&m_tiger); while(1) { uRead = fread(pBuf, 1, SIZE_HASH_BUFFER, fp); if(uRead != 0) { if(m_bAlgorithm[HASHID_CRC16]) crc16_update(&m_crc16, pBuf, uRead); if(m_bAlgorithm[HASHID_CRC16CCITT]) crc16ccitt_update(&m_crc16ccitt, pBuf, uRead); if(m_bAlgorithm[HASHID_CRC32]) crc32Update(&m_crc32, pBuf, uRead); if(m_bAlgorithm[HASHID_FCS_16]) fcs16_update(&m_fcs16, pBuf, uRead); if(m_bAlgorithm[HASHID_FCS_32]) fcs32_update(&m_fcs32, pBuf, uRead); if(m_bAlgorithm[HASHID_GHASH_32_3] || m_bAlgorithm[HASHID_GHASH_32_5]) m_ghash.Update(pBuf, uRead); if(m_bAlgorithm[HASHID_GOST]) gosthash_update(&m_gost, pBuf, uRead); if(m_bAlgorithm[HASHID_HAVAL]) haval_hash(&m_haval, pBuf, uRead); if(m_bAlgorithm[HASHID_MD2]) m_md2.Update(pBuf, uRead); if(m_bAlgorithm[HASHID_MD4]) MD4Update(&m_md4, pBuf, uRead); if(m_bAlgorithm[HASHID_MD5]) MD5Update(&m_md5, pBuf, uRead); if(m_bAlgorithm[HASHID_SHA1]) sha1_hash(pBuf, uRead, &m_sha1); if(m_bAlgorithm[HASHID_SHA2_256]) sha256_hash(pBuf, uRead, &m_sha256); if(m_bAlgorithm[HASHID_SHA2_384]) sha384_hash(pBuf, uRead, &m_sha384); if(m_bAlgorithm[HASHID_SHA2_512]) sha512_hash(pBuf, uRead, &m_sha512); if(m_bAlgorithm[HASHID_SIZE_32]) sizehash32_hash(&m_uSizeHash32, uRead); if(m_bAlgorithm[HASHID_TIGER]) tiger_process(&m_tiger, pBuf, uRead); } if(uRead != SIZE_HASH_BUFFER) break; } fclose(fp); fp = NULL; // SizeHash-32 is the first hash, because it's the simplest one, // the fastest, and most widely used one. ;-) if(m_bAlgorithm[HASHID_SIZE_32]) { sizehash32_end(&m_uSizeHash32); printf(SZ_SIZEHASH_32); printf(SZ_HASHPRE); printf("%08X", m_uSizeHash32); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_CRC16]) { crc16_final(&m_crc16); printf(SZ_CRC16); printf(SZ_HASHPRE); printf("%04X", m_crc16); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_CRC16CCITT]) { crc16ccitt_final(&m_crc16ccitt); printf(SZ_CRC16CCITT); printf(SZ_HASHPRE); printf("%04X", m_crc16ccitt); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_CRC32]) { crc32Finish(&m_crc32); printf(SZ_CRC32); printf(SZ_HASHPRE); printf("%08X", m_crc32); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_FCS_16]) { fcs16_final(&m_fcs16); printf(SZ_FCS_16); printf(SZ_HASHPRE); printf("%04X", m_fcs16); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_FCS_32]) { fcs32_final(&m_fcs32); printf(SZ_FCS_32); printf(SZ_HASHPRE); printf("%08X", m_fcs32); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_GHASH_32_3]) { m_ghash.FinalToStr(szTemp, 3); printf(SZ_GHASH_32_3); printf(SZ_HASHPRE); printf(szTemp); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_GHASH_32_5]) { m_ghash.FinalToStr(szTemp, 5); printf(SZ_GHASH_32_5); printf(SZ_HASHPRE); printf(szTemp); printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_GOST]) { gosthash_final(&m_gost, pTemp); printf(SZ_GOST); printf(SZ_HASHPRE); for(i = 0; i < 32; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_HAVAL]) { haval_end(&m_haval, pTemp); printf(SZ_HAVAL); printf(SZ_HASHPRE); for(i = 0; i < 32; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_MD2]) { m_md2.TruncatedFinal(pTemp, 16); printf(SZ_MD2); printf(SZ_HASHPRE); for(i = 0; i < 16; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_MD4]) { MD4Final(pTemp, &m_md4); printf(SZ_MD4); printf(SZ_HASHPRE); for(i = 0; i < 16; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_MD5]) { MD5Final(&m_md5); printf(SZ_MD5); printf(SZ_HASHPRE); for(i = 0; i < 16; i++) { fmtFixHashOutput(i); printf("%02X", m_md5.digest[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_SHA1]) { sha1_end(pTemp, &m_sha1); printf(SZ_SHA1); printf(SZ_HASHPRE); for(i = 0; i < 20; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_SHA2_256]) { sha256_end(pTemp, &m_sha256); printf(SZ_SHA2_256); printf(SZ_HASHPRE); for(i = 0; i < 32; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_SHA2_384]) { sha384_end(pTemp, &m_sha384); printf(SZ_SHA2_384); printf(SZ_HASHPRE); for(i = 0; i < 48; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_SHA2_512]) { sha512_end(pTemp, &m_sha512); printf(SZ_SHA2_512); printf(SZ_HASHPRE); for(i = 0; i < 64; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[i]); } printf(CPS_NEWLINE); } if(m_bAlgorithm[HASHID_TIGER]) { tiger_done(&m_tiger, pTemp); printf(SZ_TIGER); printf(SZ_HASHPRE); for(i = 0; i < 8; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[7-i]); } for(i = 8; i < 16; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[23-i]); } for(i = 16; i < 24; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[39-i]); } printf(CPS_NEWLINE); } return RH_SUCCESS; }
int main_loop(int argc, const char **argv_) { vpx_codec_ctx_t decoder; char *fn = NULL; int i; uint8_t *buf = NULL; size_t bytes_in_buffer = 0, buffer_size = 0; FILE *infile; int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0; int do_md5 = 0, progress = 0; int stop_after = 0, postproc = 0, summary = 0, quiet = 1; int arg_skip = 0; int ec_enabled = 0; const VpxInterface *interface = NULL; const VpxInterface *fourcc_interface = NULL; uint64_t dx_time = 0; struct arg arg; char **argv, **argi, **argj; int single_file; int use_y4m = 1; vpx_codec_dec_cfg_t cfg = {0}; #if CONFIG_VP8_DECODER vp8_postproc_cfg_t vp8_pp_cfg = {0}; int vp8_dbg_color_ref_frame = 0; int vp8_dbg_color_mb_modes = 0; int vp8_dbg_color_b_modes = 0; int vp8_dbg_display_mv = 0; #endif int frames_corrupted = 0; int dec_flags = 0; int do_scale = 0; vpx_image_t *scaled_img = NULL; int frame_avail, got_data; int num_external_frame_buffers = 0; struct ExternalFrameBufferList ext_fb_list = {0}; const char *outfile_pattern = NULL; char outfile_name[PATH_MAX] = {0}; FILE *outfile = NULL; MD5Context md5_ctx; unsigned char md5_digest[16]; struct VpxDecInputContext input = {0}; struct VpxInputContext vpx_input_ctx = {0}; #if CONFIG_WEBM_IO struct WebmInputContext webm_ctx = {0}; input.webm_ctx = &webm_ctx; #endif input.vpx_input_ctx = &vpx_input_ctx; /* Parse command line */ exec_name = argv_[0]; argv = argv_dup(argc - 1, argv_ + 1); for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { memset(&arg, 0, sizeof(arg)); arg.argv_step = 1; if (arg_match(&arg, &codecarg, argi)) { interface = get_vpx_decoder_by_name(arg.val); if (!interface) die("Error: Unrecognized argument (%s) to --codec\n", arg.val); } else if (arg_match(&arg, &looparg, argi)) { // no-op } else if (arg_match(&arg, &outputfile, argi)) outfile_pattern = arg.val; else if (arg_match(&arg, &use_yv12, argi)) { use_y4m = 0; flipuv = 1; } else if (arg_match(&arg, &use_i420, argi)) { use_y4m = 0; flipuv = 0; } else if (arg_match(&arg, &flipuvarg, argi)) flipuv = 1; else if (arg_match(&arg, &noblitarg, argi)) noblit = 1; else if (arg_match(&arg, &progressarg, argi)) progress = 1; else if (arg_match(&arg, &limitarg, argi)) stop_after = arg_parse_uint(&arg); else if (arg_match(&arg, &skiparg, argi)) arg_skip = arg_parse_uint(&arg); else if (arg_match(&arg, &postprocarg, argi)) postproc = 1; else if (arg_match(&arg, &md5arg, argi)) do_md5 = 1; else if (arg_match(&arg, &summaryarg, argi)) summary = 1; else if (arg_match(&arg, &threadsarg, argi)) cfg.threads = arg_parse_uint(&arg); else if (arg_match(&arg, &verbosearg, argi)) quiet = 0; else if (arg_match(&arg, &scalearg, argi)) do_scale = 1; else if (arg_match(&arg, &fb_arg, argi)) num_external_frame_buffers = arg_parse_uint(&arg); #if CONFIG_VP8_DECODER else if (arg_match(&arg, &addnoise_level, argi)) { postproc = 1; vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE; vp8_pp_cfg.noise_level = arg_parse_uint(&arg); } else if (arg_match(&arg, &demacroblock_level, argi)) { postproc = 1; vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK; vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg); } else if (arg_match(&arg, &deblock, argi)) { postproc = 1; vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK; } else if (arg_match(&arg, &mfqe, argi)) { postproc = 1; vp8_pp_cfg.post_proc_flag |= VP8_MFQE; } else if (arg_match(&arg, &pp_debug_info, argi)) { unsigned int level = arg_parse_uint(&arg); postproc = 1; vp8_pp_cfg.post_proc_flag &= ~0x7; if (level) vp8_pp_cfg.post_proc_flag |= level; } else if (arg_match(&arg, &pp_disp_ref_frame, argi)) { unsigned int flags = arg_parse_int(&arg); if (flags) { postproc = 1; vp8_dbg_color_ref_frame = flags; } } else if (arg_match(&arg, &pp_disp_mb_modes, argi)) { unsigned int flags = arg_parse_int(&arg); if (flags) { postproc = 1; vp8_dbg_color_mb_modes = flags; } } else if (arg_match(&arg, &pp_disp_b_modes, argi)) { unsigned int flags = arg_parse_int(&arg); if (flags) { postproc = 1; vp8_dbg_color_b_modes = flags; } } else if (arg_match(&arg, &pp_disp_mvs, argi)) { unsigned int flags = arg_parse_int(&arg); if (flags) { postproc = 1; vp8_dbg_display_mv = flags; } } else if (arg_match(&arg, &error_concealment, argi)) { ec_enabled = 1; } #endif else argj++; } /* Check for unrecognized options */ for (argi = argv; *argi; argi++) if (argi[0][0] == '-' && strlen(argi[0]) > 1) die("Error: Unrecognized option %s\n", *argi); /* Handle non-option arguments */ fn = argv[0]; if (!fn) usage_exit(); /* Open file */ infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin); if (!infile) { fprintf(stderr, "Failed to open file '%s'", strcmp(fn, "-") ? fn : "stdin"); return EXIT_FAILURE; } #if CONFIG_OS_SUPPORT /* Make sure we don't dump to the terminal, unless forced to with -o - */ if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) { fprintf(stderr, "Not dumping raw video to your terminal. Use '-o -' to " "override.\n"); return EXIT_FAILURE; } #endif input.vpx_input_ctx->file = infile; if (file_is_ivf(input.vpx_input_ctx)) input.vpx_input_ctx->file_type = FILE_TYPE_IVF; #if CONFIG_WEBM_IO else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx)) input.vpx_input_ctx->file_type = FILE_TYPE_WEBM; #endif else if (file_is_raw(input.vpx_input_ctx)) input.vpx_input_ctx->file_type = FILE_TYPE_RAW; else { fprintf(stderr, "Unrecognized input file type.\n"); #if !CONFIG_WEBM_IO fprintf(stderr, "vpxdec was built without WebM container support.\n"); #endif return EXIT_FAILURE; } outfile_pattern = outfile_pattern ? outfile_pattern : "-"; single_file = is_single_file(outfile_pattern); if (!noblit && single_file) { generate_filename(outfile_pattern, outfile_name, PATH_MAX, vpx_input_ctx.width, vpx_input_ctx.height, 0); if (do_md5) MD5Init(&md5_ctx); else outfile = open_outfile(outfile_name); } if (use_y4m && !noblit) { if (!single_file) { fprintf(stderr, "YUV4MPEG2 not supported with output patterns," " try --i420 or --yv12.\n"); return EXIT_FAILURE; } #if CONFIG_WEBM_IO if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) { if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) { fprintf(stderr, "Failed to guess framerate -- error parsing " "webm file?\n"); return EXIT_FAILURE; } } #endif } fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc); if (interface && fourcc_interface && interface != fourcc_interface) warn("Header indicates codec: %s\n", fourcc_interface->name); else interface = fourcc_interface; if (!interface) interface = get_vpx_decoder_by_index(0); dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) | (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0); if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) { fprintf(stderr, "Failed to initialize decoder: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } if (!quiet) fprintf(stderr, "%s\n", decoder.name); #if CONFIG_VP8_DECODER if (vp8_pp_cfg.post_proc_flag && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) { fprintf(stderr, "Failed to configure postproc: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } if (vp8_dbg_color_ref_frame && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_REF_FRAME, vp8_dbg_color_ref_frame)) { fprintf(stderr, "Failed to configure reference block visualizer: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } if (vp8_dbg_color_mb_modes && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_MB_MODES, vp8_dbg_color_mb_modes)) { fprintf(stderr, "Failed to configure macro block visualizer: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } if (vp8_dbg_color_b_modes && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_B_MODES, vp8_dbg_color_b_modes)) { fprintf(stderr, "Failed to configure block visualizer: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } if (vp8_dbg_display_mv && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv)) { fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } #endif if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip); while (arg_skip) { if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break; arg_skip--; } if (num_external_frame_buffers > 0) { ext_fb_list.num_external_frame_buffers = num_external_frame_buffers; ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc( num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb)); if (vpx_codec_set_frame_buffer_functions( &decoder, get_vp9_frame_buffer, release_vp9_frame_buffer, &ext_fb_list)) { fprintf(stderr, "Failed to configure external frame buffers: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } } frame_avail = 1; got_data = 0; /* Decode file */ while (frame_avail || got_data) { vpx_codec_iter_t iter = NULL; vpx_image_t *img; struct vpx_usec_timer timer; int corrupted; frame_avail = 0; if (!stop_after || frame_in < stop_after) { if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) { frame_avail = 1; frame_in++; vpx_usec_timer_start(&timer); if (vpx_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer, NULL, 0)) { const char *detail = vpx_codec_error_detail(&decoder); warn("Failed to decode frame %d: %s", frame_in, vpx_codec_error(&decoder)); if (detail) warn("Additional information: %s", detail); goto fail; } vpx_usec_timer_mark(&timer); dx_time += vpx_usec_timer_elapsed(&timer); } } vpx_usec_timer_start(&timer); got_data = 0; if ((img = vpx_codec_get_frame(&decoder, &iter))) { ++frame_out; got_data = 1; } vpx_usec_timer_mark(&timer); dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer); if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) { warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder)); goto fail; } frames_corrupted += corrupted; if (progress) show_progress(frame_in, frame_out, dx_time); if (!noblit && img) { const int PLANES_YUV[] = {VPX_PLANE_Y, VPX_PLANE_U, VPX_PLANE_V}; const int PLANES_YVU[] = {VPX_PLANE_Y, VPX_PLANE_V, VPX_PLANE_U}; const int *planes = flipuv ? PLANES_YVU : PLANES_YUV; if (do_scale) { if (frame_out == 1) { // If the output frames are to be scaled to a fixed display size then // use the width and height specified in the container. If either of // these is set to 0, use the display size set in the first frame // header. If that is unavailable, use the raw decoded size of the // first decoded frame. int display_width = vpx_input_ctx.width; int display_height = vpx_input_ctx.height; if (!display_width || !display_height) { int display_size[2]; if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE, display_size)) { // As last resort use size of first frame as display size. display_width = img->d_w; display_height = img->d_h; } else { display_width = display_size[0]; display_height = display_size[1]; } } scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, display_width, display_height, 16); } if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) { vpx_image_scale(img, scaled_img, kFilterBox); img = scaled_img; } } if (single_file) { if (use_y4m) { char buf[Y4M_BUFFER_SIZE] = {0}; size_t len = 0; if (frame_out == 1) { // Y4M file header len = y4m_write_file_header(buf, sizeof(buf), vpx_input_ctx.width, vpx_input_ctx.height, &vpx_input_ctx.framerate, img->fmt); if (do_md5) { MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len); } else { fputs(buf, outfile); } } // Y4M frame header len = y4m_write_frame_header(buf, sizeof(buf)); if (do_md5) { MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len); } else { fputs(buf, outfile); } } if (do_md5) { update_image_md5(img, planes, &md5_ctx); } else { write_image_file(img, planes, outfile); } } else { generate_filename(outfile_pattern, outfile_name, PATH_MAX, img->d_w, img->d_h, frame_in); if (do_md5) { MD5Init(&md5_ctx); update_image_md5(img, planes, &md5_ctx); MD5Final(md5_digest, &md5_ctx); print_md5(md5_digest, outfile_name); } else { outfile = open_outfile(outfile_name); write_image_file(img, planes, outfile); fclose(outfile); } } } if (stop_after && frame_in >= stop_after) break; } if (summary || progress) { show_progress(frame_in, frame_out, dx_time); fprintf(stderr, "\n"); } if (frames_corrupted) fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted); fail: if (vpx_codec_destroy(&decoder)) { fprintf(stderr, "Failed to destroy decoder: %s\n", vpx_codec_error(&decoder)); return EXIT_FAILURE; } if (!noblit && single_file) { if (do_md5) { MD5Final(md5_digest, &md5_ctx); print_md5(md5_digest, outfile_name); } else { fclose(outfile); } } #if CONFIG_WEBM_IO if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM) webm_free(input.webm_ctx); #endif if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM) free(buf); if (scaled_img) vpx_img_free(scaled_img); for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) { free(ext_fb_list.ext_fb[i].data); } free(ext_fb_list.ext_fb); fclose(infile); free(argv); return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS; }
int checkFileCopy(char *fileName){ int flag = 1; int i; char md5Hash[16] = {0}; int mySize = 0; FILE *inFile = fopen (fileName, "rb"); MD5_CTX mdContext; int bytes; unsigned char data[1024]; if (inFile == NULL) { printf ("%s can't be opened.\n", fileName); return; } MD5Init (&mdContext); while ((bytes = fread (data, 1, 1024, inFile)) != 0){ MD5Update (&mdContext, data, bytes); mySize += bytes; } MD5Final (&mdContext); for (i = 0; i < 16; i++) sprintf (md5Hash+2*i, "%02x", mdContext.digest[i]); fclose (inFile); // Both threads have MD5 hash. //printf("PATH %s HASH VALUE %s", fileName, md5Hash); //If it is not a directory, assumed that it is a regular file and not a - fifo , pipe or any other special file. //Send name of file -> If matched, send size of file -> If matched, send a hash code if(pthread_equal(pthread_self(), ids[0])>0){ //MASTER THREAD //printf("FULLPATH %s\n", fileName); fileSize = mySize; pthread_mutex_lock(&mutex_lock_object); thread_state = 2; pthread_mutex_unlock(&mutex_lock_object); while(thread_state==2){ } //printf("GOT RESPONSE 1\n"); if(thread_state==21){ for (i = 0; i < 16; i++){ fileHash[i] = md5Hash[i]; } pthread_mutex_lock(&mutex_lock_object); thread_state = 2; pthread_mutex_unlock(&mutex_lock_object); while(thread_state==2){ } //printf("GOT RESPONSE 2\n"); if(thread_state==21){ } else{ flag = 0; //printf("HASH UNEQUAL\n"); } } else{ flag = 0; //printf("SIZE UNEQUAL\n"); } //printf("THREAD 1 EXITS\n"); } else{ //SLAVE THREAD //printf("FULLPATH %s\n", fileName); while(thread_state!=2){ } if(mySize == fileSize){ pthread_mutex_lock(&mutex_lock_object); thread_state = 21; pthread_mutex_unlock(&mutex_lock_object); while(thread_state!=2){ } if(strncmp(md5Hash, fileHash, 16)==0){ pthread_mutex_lock(&mutex_lock_object); thread_state = 21; pthread_mutex_unlock(&mutex_lock_object); } else{ pthread_mutex_lock(&mutex_lock_object); thread_state = 22; pthread_mutex_unlock(&mutex_lock_object); } } else{ pthread_mutex_lock(&mutex_lock_object); thread_state = 22; pthread_mutex_unlock(&mutex_lock_object); } //printf("THREAD 2 EXITS\n"); } return flag; }
int ICACHE_FLASH_ATTR CustomCommand(char * buffer, int retsize, char *pusrdata, unsigned short len) { char * buffend = buffer; switch( pusrdata[1] ) { case 'C': case 'c': //Custom command test { buffend += ets_sprintf( buffend, "CC\n" ); return buffend-buffer; } case 'A': case 'a': //AVR Commands { switch( pusrdata[2] ) { case 'R': case 'r': { buffend += ets_sprintf( buffend, "AR\n" ); return buffend-buffer; } case 'F': case 'f': { int i; char md5h[48]; char md5hraw[48]; MD5_CTX md5ctx; char * colon = (char *) ets_strstr( (char*)&pusrdata[3], "\t" ); char * colon2 = (colon)?((char *)ets_strstr( (char*)(colon+1), "\t" )):0; if( !colon || !colon2 ) break; *colon = 0; colon++; *colon2 = 0; colon2++; uint32_t from = my_atoi( &pusrdata[3] ); uint32_t len = my_atoi( colon ); char * md5 = colon2; printf( "caffer %d %d %s\n", from, len, md5 ); MD5Init( &md5ctx ); if( keylen ) MD5Update( &md5ctx, key, keylen ); SafeMD5Update( &md5ctx, (uint8_t*)0x40200000 + from, len ); MD5Final( md5hraw, &md5ctx ); for( i = 0; i < 16; i++ ) { ets_sprintf( md5h+i*2, "%02x", md5hraw[i] ); } printf( "AVR Program MD5s: %s == %s\n", md5h, md5 ); for( i = 0; i < 32; i++ ) { if( md5[i] != md5h[i] ) { break; } } if( i != 32 ) break; int r = ProgramAVRFlash( (uint8_t*)0x40200000+from, len ); if( r ) { buffend += ets_sprintf( buffend, "!CAF\t%d\r\n", r ); } else { buffend += ets_sprintf( buffend, "CAF\r\n" ); } return buffend-buffer; } default: break; } buffend += ets_sprintf( buffend, "!CA%c\t-99\r\n", pusrdata[2] ); return buffend-buffer; } } return -1; }
/* * SIP_CALCULATE_BRANCH * * Calculates a branch parameter according to RFC3261 section 16.11 * * The returned 'id' will be HASHHEXLEN + strlen(magic_cookie) * characters (32 + 7) long. The caller must supply at least this * amount of space in 'id'. * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int sip_calculate_branch_id (sip_ticket_t *ticket, char *id) { /* RFC3261 section 16.11 recommends the following procedure: * The stateless proxy MAY use any technique it likes to guarantee * uniqueness of its branch IDs across transactions. However, the * following procedure is RECOMMENDED. The proxy examines the * branch ID in the topmost Via header field of the received * request. If it begins with the magic cookie, the first * component of the branch ID of the outgoing request is computed * as a hash of the received branch ID. Otherwise, the first * component of the branch ID is computed as a hash of the topmost * Via, the tag in the To header field, the tag in the From header * field, the Call-ID header field, the CSeq number (but not * method), and the Request-URI from the received request. One of * these fields will always vary across two different * transactions. * * The branch value will consist of: * - magic cookie "z9hG4bK" * - 1st part (unique calculated ID * - 2nd part (value for loop detection) <<- not yet used by siproxd */ osip_message_t *sip_msg=ticket->sipmsg; static char *magic_cookie="z9hG4bK"; osip_via_t *via; osip_uri_param_t *param=NULL; osip_call_id_t *call_id=NULL; HASHHEX hashstring; hashstring[0]='\0'; /* * Examine topmost via and look for a magic cookie. * If it is there, I use THIS branch parameter as input for * our hash calculation */ via = osip_list_get (sip_msg->vias, 0); if (via == NULL) { ERROR("have a SIP message without any via header"); return STS_FAILURE; } param=NULL; osip_via_param_get_byname(via, "branch", ¶m); if (param && param->gvalue) { DEBUGC(DBCLASS_BABBLE, "looking for magic cookie [%s]",param->gvalue); if (strncmp(param->gvalue, magic_cookie, strlen(magic_cookie))==0) { /* calculate MD5 hash */ MD5_CTX Md5Ctx; HASH HA1; MD5Init(&Md5Ctx); MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue)); MD5Final(HA1, &Md5Ctx); CvtHex(HA1, hashstring); DEBUGC(DBCLASS_BABBLE, "existing branch -> branch hash [%s]", hashstring); } } /* * If I don't have a branch parameter in the existing topmost via, * then I need: * - the topmost via * - the tag in the To header field * - the tag in the From header field * - the Call-ID header field * - the CSeq number (but not method) * - the Request-URI from the received request */ if (hashstring[0] == '\0') { /* calculate MD5 hash */ MD5_CTX Md5Ctx; HASH HA1; char *tmp; MD5Init(&Md5Ctx); /* topmost via */ osip_via_to_str(via, &tmp); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); osip_free(tmp); } /* Tag in To header */ osip_to_get_tag(sip_msg->to, ¶m); if (param && param->gvalue) { MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue)); } /* Tag in From header */ osip_from_get_tag(sip_msg->from, ¶m); if (param && param->gvalue) { MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue)); } /* Call-ID */ call_id = osip_message_get_call_id(sip_msg); osip_call_id_to_str(call_id, &tmp); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); osip_free(tmp); } /* CSeq number (but not method) */ tmp = osip_cseq_get_number(sip_msg->cseq); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); } /* Request URI */ osip_uri_to_str(sip_msg->req_uri, &tmp); if (tmp) { MD5Update(&Md5Ctx, tmp, strlen(tmp)); osip_free(tmp); } MD5Final(HA1, &Md5Ctx); CvtHex(HA1, hashstring); DEBUGC(DBCLASS_BABBLE, "non-existing branch -> branch hash [%s]", hashstring); } /* include the magic cookie */ sprintf(id, "%s%s", magic_cookie, hashstring); return STS_SUCCESS; }
/* * calculate hash response for digest auth. * outresp must be buffer of at least DIGEST_HEX_SIZE * outresp and hex_int may be the same * method may be NULL if mlen is 0 */ static void digest_calc_resp(const digest_attrs_t *attr, CONST_UCHAR *hash_a1, const char *method, int mlen, CONST_UCHAR *hex_int, char *outresp) { static CONST_UCHAR defncount[] = ":00000001:"; static CONST_UCHAR empty_hex_int[] = "00000000000000000000000000000000"; MD5_CTX ctx; unsigned char resp[DIGEST_SIZE]; unsigned char *hex_a1 = (unsigned char *) outresp; unsigned char *hex_a2 = (unsigned char *) outresp; unsigned j; /* compute hash of A2 and put in resp */ MD5Init(&ctx); if (mlen == 0 && method != NULL) mlen = strlen(method); if (mlen) MD5Update(&ctx, (CONST_UCHAR *) method, mlen); MD5Update(&ctx, colon, 1); if (attr->urilen != 0) { MD5Update(&ctx, (CONST_UCHAR *) attr->uri, attr->urilen); } if (attr->qlen != 4 || strncasecmp(attr->qop, "auth", 4) != 0) { MD5Update(&ctx, colon, 1); if (hex_int == NULL) hex_int = empty_hex_int; MD5Update(&ctx, hex_int, DIGEST_SIZE * 2); } MD5Final(resp, &ctx); /* compute hex_a1 from hash_a1 */ for (j = 0; j < DIGEST_SIZE; ++j) { hex_a1[j * 2] = hextab[hash_a1[j] >> 4]; hex_a1[j * 2 + 1] = hextab[hash_a1[j] & 0xf]; } /* compute response */ MD5Init(&ctx); MD5Update(&ctx, hex_a1, DIGEST_SIZE * 2); MD5Update(&ctx, colon, 1); MD5Update(&ctx, (CONST_UCHAR *) attr->nonce, attr->nlen); if (attr->ncount != NULL) { MD5Update(&ctx, colon, 1); MD5Update(&ctx, (CONST_UCHAR *) attr->ncount, attr->nclen); MD5Update(&ctx, colon, 1); } else { MD5Update(&ctx, defncount, sizeof (defncount) - 1); } MD5Update(&ctx, (CONST_UCHAR *) attr->cnonce, attr->clen); MD5Update(&ctx, colon, 1); MD5Update(&ctx, (CONST_UCHAR *) attr->qop, attr->qlen); MD5Update(&ctx, colon, 1); /* compute hex_a2 from hash_a2 */ for (j = 0; j < DIGEST_SIZE; ++j) { hex_a2[j * 2] = hextab[resp[j] >> 4]; hex_a2[j * 2 + 1] = hextab[resp[j] & 0xf]; } MD5Update(&ctx, hex_a2, DIGEST_SIZE * 2); MD5Final(resp, &ctx); /* generate hex output */ for (j = 0; j < DIGEST_SIZE; ++j) { outresp[j * 2] = hextab[resp[j] >> 4]; outresp[j * 2 + 1] = hextab[resp[j] & 0xf]; } outresp[DIGEST_SIZE * 2] = '\0'; memset(resp, 0, sizeof (resp)); }
static NTSTATUS ntlmssp3_client_challenge(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *out_mem_ctx, /* Unused at this time */ const DATA_BLOB reply, DATA_BLOB *next_request) { uint32_t chal_flags, ntlmssp_command, unkn1, unkn2; DATA_BLOB server_domain_blob; DATA_BLOB challenge_blob; DATA_BLOB struct_blob = data_blob_null; char *server_domain; const char *chal_parse_string; const char *auth_gen_string; DATA_BLOB lm_response = data_blob_null; DATA_BLOB nt_response = data_blob_null; DATA_BLOB session_key = data_blob_null; DATA_BLOB encrypted_session_key = data_blob_null; NTSTATUS nt_status = NT_STATUS_OK; bool anon = ntlmssp_is_anonymous(ntlmssp_state); if (!anon && ntlmssp_state->use_ccache) { struct wbcCredentialCacheParams params; struct wbcCredentialCacheInfo *info = NULL; struct wbcAuthErrorInfo *error = NULL; struct wbcNamedBlob auth_blob; struct wbcBlob *wbc_next = NULL; struct wbcBlob *wbc_session_key = NULL; wbcErr wbc_status; int i; /* * We need to set the netbios name or we are not able to connect * a Windows DC. */ if (ntlmssp_state->server.netbios_domain == NULL || ntlmssp_state->server.netbios_domain[0] == '\0') { ntlmssp_state->server.netbios_domain = ntlmssp_state->domain; } params.account_name = ntlmssp_state->user; params.domain_name = ntlmssp_state->domain; params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; auth_blob.name = "challenge_blob"; auth_blob.flags = 0; auth_blob.blob.data = reply.data; auth_blob.blob.length = reply.length; params.num_blobs = 1; params.blobs = &auth_blob; wbc_status = wbcCredentialCache(¶ms, &info, &error); wbcFreeMemory(error); if (!WBC_ERROR_IS_OK(wbc_status)) { goto noccache; } for (i=0; i<info->num_blobs; i++) { if (strequal(info->blobs[i].name, "auth_blob")) { wbc_next = &info->blobs[i].blob; } if (strequal(info->blobs[i].name, "session_key")) { wbc_session_key = &info->blobs[i].blob; } } if ((wbc_next == NULL) || (wbc_session_key == NULL)) { wbcFreeMemory(info); goto noccache; } *next_request = data_blob_talloc(ntlmssp_state, wbc_next->data, wbc_next->length); ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state, wbc_session_key->data, wbc_session_key->length); wbcFreeMemory(info); goto done; } noccache: if (!msrpc_parse(ntlmssp_state, &reply, "CdBd", "NTLMSSP", &ntlmssp_command, &server_domain_blob, &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); dump_data(2, reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } if (DEBUGLEVEL >= 10) { struct CHALLENGE_MESSAGE *challenge = talloc( talloc_tos(), struct CHALLENGE_MESSAGE); if (challenge != NULL) { NTSTATUS status; challenge->NegotiateFlags = chal_flags; status = ntlmssp_pull_CHALLENGE_MESSAGE( &reply, challenge, challenge); if (NT_STATUS_IS_OK(status)) { NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, challenge); } TALLOC_FREE(challenge); } } data_blob_free(&server_domain_blob); DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdUdbddB"; } else { chal_parse_string = "CdUdbdd"; } auth_gen_string = "CdBBUUUBd"; } else { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdAdbddB"; } else { chal_parse_string = "CdAdbdd"; } auth_gen_string = "CdBBAAABd"; } DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); if (!msrpc_parse(ntlmssp_state, &reply, chal_parse_string, "NTLMSSP", &ntlmssp_command, &server_domain, &chal_flags, &challenge_blob, 8, &unkn1, &unkn2, &struct_blob)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); dump_data(2, reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) { ntlmssp_state->server.is_standalone = true; } else { ntlmssp_state->server.is_standalone = false; } /* TODO: parse struct_blob and fill in the rest */ ntlmssp_state->server.netbios_name = ""; ntlmssp_state->server.netbios_domain = server_domain; ntlmssp_state->server.dns_name = ""; ntlmssp_state->server.dns_domain = ""; if (challenge_blob.length != 8) { data_blob_free(&struct_blob); return NT_STATUS_INVALID_PARAMETER; } if (anon || !ntlmssp_state->nt_hash) { static const uint8_t zeros[16] = {0, }; /* do nothing - blobs are zero length */ /* session key is all zeros */ session_key = data_blob_talloc(ntlmssp_state, zeros, 16); /* not doing NLTM2 without a password */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { if (!struct_blob.length) { /* be lazy, match win2k - we can't do NTLMv2 without it */ DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); return NT_STATUS_INVALID_PARAMETER; } /* TODO: if the remote server is standalone, then we should replace 'domain' with the server name as supplied above */ if (!SMBNTLMv2encrypt_hash(ntlmssp_state, ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->nt_hash, &challenge_blob, &struct_blob, &lm_response, &nt_response, NULL, &session_key)) { data_blob_free(&challenge_blob); data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { MD5_CTX md5_session_nonce_ctx; uint8_t session_nonce[16]; uint8_t session_nonce_hash[16]; uint8_t user_session_key[16]; lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); generate_random_buffer(lm_response.data, 8); memset(lm_response.data+8, 0, 16); memcpy(session_nonce, challenge_blob.data, 8); memcpy(&session_nonce[8], lm_response.data, 8); MD5Init(&md5_session_nonce_ctx); MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); DEBUG(5, ("challenge is: \n")); dump_data(5, session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBNTencrypt_hash(ntlmssp_state->nt_hash, session_nonce_hash, nt_response.data); session_key = data_blob_talloc(ntlmssp_state, NULL, 16); SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth() && ntlmssp_state->lm_hash) { lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data, lm_response.data); } nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data, nt_response.data); session_key = data_blob_talloc(ntlmssp_state, NULL, 16); if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lp_client_lanman_auth() && ntlmssp_state->lm_hash) { SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data, session_key.data); dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, session_key.data); dump_data_pw("NT session key:\n", session_key.data, session_key.length); } } data_blob_free(&struct_blob); /* Key exchange encryptes a new client-generated session key with the password-derived key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { /* Make up a new session key */ uint8_t client_session_key[16]; generate_random_buffer(client_session_key, sizeof(client_session_key)); /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); arcfour_crypt_blob(encrypted_session_key.data, encrypted_session_key.length, &session_key); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ data_blob_free(&session_key); session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key)); } /* this generates the actual auth packet */ nt_status = msrpc_gen(ntlmssp_state, next_request, auth_gen_string, "NTLMSSP", NTLMSSP_AUTH, lm_response.data, lm_response.length, nt_response.data, nt_response.length, ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->client.netbios_name, encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags); if (!NT_STATUS_IS_OK(nt_status)) { return NT_STATUS_NO_MEMORY; } if (DEBUGLEVEL >= 10) { struct AUTHENTICATE_MESSAGE *authenticate = talloc( talloc_tos(), struct AUTHENTICATE_MESSAGE); if (authenticate != NULL) { NTSTATUS status; authenticate->NegotiateFlags = ntlmssp_state->neg_flags; status = ntlmssp_pull_AUTHENTICATE_MESSAGE( next_request, authenticate, authenticate); if (NT_STATUS_IS_OK(status)) { NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, authenticate); } TALLOC_FREE(authenticate); } } data_blob_free(&encrypted_session_key); data_blob_free(&ntlmssp_state->chal); ntlmssp_state->session_key = session_key; ntlmssp_state->chal = challenge_blob; ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; done: ntlmssp_state->expected_state = NTLMSSP_DONE; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); } return nt_status; }
int capi2_checkuser2(int fd, char *user, char *passwd) { #define CCHECK_ERR -1 int ev; struct { CAPI_control_req_t req; char buffer[256]; } r; struct { CAPI_control_conf_ex_t conf; char buffer[256]; } a; union CAPI_primitives *cmsg = (union CAPI_primitives *)&a; int len; int chall_len = 0; char *chall = NULL; struct userdata *data; md5context_t md5Context; memset(&r.req, 0, sizeof(r.req)); if (user == NULL) { return 0; /* OK no authentication desired */ } if (passwd == NULL) { passwd = ""; } PUT_WORD( r.req.len , sizeof(r.req)); PUT_WORD( r.req.appl , fd); PUT_WORD( r.req.PRIM_type , CAPI_CONTROL_REQ); PUT_WORD( r.req.messid , 0); PUT_WORD( r.req.contrl , 0); PUT_WORD( r.req.type , CTRL_GETCHALLENGE); PUT_BYTE( r.req.structlen , 0); if ((ev = capi2_put_message( fd, (char *)&r)) != 0) { cTRACE( 1, fprintf( stderr, "capi2_put_message rn=0x%x\n", ev)); capi2_errno = ev; return CCHECK_ERR; } if ((ev = capi2_wait_for_signal(fd, MAXRTT)) != 0) { cTRACE(1, fprintf(stderr, "capi2_wait_for_signal 0x%x\n", ev)); capi2_errno = ev; return CCHECK_ERR; } if ((ev = capi2_get_message( fd, &cmsg, (union CAPI_primitives *)&a, NULL, 0)) != 0) { cTRACE( 1, fprintf( stderr, "capi2_get_message rn=0x%x\n", ev)); capi2_errno = ev; return CCHECK_ERR; } if (GET_PRIMTYPE(cmsg) == CAPI_CONTROL_CONF && GET_WORD(a.conf.type) == CTRL_GETCHALLENGE /* get random number */ && a.conf.structlen ) { chall_len = (size_t)a.conf.structlen; chall = a.buffer; /* random number computed by the brick */ } else { cTRACE( 1, fprintf( stderr, "CAPI_CONTROL_CONF failed\n")); capi2_errno = CAPI2_E_REG_OS_RESOURCE_ERROR; return CCHECK_ERR; } /* * calculate hash value; * see RFC 1321 for a description of the MD5 algorithm */ MD5Init(&md5Context); MD5Update (&md5Context, (unsigned char *) user, strlen(user)); MD5Update (&md5Context, chall, chall_len); MD5Update (&md5Context, (unsigned char *) passwd, strlen(passwd)); MD5Final (&md5Context); PUT_WORD( r.req.appl , fd); PUT_WORD( r.req.PRIM_type , CAPI_CONTROL_REQ); PUT_WORD( r.req.messid , 0); PUT_WORD( r.req.contrl , 0); PUT_WORD( r.req.type , CTRL_SETUSER); /* copy user and hash value */ data = (struct userdata *)&r.req.structlen; data->length = strlen(user); memcpy( data->data, user, data->length); data = (struct userdata *)&data->data[data->length]; data->length = CAPI_MD5_HASH_LEN; memcpy( data->data, md5Context.digest, CAPI_MD5_HASH_LEN); /* hash value to be compared */ data = (struct userdata *)&data->data[data->length]; /* on the other side */ len = (char *)data - (char *)&r; PUT_WORD( r.req.len, len ); if ((ev = capi2_put_message( fd, (char *)&r)) != 0) { cTRACE( 1, fprintf( stderr, "capi2_put_message rn=0x%x\n", ev)); capi2_errno = ev; return CCHECK_ERR; } if ((ev = capi2_wait_for_signal(fd, MAXRTT)) != 0) { cTRACE(1, fprintf(stderr, "capi2_wait_for_signal 0x%x\n", ev)); capi2_errno = ev; return CCHECK_ERR; } if ((ev = capi2_get_message( fd, &cmsg, (union CAPI_primitives *)&a, NULL, 0)) != 0) { cTRACE( 1, fprintf( stderr, "capi2_get_message rn=0x%x\n", ev)); capi2_errno = ev; return CCHECK_ERR; } if (GET_PRIMTYPE(cmsg) == CAPI_CONTROL_CONF && GET_WORD(a.conf.type) == CTRL_SETUSER && GET_WORD(a.conf.info) == 1 ) { return 0; /* OK authentication passed */ } cTRACE( 1, fprintf( stderr, "CAPI_CONTROL_CONF failed, invalid authentication")); capi2_errno = CAPI2_E_REG_EXT_EQUIPMENT_NOT_SUPPORTED; return CCHECK_ERR; }
void rxpacket(int sock) { Packet pkt; memset(&pkt, 0, sizeof(pkt)); // using recvmsg int size; // size of the received data struct msghdr msg; memset(&msg, 0, sizeof(msg)); struct sockaddr_in from; int fromlen=sizeof(from); msg.msg_name = &from; msg.msg_namelen = fromlen; char anciliary[2048]; msg.msg_control = anciliary; msg.msg_controllen = sizeof(anciliary); struct iovec iov[1]; memset(iov, 0, sizeof(iov)); iov[0].iov_base = &pkt.data; iov[0].iov_len = sizeof(pkt.data); msg.msg_iov = iov; msg.msg_iovlen = 1; struct cmsghdr *cmsg; unsigned int ifindex; // interface index struct in_addr hdraddr; // destination IP address in IP header size = recvmsg(sock, &msg, 0); if (size == -1) { ASSERT(0); rcpLog(muxsock, RCP_PROC_RIP, RLOG_ERR, RLOG_FC_RIP, "cannot read data on socket, attempting recovery..."); exit(1); } // verify packet size int sz = size - 4; if (sz<= 0 || (sz % sizeof(RipRoute)) != 0) { rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "Invalid RIP packet size"); return; } int routes = sz / sizeof(RipRoute); int found = 0; for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { // struct in_pktinfo { // unsigned int ipi_ifindex; /* Interface index */ // struct in_addr ipi_spec_dst; /* Local address */ // struct in_addr ipi_addr; /* Header Destination // address */ // }; hdraddr = ((struct in_pktinfo*)CMSG_DATA(cmsg))->ipi_addr; ifindex = ((struct in_pktinfo*)CMSG_DATA(cmsg))->ipi_ifindex; found = 1; } } if (!found) return; pkt.ip_source = ntohl(from.sin_addr.s_addr); pkt.ip_dest = ntohl(hdraddr.s_addr); pkt.if_index = ifindex; // is the source ip address one of our addresses? RcpInterface *rxif = rcpFindInterface(shm, pkt.ip_source); if (rxif) { // on Linux, packets we send to the multicast group will be received back on the socket return; } char *cmd[] = {"", "request", "response"}; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "Receiving RIP packet of size %d, from %d.%d.%d.%d, destination %d.%d.%d.%d, RIP %s, protocol version %d", size, RCP_PRINT_IP(pkt.ip_source), RCP_PRINT_IP(pkt.ip_dest), cmd[(pkt.data.command <= 2) ? pkt.data.command: 0], pkt.data.version); // update neighbor list RipNeighbor *neigh = neighbors; while (neigh != NULL) { if (neigh->ip == pkt.ip_source) { neigh->rx_time = 0; break; } neigh = neigh->next; } if (neigh == NULL) { RipNeighbor *newneigh = malloc(sizeof(RipNeighbor)); if (newneigh != NULL) { memset(newneigh, 0, sizeof(RipNeighbor)); newneigh->ip = pkt.ip_source; newneigh->next = neighbors; neighbors = newneigh; neigh = newneigh; } else { ASSERT(0); rcpLog(muxsock, RCP_PROC_RIP, RLOG_ERR, RLOG_FC_RIP, "cannot allocate memory, attempting recovery..."); exit(1); } } // do we have a valid interface? rxif =rcpFindInterfaceByKIndex(shm, pkt.if_index); if (rxif == NULL) { neigh->errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid interface, dropping..."); return; } // do we have a configured neighbor? RcpRipPartner *rxnetwork = NULL; RcpRipPartner *net; int i; for (i = 0, net = shm->config.rip_neighbor; i < RCP_RIP_NEIGHBOR_LIMIT; i++, net++) { if (!net->valid) continue; // matching both source and destination addresses if (net->ip == pkt.ip_source && rxif->ip == pkt.ip_dest) { rxnetwork = net; break; } } // if no configured neighbor was found, try to find a configured network if (rxnetwork == NULL) rxnetwork = find_network_for_interface(rxif); // no network or neighbor configured, just drop the packet if (rxnetwork == NULL) { neigh->errors++; // the network can get disabled while receiving packets rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid network or neighbor, dropping..."); return; } // the source of the datagram must be on a directly-connected network if ((pkt.ip_source & rxif->mask) != (rxif->ip & rxif->mask)) { neigh->errors++; // interface ip addresses are changing dynamically via CLI rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid source IP address, dropping..."); return; } // drop invalid command packets if (pkt.data.command > 2) { neigh->errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid RIP command, dropping..."); return; } if (pkt.data.command == 1) { rxnetwork->req_rx++; // force a response in one second rxif->rip_timeout = 1; return; } else rxnetwork->resp_rx++; ASSERT(sizeof(RipAuthMd5) == sizeof(RipAuthSimple)); ASSERT(sizeof(RipAuthSimple) == sizeof(RipRoute)); RipRoute *ptr = &pkt.data.routes[0]; int rt = 0; // if md5 auth configured, and the packet is missing the auth header, drop the packet if (rxif->rip_passwd[0] != '\0') { if (ptr->family != 0xffff || ntohs(ptr->tag) != 3) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " missing MD5 authentication header"); return; } } // checking auth header and calculate md5 if (ptr->family == 0xffff) { // we don't care about simple auth if (ntohs(ptr->tag) == 3 && rxif->rip_passwd[0] != '\0') { RipAuthMd5 *md5 = (RipAuthMd5 *) ptr; uint16_t offset = ntohs(md5->offset); uint32_t seq = ntohl(md5->seq); rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " MD5 auth offset %u, key id %d, auth_len %d, seq %u", offset, md5->key_id, md5->auth_len, ntohl(md5->seq)); // check offset if ((offset + sizeof(RipRoute)) != size) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid offset"); return; } // check seq if (seq != 0 && seq < neigh->auth_seq) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid sequence number"); return; } neigh->auth_seq = seq; // calculate md5 uint8_t secret[16]; memset(secret, 0, 16); memcpy(secret, rxif->rip_passwd, strlen(rxif->rip_passwd)); MD5_CTX context; uint8_t digest[16]; MD5Init (&context); MD5Update (&context, (uint8_t *) &pkt, size - 16); MD5Update (&context, secret, 16); MD5Final (digest, &context); #if 0 { int i; uint8_t *p = digest; printf("rx digest:\n"); for (i = 0; i < 16; i++,p++) printf("%02x ", *p); printf("\n"); } #endif // compare md5 if (memcmp((uint8_t *) ptr + offset, digest, 16) != 0) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid MD5 digest"); return; } } ptr++; rt++; routes--; // the last route is the digest } // parsing routes while (rt < routes) { uint32_t metric = ntohl(ptr->metric); uint32_t mask = ntohl(ptr->mask); uint32_t ip = ntohl(ptr->ip); uint32_t gw = ntohl(ptr->gw); // if (trace_prefix == 0 || // (trace_prefix != 0 && trace_prefix == ip)) { // if (gw == 0) // rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, // " %d.%d.%d.%d/%d metric %u", // RCP_PRINT_IP(ip), // mask2bits(mask), // metric); // else // rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, // " %d.%d.%d.%d/%d metric %u next hop %d.%d.%d.%d", // RCP_PRINT_IP(ip), // mask2bits(mask), // metric, // RCP_PRINT_IP(gw)); // } // only AF_INET family is supported if (ntohs(ptr->family) != AF_INET) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid route family"); goto next_element; } // check destination for loopback addresses if (isLoopback(ip)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid loopback route prefix"); goto next_element; } // check destination for broadcast addresses if (isBroadcast(ip)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid broadcast route prefix"); goto next_element; } // check destination for multicast addresses if (isMulticast(ip)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid multicast route prefix"); goto next_element; } // validate route metric else if (metric > 16 || metric == 0) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid metric"); goto next_element; } // validate route entry if (ip == 0 && mask == 0) { rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " received default route metric %d", metric); } else if (pkt.data.version == 2 && mask == 0) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid RIP route"); goto next_element; } else if (pkt.data.version == 1 && mask != 0) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid RIP route"); goto next_element; } // check if the mask is contiguous if (mask != 0 && !maskContiguous(mask)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid mask"); goto next_element; } // validate next hop if (gw) { if (isLoopback(gw) || isMulticast(gw) || isBroadcast(gw)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid next hop"); goto next_element; } } // manufacture mask for rip v1 if (pkt.data.version == 1) mask = classMask(ip); // RFC metric = metric + interface cost // we assume a cost of 1 for each interface metric++; // add the route in the database if (metric < 16) { //RFC //- Setting the destination address to the destination address in the // RTE // // - Setting the metric to the newly calculated metric (as described // above) // // - Set the next hop address to be the address of the router from which // the datagram came // // - Initialize the timeout for the route. If the garbage-collection // timer is running for this route, stop it (see section 3.6 for a // discussion of the timers) // // - Set the route change flag // // - Signal the output process to trigger an update (see section 3.8.1) // a next hop of 0 means send the packets to me if (gw == 0) gw = pkt.ip_source; ripdb_add(RCP_ROUTE_RIP, ip, mask, gw, metric, pkt.ip_source, rxif); } else { // a next hop of 0 means send the packets to me if (gw == 0) gw = pkt.ip_source; ripdb_delete(RCP_ROUTE_RIP, ip, mask, gw, pkt.ip_source); } next_element: ptr++; rt++; } }