Пример #1
0
/*********************************************************************
 *
 *         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;
}
Пример #2
0
/* 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 */
Пример #3
0
/*
 * 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);
}
Пример #4
0
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));
}
Пример #5
0
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();
		}
	}
}
Пример #6
0
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;
}
Пример #7
0
/*
 * 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;
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
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;
}
Пример #11
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;
    }
}
Пример #12
0
/*
 * 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);
}
Пример #13
0
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;
}
Пример #15
0
/**
 * 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;
}
Пример #16
0
/* MD5 Low Level Interface */
int md5_low_init(MD5_CTX *context) {
	MD5Init(context);

	return 0;
}
Пример #17
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;
}
Пример #18
0
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;
}
Пример #19
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;
}
Пример #20
0
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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #25
0
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;
}
Пример #26
0
/*
 * 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", &param);
   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, &param);
      if (param && param->gvalue) {
         MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue));
      }

      /* Tag in From header */
      osip_from_get_tag(sip_msg->from, &param);
      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;
}
Пример #27
0
/*
 * 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));
}
Пример #28
0
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(&params, &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;
}
Пример #29
0
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;
}
Пример #30
0
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++;
	}
}