diff --git a/README b/README index d69c925..6d3d63b 100644 --- a/README +++ b/README @@ -41,6 +41,7 @@ Options: -? Print this help --version Print program version -version Print program version + -type Use hash algorithmn . Types can be chained together as a comma-seperated list. -md5 Use md5 hash algorithmn -sha1 Use sha1 hash algorithmn -sha256 Use sha256 hash algorithmn @@ -149,6 +150,10 @@ USE EXAMPLES: Read lines from stdin, and generate an md5 hash in 'traditional' format for every line INCLUDING TRAILING WHITESPACE. This is compatible with 'echo text | md5sum' where 'text' is one line, as 'echo' adds a newline to the end of the text it outputs. + hashrat -type sha256,whirl,md5 + + Read data from stdin, hash it with sha256, then hash the resulting hash with whirlpool, then with md5 + hashrat * Generate a list of hashes for files in the current directory (default hash type is md5). diff --git a/check-hash.c b/check-hash.c index a82b4d9..483f901 100644 --- a/check-hash.c +++ b/check-hash.c @@ -71,6 +71,7 @@ int CheckFileHash(HashratCtx *Ctx, char *Path, struct stat *Stat, char *ActualHa int result=FALSE; if (strcasecmp(FP->Hash,ActualHash) != 0) HandleCheckFail(Path, "Hash mismatch"); + else { if (! (Flags & FLAG_OUTPUT_FAILS)) { @@ -118,6 +119,7 @@ return(result); } +//returns true on a significant event, meaning on FAIL int CheckHashesFromList(HashratCtx *Ctx) { char *HashStr=NULL, *ptr; @@ -150,7 +152,8 @@ while (FP) fprintf(stderr,"\nChecked %d files. %d Failures\n",Checked,Errors); DestroyString(HashStr); -if (Errors) return(FALSE); -return(TRUE); + +if (Errors) return(TRUE); +return(FALSE); } diff --git a/check.sh b/check.sh index b8fd5c1..c058576 100755 --- a/check.sh +++ b/check.sh @@ -71,6 +71,29 @@ else fi } +TestExitCodes() +{ +if [ "$4" = "FindDuplicates" ] +then + HR_OUT=`./hashrat -r -dups $1` + EXIT_FOUND=$? + HR_OUT=`./hashrat -r -dups $2` + EXIT_NOTFOUND=$? +else + HR_OUT=`echo $1 $2 | ./hashrat $3 2>/dev/null` + EXIT_FOUND=$? + HR_OUT=`echo $1x $2 | ./hashrat $3 2>/dev/null` + EXIT_NOTFOUND=$? +fi + +if [ "$EXIT_FOUND" = "0" -a "$EXIT_NOTFOUND" = "1" ] +then + OkayMessage "$4 exit codes correct" +else + FailMessage "$4 exit codes BROKEN." +fi +} + ##################### MAIN STARTS HERE ########################## @@ -114,7 +137,7 @@ TestHash z85 "ZEROMQ85 encoding" "wX%ElWFTQ9+Z=X4h" Title "Testing Misc. Features" HR_OUT=`./hashrat -version` -if [ "$HR_OUT" = "version: 1.8.2" ] +if [ "$HR_OUT" = "version: 1.8.3" ] then OkayMessage "Version (-version) works" else @@ -157,7 +180,7 @@ else FailMessage "Checking files BROKEN" fi -HR_OUT=`./hashrat -r -dups tests` +HR_OUT=`./hashrat -r -dups tests` if [ "$HR_OUT" = "DUPLICATE: tests/quotes.txt of tests/duplicate.txt " ] then OkayMessage "Finding duplicate files works" @@ -176,4 +199,10 @@ HR_INPUT=`cat tests/test.ioc` TestLocate "$HR_INPUT" "LOCATED: 6ec9de513a8ff1768eb4768236198cf3 ' Hashrat Test IOC' at ./tests/help.txt" "Locating files with OpenIOC input" +Title "Testing exit codes for different operations" + +TestExitCodes "6ec9de513a8ff1768eb4768236198cf3" "tests/help.txt" "-cf" "CheckHash" +TestExitCodes "6ec9de513a8ff1768eb4768236198cf3" "tests/help.txt" "-m -r ." "Locate" +TestExitCodes "tests" "libUseful-2.5" "-r -dups" "FindDuplicates" + exit $EXIT diff --git a/command-line-args.c b/command-line-args.c index 81159d0..1b73ead 100644 --- a/command-line-args.c +++ b/command-line-args.c @@ -328,6 +328,12 @@ else if (strcmp(argv[i],"-jh256")==0) ParseFlags |= CommandLineHandleArg(argc, a else if (strcmp(argv[i],"-jh384")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, 0, "HashType", "jh-384",Ctx->Vars); else if (strcmp(argv[i],"-jh512")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, 0, "HashType", "jh-512",Ctx->Vars); else if (strcmp(argv[i],"-jh")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, 0, "HashType", "jh-512",Ctx->Vars); +else if (strcmp(argv[i],"-type")==0) +{ + strcpy(argv[i],""); + i++; + ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, 0, "HashType", argv[i],Ctx->Vars); +} //else if (strcmp(argv[i],"-crc32")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, 0, "HashType", "crc32",Ctx->Vars); else if (strcmp(argv[i],"-8")==0) CommandLineSetCtx(argc, argv, i, Ctx, 0, ENCODE_OCTAL); else if (strcmp(argv[i],"-10")==0) CommandLineSetCtx(argc, argv, i, Ctx, 0, ENCODE_DECIMAL); diff --git a/common.h b/common.h index e6fa8fe..51b47c7 100644 --- a/common.h +++ b/common.h @@ -75,7 +75,9 @@ #define BLOCKSIZE 4096 -#define VERSION "1.8.2" +#define IGNORE -1 + +#define VERSION "1.8.3" typedef struct diff --git a/files.c b/files.c index 16b1dfc..5c6de63 100644 --- a/files.c +++ b/files.c @@ -237,7 +237,7 @@ void HashratFinishHash(char **RetStr, HashratCtx *Ctx, THash *Hash) int val; char *ptr; - Hash->Finish(Hash,Ctx->Encoding,RetStr); + HashFinish(Hash,Ctx->Encoding,RetStr); ptr=GetVar(Ctx->Vars,"Output:Length"); if (StrValid(ptr)) @@ -245,7 +245,6 @@ char *ptr; val=atoi(ptr); if ((val > 0) && (StrLen(*RetStr) > val)) (*RetStr)[val]='\0'; } - HashDestroy(Hash); } @@ -297,11 +296,14 @@ THash *Hash; if (! Ctx->Hash) { Hash=HashInit(Ctx->HashType); + if (Hash) + { ptr=GetVar(Ctx->Vars,"EncryptionKey"); if (ptr) HMACSetKey(Hash, ptr, StrLen(ptr)); Hash->Update(Hash ,Data, DataLen); HashratFinishHash(RetStr, Ctx, Hash); + } } else Ctx->Hash->Update(Ctx->Hash ,Data, DataLen); } @@ -414,24 +416,28 @@ return(0); - -void HashratAction(HashratCtx *Ctx, char *Path, struct stat *Stat) +//HashratAction returns true on a significant event, which is either an item found in search +//or a check failing in hash-checking mode +int HashratAction(HashratCtx *Ctx, char *Path, struct stat *Stat) { char *HashStr=NULL; +int Type, result=FALSE; TFingerprint *FP; -int Type; switch (Ctx->Action) { case ACT_HASHDIR: Type=FileType(Path, Flags, Stat); - HashratHashFile(Ctx, Ctx->Hash, Type, Path, Stat->st_size); + //we return TRUE if hash succeeded + if (HashratHashFile(Ctx, Ctx->Hash, Type, Path, Stat->st_size)) result=TRUE; break; case ACT_HASH: HashItem(Ctx, Ctx->HashType, Path, Stat, &HashStr); HashratOutputInfo(Ctx, Ctx->Out, Path, Stat, HashStr); HashratStoreHash(Ctx, Path, Stat, HashStr); + //we return TRUE if hash succeeded + result=TRUE; break; case ACT_CHECK: @@ -441,11 +447,13 @@ case ACT_CHECK: { HashItem(Ctx, Ctx->HashType, Path, Stat, &HashStr); FP=CheckForMatch(Ctx, Path, Stat, HashStr); - if (FP) + if (FP && HashratCheckFile(Ctx, Path, Stat, HashStr, FP)) MatchCount++; + else { - if (HashratCheckFile(Ctx, Path, Stat, HashStr, FP)) MatchCount++; + HandleCheckFail(Path, "Changed or new"); + //we return TRUE on FAILURE, as we are signaling a significant event + result=TRUE; } - else HandleCheckFail(Path, "Changed or new"); TFingerprintDestroy(FP); } else if (Flags & FLAG_VERBOSE) fprintf(stderr,"ZERO LENGTH FILE: %s\n",Path); @@ -455,20 +463,27 @@ break; case ACT_CHECK_XATTR: if (S_ISREG(Stat->st_mode)) { + //result == TRUE by default (TRUE==Signficant event, here meaning 'check failed') + result=TRUE; FP=XAttrLoadHash(Ctx, Path); if (FP) { HashItem(Ctx, FP->HashType, Path, Stat, &HashStr); - if (FP->Flags & FP_HASSTAT) HashratCheckFile(Ctx, Path, Stat, HashStr, FP); - else HashratCheckFile(Ctx, Path, Stat, HashStr, FP); + if (FP->Flags & FP_HASSTAT) if (HashratCheckFile(Ctx, Path, Stat, HashStr, FP)) result=FALSE; + else if (HashratCheckFile(Ctx, Path, Stat, HashStr, FP)) result=FALSE; } else fprintf(stderr,"ERROR: No stored hash for '%s'\n",Path); } + else fprintf(stderr,"ERROR: Not regular file '%s'. Not checking in xattr mode.\n",Path); break; + case ACT_CHECK_MEMCACHED: if (S_ISREG(Stat->st_mode)) { + //result == TRUE by default (TRUE==Signficant event, here meaning 'check failed') + result=TRUE; + if (Stat->st_size > 0) { HashItem(Ctx, Ctx->HashType, Path, Stat, &HashStr); @@ -477,12 +492,13 @@ case ACT_CHECK_MEMCACHED: else FP->Path=MCopyStr(FP->Path,"hashrat://",LocalHost,Path,NULL); FP->Hash=MemcachedGet(FP->Hash, FP->Path); - if (FP) HashratCheckFile(Ctx, Path, NULL, HashStr, FP); + if (FP && HashratCheckFile(Ctx, Path, NULL, HashStr, FP)) result=FALSE; else fprintf(stderr,"ERROR: No stored hash for '%s'\n",Path); TFingerprintDestroy(FP); } else if (Flags & FLAG_VERBOSE) fprintf(stderr,"ZERO LENGTH FILE: %s\n",Path); } + else fprintf(stderr,"ERROR: Not regular file '%s'. Not checking in memcached mode.\n",Path); break; case ACT_FINDMATCHES: @@ -498,6 +514,8 @@ case ACT_FINDMATCHES_MEMCACHED: if (StrValid(FP->Path) || StrValid(FP->Data)) printf("LOCATED: %s '%s %s' at %s\n",FP->Hash, FP->Path, FP->Data, Path); else printf("LOCATED: %s at %s\n",FP->Hash, Path); MatchCount++; + //here we return true if a match found + result=TRUE; } else DiffCount++; TFingerprintDestroy(FP); @@ -518,6 +536,8 @@ case ACT_FINDDUPLICATES: { printf("DUPLICATE: %s of %s %s\n",Path,FP->Path,FP->Data); MatchCount++; + //here we return true if a match found + result=TRUE; TFingerprintDestroy(FP); } else @@ -534,16 +554,19 @@ break; } DestroyString(HashStr); -} +return(result); +} +//ProcessItem returns TRUE on a significant event, so any instance of TRUE +//from items checked makes return value here TRUE int ProcessDir(HashratCtx *Ctx, char *Dir, char *HashType) { char *Tempstr=NULL, *HashStr=NULL; ListNode *FileList, *Curr; +int result=FALSE; int Type; -int result=TRUE; Type=FileType(Dir, Flags, NULL); @@ -553,7 +576,7 @@ int result=TRUE; Curr=ListGetNext(FileList); while (Curr) { - ProcessItem(Ctx, Curr->Tag, (struct stat *) Curr->Item); + if (ProcessItem(Ctx, Curr->Tag, (struct stat *) Curr->Item)) result=TRUE; Curr=ListGetNext(Curr); } @@ -566,11 +589,13 @@ return(result); } - -int HashratRecurse(HashratCtx *Ctx, char *Path, char **HashStr, int result) +//ProcessDir returns TRUE on a significant event, so any instance of TRUE +//from items checked makes return value here TRUE +int HashratRecurse(HashratCtx *Ctx, char *Path, char **HashStr) { char *ptr; struct stat FStat; +int result=FALSE; if ((Ctx->Action == ACT_HASHDIR) && (! Ctx->Hash)) { @@ -582,8 +607,9 @@ struct stat FStat; HashratFinishHash(HashStr, Ctx, Ctx->Hash); stat(Path, &FStat); HashratOutputInfo(Ctx, Ctx->Out, Path, &FStat, *HashStr); + result=TRUE; } - else if (! ProcessDir(Ctx, Path, Ctx->HashType)) result=FALSE; + else if (ProcessDir(Ctx, Path, Ctx->HashType)) result=TRUE; return(result); } @@ -591,26 +617,30 @@ struct stat FStat; -void ProcessItem(HashratCtx *Ctx, char *Path, struct stat *Stat) +int ProcessItem(HashratCtx *Ctx, char *Path, struct stat *Stat) { char *HashStr=NULL; +int result=FALSE; switch (ConsiderItem(Ctx, Path, Stat)) { case CTX_EXCLUDE: case CTX_ONE_FS: + result=IGNORE; break; case CTX_RECURSE: - HashratRecurse(Ctx, Path, &HashStr, 0); + result=HashratRecurse(Ctx, Path, &HashStr); break; default: - HashratAction(Ctx, Path, Stat); + result=HashratAction(Ctx, Path, Stat); break; } DestroyString(HashStr); + +return(result); } diff --git a/files.h b/files.h index d5dc1c3..3b5b0c7 100644 --- a/files.h +++ b/files.h @@ -21,7 +21,7 @@ int StatFile(HashratCtx *Ctx, char *Path, struct stat *Stat); int HashSingleFile(char **RetStr, HashratCtx *Ctx, int Type,char *Path); void ProcessData(char **RetStr, HashratCtx *Ctx, char *Data, int DataLen); int HashItem(HashratCtx *Ctx, char *HashType, char *Path, struct stat *FStat, char **HashStr); -void ProcessItem(HashratCtx *Ctx, char *Path, struct stat *Stat); +int ProcessItem(HashratCtx *Ctx, char *Path, struct stat *Stat); int ProcessDir(HashratCtx *Ctx, char *Dir, char *HashType); void HashratFinishHash(char **RetStr, HashratCtx *Ctx, THash *Hash); diff --git a/filesigning.c b/filesigning.c index 11ee1e4..cde3ce4 100644 --- a/filesigning.c +++ b/filesigning.c @@ -103,10 +103,9 @@ while (Tempstr) if (strncmp(Tempstr, "hashrat-integrity-mark: ",24)==0) { tmpHash=Hash->Clone(Hash); - tmpHash->Finish(tmpHash,ENCODE_BASE64,&HashStr); + HashFinish(tmpHash,ENCODE_BASE64,&HashStr); HashratOutputSigningCheck(Ctx, HashStr, Tempstr, LineCount); - HashDestroy(tmpHash); } Hash->Update(Hash ,Tempstr, StrLen(Tempstr)); diff --git a/fingerprint.c b/fingerprint.c index e99ec23..64828ae 100644 --- a/fingerprint.c +++ b/fingerprint.c @@ -9,14 +9,19 @@ int result=FALSE; char *ptr; ptr=GetToken(Data,"\\S",Type,0); -while (isspace(*ptr)) ptr++; -if (*ptr=='(') ptr++; -ptr=GetToken(ptr,")",Path,0); -while (isspace(*ptr)) ptr++; -if (*ptr=='=') ptr++; -while (isspace(*ptr)) ptr++; - -*Hash=CopyStr(*Hash,ptr); +if (ptr) +{ + while (isspace(*ptr)) ptr++; + if (*ptr=='(') ptr++; + ptr=GetToken(ptr,")",Path,0); + if (ptr) + { + while (isspace(*ptr)) ptr++; + if (*ptr=='=') ptr++; + while (isspace(*ptr)) ptr++; + } + *Hash=CopyStr(*Hash,ptr); +} } @@ -26,9 +31,12 @@ void ParseTradFormat(const char *Data, char **Hash, char **Path) char *ptr; ptr=GetToken(Data,"\\S",Hash,0); -if (*ptr=='*') ptr++; -while (isspace(*ptr)) ptr++; -*Path=CopyStr(*Path,ptr); +if (ptr) +{ + if (*ptr=='*') ptr++; + while (isspace(*ptr)) ptr++; + *Path=CopyStr(*Path,ptr); +} } diff --git a/hashrat.1 b/hashrat.1 index e4292fb..716be00 100644 --- a/hashrat.1 +++ b/hashrat.1 @@ -33,6 +33,10 @@ Print this help. Print program version. .TP .B +\fB-type \fP +Use \fIhash\fP algorithm . Hash types can be chained as a comma-seperated list. +.TP +.B \fB-md5\fP Use md5 \fIhash\fP algorithm. This is the default \fIhash\fP. .TP @@ -336,6 +340,10 @@ This is compatible with 'echo text | md5sum', where text is one line, as echo ad text it outputs. .TP .B +\fBhashrat\fP \fB-type sha256,whirl,md5\fP \fB-64\fP +Generate a sha-256 \fIhash\fP \fIof\fP data read from stdin, then hash the result with whirlpool, then with md5. +.TP +.B \fBhashrat\fP * Generate a list \fIof\fP \fIhashes\fP for files in the current directory (default \fIhash\fP type is md5). .TP diff --git a/libUseful-2.5/Hash.c b/libUseful-2.5/Hash.c index 1ed05fa..1f5f0ca 100644 --- a/libUseful-2.5/Hash.c +++ b/libUseful-2.5/Hash.c @@ -30,7 +30,7 @@ Hash=(THash *) HMAC->Ctx; //We've done with this now, blank it and reuse for the inner result HMAC->Key1=CopyStr(HMAC->Key1,""); -len=Hash->Finish(Hash,0,&HMAC->Key1); +len=Hash->Finish(Hash,&HMAC->Key1); HMAC->Key2=SetStrLen(HMAC->Key2,HMAC_BLOCKSIZE+len); memcpy(HMAC->Key2+HMAC_BLOCKSIZE,HMAC->Key1,len); @@ -105,8 +105,6 @@ HMAC->Key1Len=Len; - - #include "crc32.h" void HashUpdateCRC(THash *Hash, char *Data, int Len) @@ -128,7 +126,7 @@ return(NewHash); } -int HashFinishCRC(THash *Hash, int Encoding, char **HashStr) +int HashFinishCRC(THash *Hash, char **HashStr) { unsigned long crc; int len; @@ -137,17 +135,9 @@ len=sizeof(unsigned long); crc32Finish((unsigned long *) Hash->Ctx); crc=htonl(* (unsigned long *) Hash->Ctx); -if (Encoding > 0) -{ - *HashStr=EncodeBytes(*HashStr, (char *) &crc, len, Encoding); - return(StrLen(*HashStr)); -} -else -{ - *HashStr=SetStrLen(*HashStr,len); - memcpy(*HashStr,&crc,len); - return(len); -} +*HashStr=SetStrLen(*HashStr,len); +memcpy(*HashStr,&crc,len); +return(len); } @@ -186,28 +176,19 @@ return(NewHash); } -int HashFinishMD5(THash *Hash, int Encoding, char **HashStr) +int HashFinishMD5(THash *Hash, char **HashStr) { int len; -char *Tempstr=NULL, *DigestBuff=NULL; +char *DigestBuff=NULL; DigestBuff=(char *) calloc(1,MD5LEN+1); MD5Final((unsigned char *) DigestBuff, (MD5_CTX *) Hash->Ctx); -if (Encoding > 0) -{ - *HashStr=EncodeBytes(*HashStr, DigestBuff, MD5LEN, Encoding); - len=StrLen(*HashStr); -} -else -{ - len=MD5LEN; - *HashStr=SetStrLen(*HashStr,len); - memcpy(*HashStr,DigestBuff,len); -} +len=MD5LEN; +*HashStr=SetStrLen(*HashStr,len); +memcpy(*HashStr,DigestBuff,len); DestroyString(DigestBuff); -DestroyString(Tempstr); return(len); } @@ -244,28 +225,19 @@ return(NewHash); } -int HashFinishSHA1(THash *Hash, int Encoding, char **HashStr) +int HashFinishSHA1(THash *Hash, char **HashStr) { int len; -char *Tempstr=NULL, *DigestBuff=NULL; +char *DigestBuff=NULL; DigestBuff=(char *) calloc(1,SHA1LEN+1); sha1_finish_ctx((struct sha1_ctx *) Hash->Ctx, DigestBuff); -if (Encoding > 0) -{ - *HashStr=EncodeBytes(*HashStr, DigestBuff, SHA1LEN, Encoding); - len=StrLen(*HashStr); -} -else -{ len=SHA1LEN; *HashStr=SetStrLen(*HashStr,len); memcpy(*HashStr,DigestBuff,len); -} DestroyString(DigestBuff); -DestroyString(Tempstr); return(len); } @@ -274,29 +246,19 @@ return(len); #include "sha2.h" -int HashFinishSHA256(THash *Hash, int Encoding, char **HashStr) +int HashFinishSHA256(THash *Hash, char **HashStr) { int len; -char *Tempstr=NULL; char *DigestBuff=NULL; DigestBuff=(char *) calloc(1,SHA2_SHA256_DIGEST_LENGTH+1); SHA2_SHA256_Final((unsigned char *) DigestBuff, (SHA2_SHA256_CTX *) Hash->Ctx); -if (Encoding > 0) -{ - *HashStr=EncodeBytes(*HashStr, DigestBuff, SHA2_SHA256_DIGEST_LENGTH, Encoding); - len=StrLen(*HashStr); -} -else -{ - len=SHA2_SHA256_DIGEST_LENGTH; - *HashStr=SetStrLen(*HashStr,len); - memcpy(*HashStr,DigestBuff,len); -} +len=SHA2_SHA256_DIGEST_LENGTH; +*HashStr=SetStrLen(*HashStr,len); +memcpy(*HashStr,DigestBuff,len); DestroyString(DigestBuff); -DestroyString(Tempstr); return(len); } @@ -321,28 +283,19 @@ SHA2_SHA256_Update((SHA2_SHA256_CTX *) Hash->Ctx, (unsigned char *) Data, Len); } -int HashFinishSHA512(THash *Hash, int Encoding, char **HashStr) +int HashFinishSHA512(THash *Hash, char **HashStr) { int len; -char *Tempstr=NULL, *DigestBuff=NULL; +char *DigestBuff=NULL; DigestBuff=(char *) calloc(1,SHA2_SHA512_DIGEST_LENGTH+1); SHA2_SHA512_Final((unsigned char *) DigestBuff, (SHA2_SHA512_CTX *) Hash->Ctx); -if (Encoding > 0) -{ - *HashStr=EncodeBytes(*HashStr, DigestBuff, SHA2_SHA512_DIGEST_LENGTH, Encoding); - len=StrLen(*HashStr); -} -else -{ len=SHA2_SHA512_DIGEST_LENGTH; *HashStr=SetStrLen(*HashStr,len); memcpy(*HashStr,DigestBuff,len); -} DestroyString(DigestBuff); -DestroyString(Tempstr); return(len); } @@ -405,28 +358,19 @@ break; #include "whirlpool.h" -int HashFinishWhirlpool(THash *Hash, int Encoding, char **HashStr) +int HashFinishWhirlpool(THash *Hash, char **HashStr) { int len; -char *Tempstr=NULL, *DigestBuff=NULL; +char *DigestBuff=NULL; DigestBuff=(char *) calloc(1,WHIRLPOOL_DIGESTBYTES+1); WHIRLPOOLfinalize((WHIRLPOOLstruct *) Hash->Ctx, (unsigned char *) DigestBuff); -if (Encoding > 0) -{ - *HashStr=EncodeBytes(*HashStr, DigestBuff, WHIRLPOOL_DIGESTBYTES, Encoding); - len=StrLen(*HashStr); -} -else -{ len=WHIRLPOOL_DIGESTBYTES; *HashStr=SetStrLen(*HashStr,len); memcpy(*HashStr,DigestBuff,len); -} DestroyString(DigestBuff); -DestroyString(Tempstr); return(len); } @@ -464,28 +408,18 @@ Hash->Clone=HashCloneWhirlpool; #include "jh_ref.h" -int HashFinishJH(THash *Hash, int Encoding, char **HashStr) +int HashFinishJH(THash *Hash, char **HashStr) { int len; -char *Tempstr=NULL, *DigestBuff=NULL; +char *DigestBuff=NULL; DigestBuff=(char *) calloc(1,1024); len=JHFinal((hashState *) Hash->Ctx, (unsigned char *) DigestBuff); - -if (Encoding > 0) -{ - *HashStr=EncodeBytes(*HashStr, DigestBuff, len, Encoding); - len=StrLen(*HashStr); -} -else -{ - *HashStr=SetStrLen(*HashStr,len); - memcpy(*HashStr,DigestBuff,len); -} +*HashStr=SetStrLen(*HashStr,len); +memcpy(*HashStr,DigestBuff,len); DestroyString(DigestBuff); -DestroyString(Tempstr); return(len); } @@ -562,35 +496,80 @@ for (i=0; HashTypes[i] !=NULL; i++) SetVar(Vars,HashTypes[i], HashTypes[i]); } -THash *HashInit(char *Type) +THash *HashInit(const char *Type) { THash *Hash=NULL; +char *InitialType=NULL; Hash=(THash *) calloc(1,sizeof(THash)); Hash->Type=CopyStr(Hash->Type,Type); -if (strcasecmp(Type,"md5")==0) HashInitMD5(Hash, 0); -else if (strcasecmp(Type,"sha")==0) HashInitSHA(Hash, 0); -else if (strcasecmp(Type,"sha1")==0) HashInitSHA(Hash, 0); -else if (strcasecmp(Type,"sha256")==0) HashInitSHA(Hash, 256); -else if (strcasecmp(Type,"sha512")==0) HashInitSHA(Hash, 512); -else if (strcasecmp(Type,"whirl")==0) HashInitWhirlpool(Hash, 0); -else if (strcasecmp(Type,"whirlpool")==0) HashInitWhirlpool(Hash, 0); -else if (strcasecmp(Type,"jh-224")==0) HashInitJH(Hash,224); -else if (strcasecmp(Type,"jh-256")==0) HashInitJH(Hash,256); -else if (strcasecmp(Type,"jh-384")==0) HashInitJH(Hash,384); -else if (strcasecmp(Type,"jh-512")==0) HashInitJH(Hash,512); -//else if (strcasecmp(Type,"crc32")==0) HashInitCRC(Hash, 0); -else if (strncasecmp(Type,"hmac-",5)==0) HMACInit(Hash); +strrep(Hash->Type,',',' '); + +GetToken(Hash->Type,"\\S",&InitialType,0); +if (strcasecmp(InitialType,"md5")==0) HashInitMD5(Hash, 0); +else if (strcasecmp(InitialType,"sha")==0) HashInitSHA(Hash, 0); +else if (strcasecmp(InitialType,"sha1")==0) HashInitSHA(Hash, 0); +else if (strcasecmp(InitialType,"sha256")==0) HashInitSHA(Hash, 256); +else if (strcasecmp(InitialType,"sha512")==0) HashInitSHA(Hash, 512); +else if (strcasecmp(InitialType,"sha-256")==0) HashInitSHA(Hash, 256); +else if (strcasecmp(InitialType,"sha-512")==0) HashInitSHA(Hash, 512); +else if (strcasecmp(InitialType,"whirl")==0) HashInitWhirlpool(Hash, 0); +else if (strcasecmp(InitialType,"whirlpool")==0) HashInitWhirlpool(Hash, 0); +else if (strcasecmp(InitialType,"jh224")==0) HashInitJH(Hash,224); +else if (strcasecmp(InitialType,"jh256")==0) HashInitJH(Hash,256); +else if (strcasecmp(InitialType,"jh384")==0) HashInitJH(Hash,384); +else if (strcasecmp(InitialType,"jh512")==0) HashInitJH(Hash,512); +else if (strcasecmp(InitialType,"jh-224")==0) HashInitJH(Hash,224); +else if (strcasecmp(InitialType,"jh-256")==0) HashInitJH(Hash,256); +else if (strcasecmp(InitialType,"jh-384")==0) HashInitJH(Hash,384); +else if (strcasecmp(InitialType,"jh-512")==0) HashInitJH(Hash,512); +//else if (strcasecmp(InitialType,"crc32")==0) HashInitCRC(Hash, 0); +else if (strncasecmp(InitialType,"hmac-",5)==0) HMACInit(Hash); else { HashDestroy(Hash); Hash=NULL; } +DestroyString(InitialType); return(Hash); } +int HashFinish(THash *Hash, int Encoding, char **Return) +{ +char *Token=NULL, *Bytes=NULL, *Hashed=NULL, *ptr; +int len; + +ptr=GetToken(Hash->Type, "\\S", &Token, 0); +len=Hash->Finish(Hash, &Bytes); + +while (StrValid(ptr)) +{ + ptr=GetToken(ptr, "\\S", &Token, 0); + len=HashBytes(&Hashed, Token, Bytes, len, 0); + Bytes=SetStrLen(Bytes, len); + memcpy(Bytes,Hashed,len); +} + +if (Encoding > 0) +{ +*Return=EncodeBytes(*Return, Bytes, len, Encoding); +len=StrLen(*Return); +} +else +{ + *Return=SetStrLen(*Return, len); + memcpy(*Return, Bytes, len); +} + +HashDestroy(Hash); +DestroyString(Hashed); +DestroyString(Token); +DestroyString(Bytes); + +return(len); +} int HashBytes(char **Return, char *Type, char *text, int len, int Encoding) @@ -601,8 +580,7 @@ int result; Hash=HashInit(Type); if (! Hash) return(0); Hash->Update(Hash, text, len); -result=Hash->Finish(Hash, Encoding, Return); -HashDestroy(Hash); +result=HashFinish(Hash, Encoding, Return); return(result); } @@ -639,6 +617,7 @@ DestroyString(Hash); StrLen(*Return); } + int HashFile(char **Return, char *Type, char *Path, int Encoding) { THash *Hash; @@ -668,8 +647,7 @@ while (result !=EOF) DestroyString(Tempstr); STREAMClose(S); -result=Hash->Finish(Hash, Encoding, Return); -HashDestroy(Hash); +result=HashFinish(Hash, Encoding, Return); return(result); } diff --git a/libUseful-2.5/Hash.h b/libUseful-2.5/Hash.h index 48a10bd..1f0b79a 100644 --- a/libUseful-2.5/Hash.h +++ b/libUseful-2.5/Hash.h @@ -13,7 +13,7 @@ typedef struct t_hash THash; typedef void (*HASH_UPDATE)(THash *Hash, char *Data, int DataLen); typedef THash *(*HASH_CLONE)(THash *Hash); -typedef int (*HASH_FINISH)(THash *Hash, int Encoding, char **RetStr); +typedef int (*HASH_FINISH)(THash *Hash, char **RetStr); struct t_hash { @@ -29,7 +29,8 @@ HASH_CLONE Clone; }; void HashAvailableTypes(ListNode *Vars); -THash *HashInit(char *Type); +THash *HashInit(const char *Type); +int HashFinish(THash *Hash, int Encoding, char **Return); void HMACSetKey(THash *HMAC, char *Key, int Len); void HashDestroy(THash *Hash); int HashBytes(char **Return, char *Type, char *text, int len, int Encoding); diff --git a/main.c b/main.c index e3ab893..3594eac 100644 --- a/main.c +++ b/main.c @@ -103,7 +103,7 @@ DestroyString(Hash); int ProcessCommandLine(HashratCtx *Ctx, int argc, char *argv[]) { struct stat Stat; -int i, count=0; +int i, result=IGNORE; for (i=1; i < argc; i++) { @@ -111,14 +111,13 @@ int i, count=0; { if (StatFile(Ctx, argv[i],&Stat)==0) { - ProcessItem(Ctx, argv[i], &Stat); + result=ProcessItem(Ctx, argv[i], &Stat); } else fprintf(stderr,"ERROR: File '%s' not found\n",argv[i]); - count++; } } -return(count); +return(result); } @@ -126,7 +125,7 @@ return(count); main(int argc, char *argv[]) { char *Tempstr=NULL, *ptr; -int i, result=FALSE, count=0; +int i, result=FALSE; struct stat Stat; HashratCtx *Ctx; @@ -147,13 +146,13 @@ MemcachedConnect(GetVar(Ctx->Vars, "Memcached:Server")); switch (Ctx->Action) { case ACT_HASH: - count=ProcessCommandLine(Ctx, argc, argv); - //if we didn't find anything on the command-line then read from stdin - if (count==0) HashStdIn(Ctx); + result=ProcessCommandLine(Ctx, argc, argv); + //if we didn't find anything on the command-line then read from stdin + if (result==IGNORE) HashStdIn(Ctx); break; case ACT_HASHDIR: - count=ProcessCommandLine(Ctx, argc, argv); + result=ProcessCommandLine(Ctx, argc, argv); break; case ACT_CHECK_LIST: @@ -166,36 +165,35 @@ switch (Ctx->Action) case ACT_CHECK: case ACT_FINDMATCHES: - if (! MatchesLoad(0)) - { - printf("No hashes supplied on stdin.\n"); - exit(1); - } - ProcessCommandLine(Ctx, argc, argv); - if (Ctx->Action==ACT_CHECK) OutputUnmatched(Ctx); + if (! MatchesLoad(0)) + { + printf("No hashes supplied on stdin.\n"); + exit(1); + } + result=ProcessCommandLine(Ctx, argc, argv); + if (Ctx->Action==ACT_CHECK) OutputUnmatched(Ctx); break; //Load matches to an mcached server case ACT_LOADMATCHES: - ptr=GetVar(Ctx->Vars, "Memcached:Server"); - if (StrEnd(ptr)) printf("ERROR: No memcached server specified. Use the -memcached command-line argument to specify one\n"); - else MatchesLoad(FLAG_MEMCACHED); + ptr=GetVar(Ctx->Vars, "Memcached:Server"); + if (StrEnd(ptr)) printf("ERROR: No memcached server specified. Use the -memcached command-line argument to specify one\n"); + else MatchesLoad(FLAG_MEMCACHED); break; case ACT_FINDMATCHES_MEMCACHED: case ACT_FINDDUPLICATES: - ProcessCommandLine(Ctx, argc, argv); + result=ProcessCommandLine(Ctx, argc, argv); break; case ACT_CHECK_XATTR: - ProcessCommandLine(Ctx, argc, argv); + result=ProcessCommandLine(Ctx, argc, argv); break; case ACT_CHECK_MEMCACHED: - ProcessCommandLine(Ctx, argc, argv); + result=ProcessCommandLine(Ctx, argc, argv); break; - case ACT_CGI: CGIDisplayPage(); break; @@ -205,47 +203,64 @@ switch (Ctx->Action) break; case ACT_SIGN: - Ctx->Encoding = ENCODE_BASE64; - for (i=1; i < argc; i++) - { - if (StrValid(argv[i])) - { - if (StatFile(Ctx, argv[i],&Stat)==0) - { - if (S_ISLNK(Stat.st_mode)) fprintf(stderr,"WARN: Not following symbolic link %s\n",argv[i]); - else HashratSignFile(argv[i],Ctx); - } - else fprintf(stderr,"ERROR: File '%s' not found\n",argv[i]); - count++; - } - } + Ctx->Encoding = ENCODE_BASE64; + for (i=1; i < argc; i++) + { + if (StrValid(argv[i])) + { + if (StatFile(Ctx, argv[i],&Stat)==0) + { + if (S_ISLNK(Stat.st_mode)) fprintf(stderr,"WARN: Not following symbolic link %s\n",argv[i]); + else HashratSignFile(argv[i],Ctx); + } + else fprintf(stderr,"ERROR: File '%s' not found\n",argv[i]); + } + } break; case ACT_CHECKSIGN: - Ctx->Encoding |= ENCODE_BASE64; - for (i=1; i < argc; i++) - { - if (StrValid(argv[i])) - { - if (StatFile(Ctx, argv[i],&Stat)==0) - { - if (S_ISLNK(Stat.st_mode)) fprintf(stderr,"WARN: Not following symbolic link %s\n",argv[i]); - else HashratCheckSignedFile(argv[i], Ctx); - } - else fprintf(stderr,"ERROR: File '%s' not found\n",argv[i]); - count++; - } - } + Ctx->Encoding |= ENCODE_BASE64; + for (i=1; i < argc; i++) + { + if (StrValid(argv[i])) + { + if (StatFile(Ctx, argv[i],&Stat)==0) + { + if (S_ISLNK(Stat.st_mode)) fprintf(stderr,"WARN: Not following symbolic link %s\n",argv[i]); + else HashratCheckSignedFile(argv[i], Ctx); + } + else fprintf(stderr,"ERROR: File '%s' not found\n",argv[i]); + } + } break; } fflush(NULL); if (Ctx->Out) STREAMClose(Ctx->Out); if (Ctx->Aux) STREAMClose(Ctx->Aux); + +switch (Ctx->Action) +{ + case ACT_FINDMATCHES: + case ACT_FINDMATCHES_MEMCACHED: + case ACT_FINDDUPLICATES: + //result==TRUE for these means 'yes we found something' + if (result==TRUE) exit(0); + else exit(1); + break; + + case ACT_CHECK: + case ACT_CHECK_LIST: + case ACT_CHECK_MEMCACHED: + case ACT_CHECK_XATTR: + //result==TRUE for these means 'CHECK FAILED' + if (result==TRUE) exit(1); + else exit(0); + break; +} } DestroyString(Tempstr); -if (result) exit(0); exit(1); }