Avatar billede kennethv Nybegynder
17. september 2008 - 23:37 Der er 20 kommentarer og
1 løsning

Papirnusseri til automatisk arbejdsgang.

Måske er det offtopic, men her er det.
Jeg har en lille administrativ opgave til daglig, som jeg gerne vil have lavet om til noget der kører pr. automatik. Jeg havde forstillet mig en at lave en service, som tjekker en SQL db 4 gange i timen, for om der er sket nogle ændringer. Er der det, sender min service en email til chefen med et link. Det har jeg sådan rimlig styr på. Det jeg dog ikke helt har styr på er, selve linket, linket skal være invidiuelt fra record til record og der skal være en sikkerhed i det, forstået på den måde at man ikke kunne tænke sig til at ændre webadressen når den står i internet exploreren og så fat i en anden record. En anden ting, som jeg heller ikke helt har styr på er, webinterfacet, som linket videre sender til, som kunne være min chef. Indholdet er dog info fra min SQL db sammen med noget standard tekst. Jeg vil gerne have at chefen udfylder noget ekstra information via webinterfacet udfra en form. Det meste at forms indhold er bygget op af standard tekst, men noget af det ændre sig iforhold til hvad der står i SQL db'en. Hvor meget af det, som jeg har skrevet her kan klares via Delphi og hvis delphi kan bruges, hvad skal jeg bruge af forskellige komponenter for at komme igang? Og gerne lidt kode, for at komme sådan lidt hurtigt igang. :)
Avatar billede hrc Mester
18. september 2008 - 09:45 #1
Hvis der skal være sikkerhed kan du sende ham et link hvori der indgår en MD5-nøgle (dvs. den rigtige nøgle konverteret til 32 '0'..'F' tegn). MD5-nøglen er en sekundær nøgle til beskedden og gemmes altså sideløbende. Man kan stadig angive en anden

Lad være med at køre primærnøglen gennem en MD5-generator. Skal man kigge i databasen kan man bare lave et lille program der løber mulige nøgler igennem indtil man støder på en MD5 der er ens med den du har lavet. Derefter kan man sagtens kigge i andre records. Brug en timestamp eller lignende (eller støj fra rummet ligesom NSA)

.. hvad angår resten af din mail: Jeg forstår det ikke.

Paster her den unit jeg bruger.

// -----------------------------------------------------------------------------------------------
//
//                                MD5 Message-Digest for Delphi 4
//
//                                Delphi 4 Unit implementing the
//                      RSA Data Security, Inc. MD5 Message-Digest Algorithm
//
//                          Implementation of Ronald L. Rivest's RFC 1321
//
//                      Copyright © 1997-1999 Medienagentur Fichtner & Meyer
//                                  Written by Matthias Fichtner
//
// -----------------------------------------------------------------------------------------------
//              See RFC 1321 for RSA Data Security's copyright and license notice!
// -----------------------------------------------------------------------------------------------
//
//    14-Jun-97  mf  Implemented MD5 according to RFC 1321                          RFC 1321
//    16-Jun-97  mf  Initial release of the compiled unit (no source code)          RFC 1321
//    28-Feb-99  mf  Added MD5Match function for comparing two digests              RFC 1321
//    13-Sep-99  mf  Reworked the entire unit                                        RFC 1321
//    17-Sep-99  mf  Reworked the "Test Driver" project                              RFC 1321
//    19-Sep-99  mf  Release of sources for MD5 unit and "Test Driver" project      RFC 1321
//    16-Feb-07  hrc Added support for streaming
//
// -----------------------------------------------------------------------------------------------
//                  The latest release of md5.pas will always be available from
//                  the distribution site at: http://www.fichtner.net/delphi/md5/
// -----------------------------------------------------------------------------------------------
//                      Please send questions, bug reports and suggestions
//                      regarding this code to: mfichtner@fichtner-meyer.com
// -----------------------------------------------------------------------------------------------
//                        This code is provided "as is" without express or
//                    implied warranty of any kind. Use it at your own risk.
// -----------------------------------------------------------------------------------------------

unit UMD5;

// -----------------------------------------------------------------------------------------------
interface
// -----------------------------------------------------------------------------------------------

uses
    Windows, Classes;

type
    MD5Count = array[0..1] of DWORD;
    MD5State = array[0..3] of DWORD;
    MD5Block = array[0..15] of DWORD;
    MD5CBits = array[0..7] of byte;
    MD5Digest = array[0..15] of byte;
    MD5Buffer = array[0..63] of byte;
    MD5Context = record
        State: MD5State;
        Count: MD5Count;
        Buffer: MD5Buffer;
    end;

procedure MD5Init(var Context: MD5Context);
procedure MD5Update(var Context: MD5Context; Input: pChar; Length: longword);
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);

function MD5String(const aString: string): MD5Digest;
function MD5File(const aFilename: string): MD5Digest;
function MD5Stream(const aMemoryStream : TMemoryStream) : MD5Digest;
function MD5Print(const aDigest: MD5Digest): string;

function MD5Match(const aDigest1, aDigest2: MD5Digest): boolean;

// -----------------------------------------------------------------------------------------------
implementation
// -----------------------------------------------------------------------------------------------

var
    PADDING: MD5Buffer = (
        $80, $00, $00, $00, $00, $00, $00, $00,
        $00, $00, $00, $00, $00, $00, $00, $00,
        $00, $00, $00, $00, $00, $00, $00, $00,
        $00, $00, $00, $00, $00, $00, $00, $00,
        $00, $00, $00, $00, $00, $00, $00, $00,
        $00, $00, $00, $00, $00, $00, $00, $00,
        $00, $00, $00, $00, $00, $00, $00, $00,
        $00, $00, $00, $00, $00, $00, $00, $00
    );

function F(x, y, z: DWORD): DWORD;
begin
    Result := (x and y) or ((not x) and z);
end;

function G(x, y, z: DWORD): DWORD;
begin
    Result := (x and z) or (y and (not z));
end;

function H(x, y, z: DWORD): DWORD;
begin
    Result := x xor y xor z;
end;

function I(x, y, z: DWORD): DWORD;
begin
    Result := y xor (x or (not z));
end;

procedure rot(var x: DWORD; n: BYTE);
begin
    x := (x shl n) or (x shr (32 - n));
end;

procedure FF(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
    inc(a, F(b, c, d) + x + ac);
    rot(a, s);
    inc(a, b);
end;

procedure GG(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
    inc(a, G(b, c, d) + x + ac);
    rot(a, s);
    inc(a, b);
end;

procedure HH(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
    inc(a, H(b, c, d) + x + ac);
    rot(a, s);
    inc(a, b);
end;

procedure II(var a: DWORD; b, c, d, x: DWORD; s: BYTE; ac: DWORD);
begin
    inc(a, I(b, c, d) + x + ac);
    rot(a, s);
    inc(a, b);
end;

// -----------------------------------------------------------------------------------------------

// Encode Count bytes at Source into (Count / 4) DWORDs at Target
procedure Encode(Source, Target: pointer; Count: longword);
var
    S: PByte;
    T: PDWORD;
    I: longword;
begin
    S := Source;
    T := Target;
    for I := 1 to Count div 4 do begin
        T^ := S^;
        inc(S);
        T^ := T^ or (S^ shl 8);
        inc(S);
        T^ := T^ or (S^ shl 16);
        inc(S);
        T^ := T^ or (S^ shl 24);
        inc(S);
        inc(T);
    end;
end;

// Decode Count DWORDs at Source into (Count * 4) Bytes at Target
procedure Decode(Source, Target: pointer; Count: longword);
var
    S: PDWORD;
    T: PByte;
    I: longword;
begin
    S := Source;
    T := Target;
    for I := 1 to Count do begin
        T^ := S^ and $ff;
        inc(T);
        T^ := (S^ shr 8) and $ff;
        inc(T);
        T^ := (S^ shr 16) and $ff;
        inc(T);
        T^ := (S^ shr 24) and $ff;
        inc(T);
        inc(S);
    end;
end;

// Transform State according to first 64 bytes at Buffer
procedure Transform(Buffer: pointer; var State: MD5State);
var
    a, b, c, d: DWORD;
    Block: MD5Block;
begin
    Encode(Buffer, @Block, 64);
    a := State[0];
    b := State[1];
    c := State[2];
    d := State[3];
    FF (a, b, c, d, Block[ 0],  7, $d76aa478);
    FF (d, a, b, c, Block[ 1], 12, $e8c7b756);
    FF (c, d, a, b, Block[ 2], 17, $242070db);
    FF (b, c, d, a, Block[ 3], 22, $c1bdceee);
    FF (a, b, c, d, Block[ 4],  7, $f57c0faf);
    FF (d, a, b, c, Block[ 5], 12, $4787c62a);
    FF (c, d, a, b, Block[ 6], 17, $a8304613);
    FF (b, c, d, a, Block[ 7], 22, $fd469501);
    FF (a, b, c, d, Block[ 8],  7, $698098d8);
    FF (d, a, b, c, Block[ 9], 12, $8b44f7af);
    FF (c, d, a, b, Block[10], 17, $ffff5bb1);
    FF (b, c, d, a, Block[11], 22, $895cd7be);
    FF (a, b, c, d, Block[12],  7, $6b901122);
    FF (d, a, b, c, Block[13], 12, $fd987193);
    FF (c, d, a, b, Block[14], 17, $a679438e);
    FF (b, c, d, a, Block[15], 22, $49b40821);
    GG (a, b, c, d, Block[ 1],  5, $f61e2562);
    GG (d, a, b, c, Block[ 6],  9, $c040b340);
    GG (c, d, a, b, Block[11], 14, $265e5a51);
    GG (b, c, d, a, Block[ 0], 20, $e9b6c7aa);
    GG (a, b, c, d, Block[ 5],  5, $d62f105d);
    GG (d, a, b, c, Block[10],  9,  $2441453);
    GG (c, d, a, b, Block[15], 14, $d8a1e681);
    GG (b, c, d, a, Block[ 4], 20, $e7d3fbc8);
    GG (a, b, c, d, Block[ 9],  5, $21e1cde6);
    GG (d, a, b, c, Block[14],  9, $c33707d6);
    GG (c, d, a, b, Block[ 3], 14, $f4d50d87);
    GG (b, c, d, a, Block[ 8], 20, $455a14ed);
    GG (a, b, c, d, Block[13],  5, $a9e3e905);
    GG (d, a, b, c, Block[ 2],  9, $fcefa3f8);
    GG (c, d, a, b, Block[ 7], 14, $676f02d9);
    GG (b, c, d, a, Block[12], 20, $8d2a4c8a);
    HH (a, b, c, d, Block[ 5],  4, $fffa3942);
    HH (d, a, b, c, Block[ 8], 11, $8771f681);
    HH (c, d, a, b, Block[11], 16, $6d9d6122);
    HH (b, c, d, a, Block[14], 23, $fde5380c);
    HH (a, b, c, d, Block[ 1],  4, $a4beea44);
    HH (d, a, b, c, Block[ 4], 11, $4bdecfa9);
    HH (c, d, a, b, Block[ 7], 16, $f6bb4b60);
    HH (b, c, d, a, Block[10], 23, $bebfbc70);
    HH (a, b, c, d, Block[13],  4, $289b7ec6);
    HH (d, a, b, c, Block[ 0], 11, $eaa127fa);
    HH (c, d, a, b, Block[ 3], 16, $d4ef3085);
    HH (b, c, d, a, Block[ 6], 23,  $4881d05);
    HH (a, b, c, d, Block[ 9],  4, $d9d4d039);
    HH (d, a, b, c, Block[12], 11, $e6db99e5);
    HH (c, d, a, b, Block[15], 16, $1fa27cf8);
    HH (b, c, d, a, Block[ 2], 23, $c4ac5665);
    II (a, b, c, d, Block[ 0],  6, $f4292244);
    II (d, a, b, c, Block[ 7], 10, $432aff97);
    II (c, d, a, b, Block[14], 15, $ab9423a7);
    II (b, c, d, a, Block[ 5], 21, $fc93a039);
    II (a, b, c, d, Block[12],  6, $655b59c3);
    II (d, a, b, c, Block[ 3], 10, $8f0ccc92);
    II (c, d, a, b, Block[10], 15, $ffeff47d);
    II (b, c, d, a, Block[ 1], 21, $85845dd1);
    II (a, b, c, d, Block[ 8],  6, $6fa87e4f);
    II (d, a, b, c, Block[15], 10, $fe2ce6e0);
    II (c, d, a, b, Block[ 6], 15, $a3014314);
    II (b, c, d, a, Block[13], 21, $4e0811a1);
    II (a, b, c, d, Block[ 4],  6, $f7537e82);
    II (d, a, b, c, Block[11], 10, $bd3af235);
    II (c, d, a, b, Block[ 2], 15, $2ad7d2bb);
    II (b, c, d, a, Block[ 9], 21, $eb86d391);
    inc(State[0], a);
    inc(State[1], b);
    inc(State[2], c);
    inc(State[3], d);
end;

// -----------------------------------------------------------------------------------------------

// Initialize given Context
procedure MD5Init(var Context: MD5Context);
begin
    with Context do begin
        State[0] := $67452301;
        State[1] := $efcdab89;
        State[2] := $98badcfe;
        State[3] := $10325476;
        Count[0] := 0;
        Count[1] := 0;
        ZeroMemory(@Buffer, SizeOf(MD5Buffer));
    end;
end;

// Update given Context to include Length bytes of Input
procedure MD5Update(var Context: MD5Context; Input: pChar; Length: longword);
var
    Index: longword;
    PartLen: longword;
    I: longword;
begin
    with Context do begin
        Index := (Count[0] shr 3) and $3f;
        inc(Count[0], Length shl 3);
        if Count[0] < (Length shl 3) then inc(Count[1]);
        inc(Count[1], Length shr 29);
    end;
    PartLen := 64 - Index;
    if Length >= PartLen then begin
        CopyMemory(@Context.Buffer[Index], Input, PartLen);
        Transform(@Context.Buffer, Context.State);
        I := PartLen;
        while I + 63 < Length do begin
            Transform(@Input[I], Context.State);
            inc(I, 64);
        end;
        Index := 0;
    end else I := 0;
    CopyMemory(@Context.Buffer[Index], @Input[I], Length - I);
end;

// Finalize given Context, create Digest and zeroize Context
procedure MD5Final(var Context: MD5Context; var Digest: MD5Digest);
var
    Bits: MD5CBits;
    Index: longword;
    PadLen: longword;
begin
    Decode(@Context.Count, @Bits, 2);
    Index := (Context.Count[0] shr 3) and $3f;
    if Index < 56 then PadLen := 56 - Index else PadLen := 120 - Index;
    MD5Update(Context, @PADDING, PadLen);
    MD5Update(Context, @Bits, 8);
    Decode(@Context.State, @Digest, 4);
    ZeroMemory(@Context, SizeOf(MD5Context));
end;

// -----------------------------------------------------------------------------------------------

// Create digest of given Message
function MD5String(const aString: string): MD5Digest;
var
    Context: MD5Context;
begin
    MD5Init(Context);
    MD5Update(Context, pChar(aString), length(aString));
    MD5Final(Context, Result);
end;

// Create digest of file with given Name
function MD5File(const aFilename: string): MD5Digest;
var
    FileHandle: THandle;
    MapHandle: THandle;
    ViewPointer: pointer;
    Context: MD5Context;
begin
    MD5Init(Context);
    FileHandle := CreateFile(pChar(aFilename),
                          GENERIC_READ,
                          FILE_SHARE_READ or FILE_SHARE_WRITE,
                              nil,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN,
                          0);

    if FileHandle <> INVALID_HANDLE_VALUE then
    try
          MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
          if MapHandle <> 0 then
        try
                ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
                if assigned(ViewPointer) then
            try
                      MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil));
                  finally
                      UnmapViewOfFile(ViewPointer);
            end;
        finally
                CloseHandle(MapHandle);
        end;
    finally
          CloseHandle(FileHandle);
    end;

    MD5Final(Context, Result);
end;

function MD5Stream(const aMemoryStream : TMemoryStream) : MD5Digest;
var
    Context: MD5Context;
begin
    MD5Init(Context);
  MD5Update(Context, aMemoryStream.Memory, aMemoryStream.Size);
    MD5Final(Context, Result);
end;

// Create hex representation of given Digest
function MD5Print(const aDigest: MD5Digest): string;
var
    I: byte;
const
    Digits: array[0..15] of char =
        ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
begin
    Result := '';
    for I := 0 to 15 do
    Result := Result + Digits[(aDigest[I] shr 4) and $0f] + Digits[aDigest[I] and $0f];
end;

// -----------------------------------------------------------------------------------------------

// Compare two Digests
function MD5Match(const aDigest1, aDigest2: MD5Digest): boolean;
var
    I: byte;
begin
    I := 0;
    Result := TRUE;
    while Result and (I < 16) do
  begin
        Result := aDigest1[I] = aDigest2[I];
        inc(I);
    end;
end;

end.
Avatar billede arne_v Ekspert
18. september 2008 - 16:34 #2
Hvis data skal tilgaaes gennem browser, saa skal der jo vaere et web interface.

ASP.NET med Delphi.NET som sprog og et CGI-script lavet i Delphi er en mulighed for at
lave det med Delphi.

Men ingen af dem er dog specielt mainstream. ASP/VBS, PHP og ASP.NET/C# er langt mere
gaengse.

MD5 tricket er en god loesning paa sikkerhedsproblemet som det er beskrevet. Men
jeg synes at det er en mystisk logik. Jeg ville nok finde det mere naturligt, hvis
der i tabellen var en afdeling/grupp/bruger identifikation som web interrfaces
kunen bruge til at checke adgang med.
Avatar billede kennethv Nybegynder
01. oktober 2008 - 12:28 #3
Jeg e nu nået til det punkt, hvor jeg skal have lavet muligheden for at chefen skal klikke på et link i en mail, som han har modtaget. Det med at sende en mail har jeg klaret, men det at chefen klikker på et link i mailen, som fører personen hen til webinterface, hvordan skal dette klares?

Point er nu 200. Da jeg intet aner nogett om det og får sådan at komme lidt hurtigt igang kunne jeg godt tænke mig noget kode til delphi 2006.
Avatar billede arne_v Ekspert
01. oktober 2008 - 15:05 #4
Du vil lave et link til et CGI script skrevet i Delphi 2006 ?

Linket er der jo ingen ben i - saa du spoerger vel reelt om hvordan man laver
CGI scripts i Delphi 2006 ?
Avatar billede kennethv Nybegynder
01. oktober 2008 - 15:18 #5
Ja, det er korrekt. :) Jeg kan godt se at det var vist ikke sådan liiiige til at forstå det jeg havde skrevet. :(
Avatar billede kennethv Nybegynder
01. oktober 2008 - 15:35 #6
Øhm, bare lige for en god ordens skyld. CGI, hvad er det egentlig? Jeg havde nu forstillet mig at jeg bare sendte et link til chefen, som så trykker på det og vupti er inde på en hjemmeside ved hjælp af en browser. Det der så skulle ske var, at der kommer en standard tekst op med  f.eks. "Din medarbejder FELT1 fratræder sin stilling d. FELT2. Han er bruger af denne pc FELT3 hvad skal der ske med den. Skal den retur Ja FELT4 Nej FELT5"

De forskellige felt 1 + 2 + 3 er så taget fra min DB, men felt 4 eller felt 5 bliver overført til min db. Er det så CGI der skal laves eller er vi ude i noget ren html kode?
Avatar billede arne_v Ekspert
01. oktober 2008 - 16:12 #7
CGI er en protokol mellem web servere og scripts. Scipts kaldes saa CGI scripts. Ogsaa
hvis de er EXE filer.

I det her tilfaelde kunne det virke som at:

du emailer chefen et link til http://intranet/cgi-bin/reminder?medarbejder=177

IIS koerer saa reminder.exe som du har lavet i Delphi der slaar medarebjder 177 op
og viser det der skal vises.

(det var nemt at lave i f.eks. PHP, men du er jo til Delphi)

-------

Alternativet ville vaere at din service uploadede en reminder177.html (evt. lavet udfra
en template) til IIS og at du mailede linket http://intranet/store/reminder177.htm
der saa bare er statisk HTML.

Det vil virke, men er efter min mening lidt klodset. Du har et oprydnings problem.
Og du aner ikke om chfen faktisk har laest linket (med CGI scriptet kan du markere
i databasen naar den er laest !).
Avatar billede kennethv Nybegynder
01. oktober 2008 - 16:33 #8
Det er klart interesseret i den del med CGI og PHP. For jeg har interesse i at vide hvornår bossen er udfyldt de felter jeg har brug for, for at komme videre i prossesen.
Avatar billede kennethv Nybegynder
01. oktober 2008 - 16:34 #9
Hov, jeg går da udfra at der er et sammenspil mellem CGI og PHP, ikk? eller er det hele bare PHP?
Avatar billede arne_v Ekspert
01. oktober 2008 - 16:47 #10
det er to alternativer:

A)  CGI med EXE lavet i Delphi

B)  PHP

du skal kun vaelge en af dem.
Avatar billede kennethv Nybegynder
01. oktober 2008 - 17:23 #11
Så tror jeg at det skal være PHP og så har du ret det er ikke i dette forum at dette spørgsmål skal oprettes i.

Men skal der ikke være et eller andet som man skal sende med Delphi for at PHP ved hvad ID man skal have i?
Avatar billede arne_v Ekspert
02. oktober 2008 - 01:56 #12
Det er jo bare at lave et link:

http://intranet/reminder.php?medarbejder=177

så kan PHP siden nemt fiske de 177 ud.
Avatar billede arne_v Ekspert
02. oktober 2008 - 01:57 #13
syntaxen er:

$_GET['medarbejder']
Avatar billede kennethv Nybegynder
09. oktober 2008 - 12:28 #14
Hvordan kan man kalde de funktioner og procedure som HRC har lagt ind?
Avatar billede arne_v Ekspert
19. januar 2009 - 01:53 #15
De er lige til at kalde fra Delphi.

MD5 er indbygget i PHP.

Tid at få afsluttet her ?
Avatar billede kennethv Nybegynder
19. januar 2009 - 09:02 #16
Ja, det tror jeg. :)
Avatar billede arne_v Ekspert
21. januar 2009 - 04:04 #17
Nogen der skal smide et svar ?
Avatar billede kennethv Nybegynder
21. januar 2009 - 08:29 #18
Ja,da. I kan bege gøre det.

½ skade til begge?
Avatar billede arne_v Ekspert
22. januar 2009 - 01:54 #19
fino
Avatar billede kennethv Nybegynder
22. januar 2009 - 08:38 #20
Jeg kan først give ½ skade til hver når HRC har lagt et svar, ikk?
Avatar billede arne_v Ekspert
22. januar 2009 - 14:56 #21
yes
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester