OSDN Git Service

2ちゃんねるのトリップ仕様の拡張に対応
authorh677 <h677>
Sat, 20 Jun 2009 15:37:28 +0000 (15:37 +0000)
committerh677 <h677>
Sat, 20 Jun 2009 15:37:28 +0000 (15:37 +0000)
SHA1Unit.pas [new file with mode: 0644]
Trip.pas
gikoNavi.dpr

diff --git a/SHA1Unit.pas b/SHA1Unit.pas
new file mode 100644 (file)
index 0000000..e485efa
--- /dev/null
@@ -0,0 +1,194 @@
+unit SHA1Unit;
+
+interface
+
+uses
+       Windows, SysUtils;
+
+const
+    SHA1_A = DWORD( $67452301 );
+    SHA1_B = DWORD( $EFCDAB89 );
+    SHA1_C = DWORD( $98BADCFE );
+    SHA1_D = DWORD( $10325476 );
+    SHA1_E = DWORD( $C3D2E1F0 );
+    SHA1_K1 = DWORD( $5A827999 );
+    SHA1_K2 = DWORD( $6ED9EBA1 );
+    SHA1_K3 = DWORD( $8F1BBCDC );
+    SHA1_K4 = DWORD( $CA62C1D6 );
+    LBMASK_HI = DWORD( $FF0000 );
+    LBMASK_LO = DWORD( $FF00 );
+
+type
+    TSHA1Digest = array [0..19] of Byte;
+    TSHA1Context = record
+        sdHi    : DWord;
+        sdLo    : DWord;
+        sdIndex : DWord;
+        sdHash  : array [0..4] of DWord;
+        sdBuf   : array [0..63] of Byte;
+    end;
+
+    function SHA1SwapByteOrder( n : DWORD ) : DWORD;
+    procedure HashSHA1( var Digest : TSHA1Digest; const Buf; BufSize : Longint );
+    procedure StringHashSHA1(var Digest : TSHA1Digest; const Str : string);
+    procedure SHA1Hash( var Context : TSHA1Context );
+
+implementation
+//! \95\8e\9a\97ñ\97pSHA1\83n\83b\83V\83\85\8eæ\93¾
+procedure StringHashSHA1(var Digest : TSHA1Digest; const Str : string);
+begin
+    HashSHA1(Digest, Str[1], Length(Str));
+end;
+//! SHA1\83n\83b\83V\83\85\8eæ\93¾
+procedure HashSHA1( var Digest : TSHA1Digest; const Buf; BufSize : Longint );
+var
+    Context : TSHA1Context;
+    PBuf: ^Byte;
+    procedure UpdateLen( var Context : TSHA1Context; Len : DWord );
+    begin
+        Inc( Context.sdLo,( Len shl 3 ));
+        if Context.sdLo < ( Len shl 3 ) then
+            Inc( Context.sdHi );
+        Inc( Context.sdHi, Len shr 29 );
+    end;
+begin
+    //0\96\84\82ß
+    fillchar( Context, SizeOf( Context ), 0 );
+    // \83}\83W\83b\83N\83i\83\93\83o\81[\82Å\8f\89\8aú\89»\82·\82é
+    Context.sdHash[ 0 ] := SHA1_A;
+    Context.sdHash[ 1 ] := SHA1_B;
+    Context.sdHash[ 2 ] := SHA1_C;
+    Context.sdHash[ 3 ] := SHA1_D;
+    Context.sdHash[ 4 ] := SHA1_E;
+
+    UpdateLen( Context, BufSize );
+    PBuf := @Buf;
+    while BufSize > 0 do begin
+        if ( Sizeof( Context.sdBuf ) - Context.sdIndex ) <= DWord( BufSize ) then begin
+            Move( PBuf^, Context.sdBuf[ Context.sdIndex ], Sizeof( Context.sdBuf ) - Context.sdIndex );
+            Dec( BufSize, Sizeof( Context.sdBuf ) - Context.sdIndex );
+            Inc( PBuf, Sizeof( Context.sdBuf ) - Context.sdIndex );
+            SHA1Hash( Context );
+        end else begin
+            Move( PBuf^, Context.sdBuf[ Context.sdIndex ], BufSize );
+            Inc( Context.sdIndex, BufSize );
+            BufSize := 0;
+        end;
+    end;
+
+    Context.sdBuf[ Context.sdIndex ] := $80;
+
+    if Context.sdIndex >= 56 then
+        SHA1Hash( Context );
+
+    PDWord( @Context.sdBuf[ 56 ])^ := SHA1SwapByteOrder( Context.sdHi );
+    PDWord( @Context.sdBuf[ 60 ])^ := SHA1SwapByteOrder( Context.sdLo );
+
+    SHA1Hash( Context );
+
+    Context.sdHash[ 0 ] := SHA1SwapByteOrder( Context.sdHash[ 0 ]);
+    Context.sdHash[ 1 ] := SHA1SwapByteOrder( Context.sdHash[ 1 ]);
+    Context.sdHash[ 2 ] := SHA1SwapByteOrder( Context.sdHash[ 2 ]);
+    Context.sdHash[ 3 ] := SHA1SwapByteOrder( Context.sdHash[ 3 ]);
+    Context.sdHash[ 4 ] := SHA1SwapByteOrder( Context.sdHash[ 4 ]);
+
+    Move( Context.sdHash, Digest, Sizeof( Digest ));
+end;
+//! \83n\83b\83V\83\85\8f\88\97\9d
+procedure SHA1Hash( var Context : TSHA1Context );
+var
+    A : DWord;
+    B : DWord;
+    C : DWord;
+    D : DWord;
+    E : DWord;
+
+    temp : DWord;
+    W : array[ 0..79 ] of DWord;
+
+    i : Longint;
+    function SHA1CircularShift(I, C : DWord) : DWord; register;
+    asm
+        mov  ecx, edx
+        rol  eax, cl
+    end;
+begin
+    with Context do begin
+        sdIndex:= 0;
+        Move( sdBuf, W, Sizeof( W ));
+
+        // Initialize the first 16 words in the array W
+        for i := 0 to 15 do begin
+            W[ i ]:= SHA1SwapByteOrder( W[ i ] );
+        end;
+
+        // Transform Message block from 16 32 bit words to 80 32 bit words
+        // Wt, = ( Wt-3 xor Wt-8 xor Wt-13 xor Wt-16 ) rolL 1 : Wt is W sub t
+        for i:= 16 to 79 do begin
+            W[i]:= SHA1CircularShift( W[ i - 3 ] xor W[ i - 8 ] xor W[ i - 14 ] xor W[ i - 16 ], 1 );
+        end;
+
+        A := sdHash[ 0 ];
+        B := sdHash[ 1 ];
+        C := sdHash[ 2 ];
+        D := sdHash[ 3 ];
+        E := sdHash[ 4 ];
+
+        // the four rounds
+        for i:= 0 to 19 do begin
+            temp    := SHA1CircularShift( A, 5 ) + ( D xor ( B and ( C xor D ))) + E + W[ i ] + SHA1_K1;
+            E       := D;
+            D       := C;
+            C       := SHA1CircularShift( B, 30 );
+            B       := A;
+            A       := temp;
+        end;
+
+        for i:= 20 to 39 do begin
+            temp    := SHA1CircularShift( A, 5 ) + ( B xor C xor D ) + E + W[ i ] + SHA1_K2;
+            E       := D;
+            D       := C;
+            C       := SHA1CircularShift( B, 30 );
+            B       := A;
+            A       := temp;
+        end;
+
+        for i:= 40 to 59 do begin
+            temp    := SHA1CircularShift( A, 5 ) + (( B and C ) or ( D and ( B or C ))) + E + W[ i ] + SHA1_K3;
+            E       := D;
+            D       := C;
+            C       := SHA1CircularShift( B, 30 );
+            B       := A;
+            A       := temp;
+        end;
+
+        for i:= 60 to 79 do
+        begin
+            temp    := SHA1CircularShift( A, 5 ) + ( B xor C xor D ) + E + W[ i ] + SHA1_K4;
+            E       := D;
+            D       := C;
+            C       := SHA1CircularShift( B, 30 );
+            B       := A;
+            A       := temp;
+        end;
+
+        sdHash[ 0 ]:= sdHash[ 0 ] + A;
+        sdHash[ 1 ]:= sdHash[ 1 ] + B;
+        sdHash[ 2 ]:= sdHash[ 2 ] + C;
+        sdHash[ 3 ]:= sdHash[ 3 ] + D;
+        sdHash[ 4 ]:= sdHash[ 4 ] + E;
+
+        FillChar( W, Sizeof( W ), 0 );
+        FillChar( sdBuf, Sizeof( sdBuf ), 0 );
+    end;
+end;
+
+//! \8fã\88Ê\83o\83C\83g\82Æ\89º\88Ê\83o\83C\83g\82Ì\93ü\82ê\91Ö\82¦
+function SHA1SwapByteOrder( n : DWORD ) : DWORD;
+begin
+    n := ( n shr 24 ) or (( n shr 8 ) and LBMASK_LO )
+       or (( n shl 8 ) and LBMASK_HI ) or ( n shl 24 );
+    Result := n;
+end;
+
+end.
index 8ed2577..1c2a78a 100644 (file)
--- a/Trip.pas
+++ b/Trip.pas
@@ -9,6 +9,9 @@ unit Trip;
 }
 interface
 
+uses
+    SHA1Unit, UBase64, SysUtils;
+
 type
        CryptBlock = record
                b_data : array [0..63] of char;
@@ -417,25 +420,93 @@ begin
 
 end;
 
+procedure get_pw_salt(
+    const pw : PChar;
+    var convpw : String;
+    const salt : PChar
+);
+var
+    i : integer;
+begin
+    // ^([0-9A-Fa-f]{16})([./0-9A-Za-z]{0,2})$
+    if (Length(pw) >= 17) or (Length(pw) <= 19) then begin
+        // \83L\81[\95\94\95ª
+        for  i := 0 to 7 do begin
+            if (Pos(pw[2*i + 0 + 1], '0123456789abcdefABCDEF') > 0) and
+                (Pos(pw[2*i + 1 + 1], '0123456789abcdefABCDEF') > 0) then begin
+                convpw := convpw +
+                    Char(StrToInt( pw[2*i + 0 + 1] ) shl 4 + StrToInt( pw[2*i + 1 + 1] ));
+            end else begin
+                convpw := '';
+                Break;
+            end;
+        end;
+
+        if (Length(convpw) = 8) then begin
+            if (Length(pw) = 19) then begin
+                if (Pos(pw[17], './0123456789abcdefABCDEF') > 0) and
+                    (Pos(pw[18], './0123456789abcdefABCDEF') > 0) then begin
+                    salt[ 0 ] := pw[17];
+                    salt[ 1 ] := pw[18];
+                    salt[ 2 ] := #0;
+                end else begin
+                    convpw := '';
+                end;
+            end else if (Length(pw) = 18) then begin
+                if (Pos(pw[17], './0123456789abcdefABCDEF') > 0) then begin
+                    salt[ 0 ] := pw[17];
+                    salt[ 1 ] := '.';
+                    salt[ 2 ] := #0;
+                end else begin
+                    convpw := '';
+                end;
+            end else begin
+                salt[ 0 ] := '.';
+                salt[ 1 ] := '.';
+                salt[ 2 ] := #0;
+            end;
+        end;
+    end;
+end;
+
 function get_2ch_trip(
        const pw : PChar
 ) : string;
 var
        s : CryptData;
        salt : array [0..2] of char;
+    digest : TSHA1Digest;
+    convpw : String;
 begin
-
+    Result := '';
        if pw[ 0 ] = #0 then
        begin
-               Result := '';
                Exit;
        end;
-
-    get_salt( pw, salt );
-
-
-       Result := Copy( crypt_r( pw, salt, s ), 4, 100 );
-
+    // 11\8c\85\82Ü\82Å\82Í\8b\8c\95û\8e®
+    if (Length(pw) <= 11) then begin
+        get_salt( pw, salt );
+       Result := Copy( crypt_r( pw, salt, s ), 4, 100 );
+    end else begin
+        // \90V\95û\8e®\83g\83\8a\83b\83v
+        if pw[ 0 ] = '$' then begin
+            // \8f«\97\88\82Ì\8ag\92£\97p
+            Result := '???';
+        end else begin
+            convpw := '';
+            // \90\83L\81[\95û\8e®
+            if pw[ 0 ] = '#' then begin
+                get_pw_salt(pw, convpw, salt);
+            end;
+            if Length(convpw) = 8 then begin
+                Result := Copy( crypt_r( PChar(convpw), salt, s ), 4, 100 );
+            end else begin
+                // \90V\95û\8e®
+                StringHashSHA1(digest, pw);
+                Result := Copy(HogeBase64Encode(digest), 0, 12);
+            end;
+        end;
+    end;
 end;
 
 procedure get_salt(
index 762f495..be2121b 100644 (file)
@@ -52,7 +52,6 @@ uses
   ExternalBoardPlugInMain in 'ExternalBoardPlugInMain.pas',
   ExternalFilePath in 'ExternalFilePath.pas',
   MojuUtils in 'MojuUtils.pas',
-  {crc in 'gzip_delphi2\crc.pas', //zlib\8dX\90V\82É\94º\82¢\8dí\8f\9c}
   gzip in 'gzip_delphi2\gzip.pas',
   zlib in 'gzip_delphi2\zlib.pas',
   bmRegExp in 'bmRegExp\bmregexp.pas',
@@ -81,7 +80,8 @@ uses
   SkinFiles in 'SkinFiles.pas',
   NewBoardURL in 'NewBoardURL.pas' {NewBoardURLForm},
   ExtPreviewDatamodule in 'ExtPreviewDatamodule.pas' {ExtPreviewDM: TDataModule},
-  UpdateCheck in 'UpdateCheck.pas' {UpdateCheckForm};
+  UpdateCheck in 'UpdateCheck.pas' {UpdateCheckForm},
+  SHA1Unit in 'SHA1Unit.pas';
 
 {$R *.RES}
 {$R gikoResource.res}