============================================================================== Documento.......................: ASS-0001 Revisione.......................: 002 Data............................: 02-Ago-1992 Relatore e responsabile progetto: Marcello Ardini (2:332/403.2) Collaborazione e consulenza.....: Alberto Pasquale (2:332/504.1) Giovanni Lopes (2:332/108.2) Stefano Crimi' (2:332/505.12) ============================================================================== SPECIFICHE TECNICHE PER DOOR DI AUTOABILITAZIONE UTENTI A.F.I. === Proposito: =============================================================== Si vuol creare una struttura di programmi completamente automatizzate che permette ad un socio A.F.I. (Associazione Fidonet Italia) di auto abilitarsi ad un particolare livello e con una certa serie di flag, il tutto precedententemente configurato dal SysOp. Come nome alla DOOR e' stato deciso in AFIMAT, visto che come spunto e' stato preso lo sportello bancario automatico BANCOMAT. Il progetto e' sviluppato tenendo presente i seguenti obbiettivi: - Sicurezza per l'utente, contro hackering del codice. - Tutela del SysOp da abilitazioni di non soci A.F.I. - Tutela dell'utenza A.F.I. contro impropriazioni indebite dei dati di aggiornamento degli AFIMat - Trasparenza e documentazione del progetto. === Strutture programma di gestione database Soci: =========================== Segue la struttura del file "AFI_SOCI.DTA" che utilizza il programma AFITUTOR, il quale aggiorna tale DataBase e prepara le liste di aggiornamento da inviare ai vari nodi dotati di AfiMat per aggiornare il DataBase locale. _SchedDBaseUser = record NomeCognome: String[35]; {( 1) 36 byte Nome e cognome del socio } DataNascita: _date {( 2) 4 byte Data di nascita } Indirizzo: String[35]; {( 3) 36 byte Via e numero di abitazione } CAP: String[5]; {( 4) 6 byte Codice di Avviamento Postale } Citta: String[35]; {( 5) 36 byte Citta'e provincia socio } Tessera: LongInt; {( 6) 4 byte numero assoluto tessera } Flag: Byte; {( 7) 1 byte flag } Codice: String[25]; {( 8) 26 byte codice riservato dell'utente } Iscrizione: _date; {( 9) 4 byte data di inizio validita' tessera } Validita: Integer; {(10) 2 byte giorni validita' tessera } Note: String[79]; {(11) 80 byte note sul socio } TelefonoVoce: String[15]; {(12) 16 byte numero telefonico a voce } TelefonoBBS: String[15]; {(13) 16 byte numero telefonico del BBS } BBS: String[23]; {(14) 24 byte numero nodo del BBS } fill: array[1..11] of Byte;{ 11 byte spazio riservato ad aggiunte } end; { Totale struttura 302 byte } Nel dettaglio: (1) E' il nome e il cognome del socio, tutto in maiuscolo e tra le parole che compongono il nome e il cognome utilizzare come separatore uno spazio. (2) Data di nascita nel formato specificato sotto nella struttura _data (3) Indirizzo composto da via e numero civico (4) Codice di avviamento postale (5) Citta', provincia ed eventualmente nazione di residenza del socio (6) Numero della tessera, che e' un numero intero positivo che parte da 1 e viene incrementato di 1 all'inserirsi dei soci, in caso di omonimie, come discriminatore, viene utilizzato proprio questo numero. (7) Flag propri dell'utente bit 1 esa 01 = se alzato socio ordinario bit 2 esa 02 = se alzato scheda da cancellare bit 3 esa 04 = se alzato scheda mutata o nel NomeCognome o nel Codice bit 4 esa 08 = se alzato record selezionato altri bit = non utilizzati ed abbassati (8) Codici personale e riservato all'utente, questi e un insieme di minimo 4 caratteri alfanumerici e trattati in modo case sensitive fino ad un massimo di 25. L'insieme di definizione e' ['0'..'9','a'..'z','A'..'Z']. (9) Data di iscrizione, e cioe' di inizio validita' della tessera. (10) Numero di giorni cui vale la tessera, solitamente 365, se il numero e' negativo, non ha scadenza. (11) Riservato ad eventuali note o commenti. (12) Numero telefonico cui il socio e' rintracciabile a voce. (13) Se il socio e' ordinario questo campo e' riservato al suo numero di telefono (14) Numero di nodo nel formato :/[.] del BBS, nel caso sia un socio sostenitore, di quello piu' frequentato. La struttura dei campi data e' la seguente: _date = record day : Byte; { 1 byte - Numero del giorno range 1..31 } month: Byte; { 1 byte - Numero del mese range 1..12 } year : Word; { 2 byte - Numero dell'anno } end; { Totale struttura 4 byte } === Struttura della lista del DataBase utenti che utilizza AfiMat: =========== Segue la struttura del file di DataBase che utilizza AfiMat, questo e' un file di tipo binario organizzato a record fissi dal nome "AFIUSER.BBS". _SchedUser = record Flag: Byte; { (1) - 1 byte } Fill: Byte; { (2) - 1 byte } CRCUtente: Word; { (3) - 2 byte } NroTessera: LongInt; { (4) - 4 byte } CRCKey: LongInt; { (5) - 4 byte } end; { Totale struttura 12 byte } Nel dettaglio: (1) Batteria di otto flag con il seguente significato bit 1 esa 01 = se alzato socio ordinario bit 2 esa 02 = se alzato scheda da cancellare bit 3 esa 04 = se alzato scheda mutata o nel NomeCognome o nel Codice bit 4 esa 08 = se alzato record selezionato altri bit = non utilizzati e abbassati (2) Byte usato per effettuare un allineamento a Word della struttura, questo byte puo' assumere valori random. (3) CRC a 16 bit del nome dell'utente tutto in maiuscolo con partenza 0 e con uno spazio di separazione tra le parole (4) Numero progressivo della tessera (numero assoluto tessera) (5) CRC a 32 bit della chiave segreta data all'utente (codice), con partenza -1 esadecimale FFFFFFFF. Questo CRC viene calcolato trattando la stringa in modo case sensitive (facendo distinzione tra caratteri maiuscoli e minuscoli). NOTA BENE: Questa e' la struttutura del file utente in memoria, nel file, ogni record verra' opportunamente criptato con l'algoritmo in appendice A, ove la password di criptazione sara' hardcoded al programma e decisa al momento opportuno dal presidente dell'AFI e resa nota solo agli sviluppatori del software. Per le prove si utilizzera' la password "GABIBBO" (le virgolette sono escluse). === Struttura del file di diff: ============================================== Il file di diff e' un file di tipo testo che contiene opportunamente codificate le informazioni (aggiornamenti) che dovranno essere inseriti nel database utenti locale ad ogni AfiMat. Il nome del file sara' "AFI_DIFF.", e cosi' strutturato: : <..> esempio: + 13/01/1991 23:04:34 :013 # A3678123BEAC693BAD3145AB 67FA # A3637534AAAC693BAD3145BC FF98 ... = + , sta ad indicare che quella linea contiene la data e l'ora di creazione del file = # , sta ad indicare che quella linea contiene le informazioni relative ad un utente = gg/mm/aaaa nel caso i campi siano ridotti vanno riempiti con il carattere 0 es 01/12/1992 questa e' la data di creazione del file = oo:mm:ss stesse condizioni di gestione di data es 00:02:12 = e' il giorno dell'anno cui e' creato il file, tale informazione verra' messa anche nell'estensione del file. = sono 24 caratteri esadecimali che rappresentano in forma esadecimale il dump della scheda che verra' inserita nel database locale. Ovviamente prima della trasformazione in esadecimale, la scheda viene criptata. = crc a 16 bit scritto in formato esadecimale di scheda, il valore di partenza per il calcolo del CRC e' 0. Questo CRC viene calcolato sulla stringa di testo esadecimale. Le linee sono dovranno avere come terminatore un CR e un LF codici codice ASCII 13 codice ASCII e 10, nel mentre il file potra' opzionalmente terminare con un ^Z codice ASCII 26. === Cos'e' AfiMat: =========================================================== AfiMat e' una Door di autoabilitazione per i soci, in versioni specifiche per i vari tipi software di BBS. Questa Door deve poter essere richiamabile dal MenuPrincipale (MainMenu) del BBS, ed in caso di attivazione leggere dal sistema il Cognome ed il Nome inseriti dall'utente. AfiMat effettuera' gli appositi controlli sull'utente, e settera' i privilegi dell'utente come specificato in un opportuno file di configurazione e generare un opportuno report che periodicamente (almeno una volta alla settimana) dovra' essere mandato al proprio up-link, che provvedera' a ruotare verso il concentratore il quale parsera' tutti i report verificando che non vi siano abusi di sicurezza verso un determinato socio. Opzionalmente, AfiMat o un programma aggiuntivo dovra' poter far il merge tra le diff e la lista utenti dell'AfiMat "AFIUSER.BBS". === Schema a blocchi di funzionamento dell' AfiMat: ========================== :Inizio AfiMat verifichera' che il SysOp sia presente nella lista dei soci ORDINARI di AFI. Se il controllo e' positivo e non viene trovato il file di report dovra' essere aperto con la seguente stringa: # AFI REPORT * SOCIO: * SYSOP: esempio # AFI REPORT * SOCIO: 1 * SYSOP: FRANCO_MULATO altrimenti il programma deve uscire. :Presentazione Verra' presentato all'utente un banner, che spieghera' in brevi parole che cos'e' l'AFIMAT e il suo scopo. Questo sara inserito in un apposito file esterno. :Socio? Verra' posta la domanda: Sei un socio di A.F.I. (Associazione FidoNet Italiana). Digita S se Si oppure N per No? a questa domanda, non deve corrispondere un default, in modo che l'utente sia costretto a scegliere. La forma cosi' "abbondante" nella domanda e' consigliata, visto che puo' capitare che l'utente che si collega sia ai suio primi tentativi di utilizzo di un BBS. :Non e' un socio Se l'utente seleziona N, verra' fatta la seguente richiesta: Vuoi sapere che cosa e' l'A.F.I. (S/N)? se l'utente risponde N, si esce dalla door, se invece risponde S, gli si mosta un opportuno file di testo e si va a scrivere nel report la seguente linea: ? esempio ? 01/05/1992 02:03:34 POPI_BONNICI e poi si esce dalla door. :E' un socio Nel caso l'utente fosse un socio ed abbia risposto si alla domanda se e' un socio si inizia il procedimento di verifica. Come prima cosa si chiede: Il tuo nome e cognome e' "" (S/N)? esempio Il tuo nome e cognome e' "PAOLO ROSSI" (S/N)? Se la risposta e' N, si richiede l'input del nome e cognome del socio, altrimenti si prosegue. La richiesta del nome e cognome, si rende necessario, perche' un socio ad esempio Paolo Rossi, in quel BBS si sia dovuto iscrivere come Paolo Rossi Giacomini, visto che esisteva gia' un Paolo Rossi, nel mentre per l'AFI tale utente e' identificato come Paolo Rossi. :Nro tessera Ora il sistema chiede il numero di tessera del socio Digita il tuo numero di tessera: :Pwd Ed infine chiede la Pwd personale di AFI Inserisci ora il tuo identificativo personale di socio AFI: In questo caso l'eco a video deve essere soppresso o sostituito da * o . in modo che neanche accidentalmente ne il Sysop o suoi collaboratori possano leggere tale informazione. Comunque per i SysOp puntigliosi, potra' essere reso configurabile il carattere da mostrare a video. La richiesta della pwd personale verra' effettuata due volte, in modo che nel caso i due inserimenti non coincidano (errore di battitura o disturbo di linea) verra' ripetuta la procedure di inserimento pwd senza nessuna formalita', ma sempre MAI visualizzando la pwd sbagliata ne quello che si digita. :Tutto ok? Ora AfiMat visualizzera' i dati inseriti dall'utente e gli chiedera' se sono tutti corretti. Nome: PAOLO ROSSI Socio: 000123 Security: 4 caratteri Sono corrette queste informazioni (S per Si, N per No, A per abbandonare la certificazione)? Se l'utente risponde N si ritorna ad eseguire la trafila da ":E' un socio". Se l'utente risponde A si abbandona la door seguendo le specifiche di uscita :Verifica L'utente ha risposto affermativamente, si inizia a parsare il file criptato con i dati degli utenti AFI, e la decriptazione dovra' avvenire solo in memoria, senza creare file di supporto. Se il controllo ha esito positivo si esce dalla door con opportuno procedimento. :No_AFI Nel caso il controllo fallisca si si scrive nel report: ! esempio ! 12/03/1992 02:03:23 PAOLO_ROSSI 5689 PAOLO_ROSSI_GIACOMINI inoltre si incrementa un contatore e si avvisa l'utente che non e' stato trovato e si ripete la trafila da ":Utente OK?". Questa trafila in caso di dati sbagliati si puo' ripercorrere per massimo tre volte. :Uscita da AFIMAT Nel caso l'utente l'utente sia stato riconosciuto socio AFI: si settano privilegi, come specificato in configurazione dal SysOp, applicando una condizione di somma dei flag (or) e controllando di non ridurre il privilegio dell'utente nel caso questi lo abbia piu' alto di quello fissato. Nel file di report verra' scritto: + esempio + 12/03/1992 02:03:23 PAOLO_ROSSI 123 PAOLO_ROSSI_GIACOMINI Nel mentre se ha utilizzato i suoi tre tentativi o casca la linea si esce senza nessuna formalita'. A discrezione del programmatore, nel caso abbia esaurito i tre tentativi, si puo' prevedere che vengano abbassati i privilegi e modificati i flag sempre secondo la configurazione che stabilira' il SysOp. === Riepilogo sul Report generato da AfiMat: ================================= Il file di report e' un file di testo che deve essere inviato periodicamente al concentratore. Il nome del file sara' ".REP", dove codice e' il numero di tessera del socio ordinario espesso con un numero esadecimale di 8 caratteri. All'interno del report il tessera verra' invece espicitato in forma decimale. La prima riga del file sara': # AFI REPORT * SOCIO: * SYSOP: Nel caso vengano chieste informazioni su AFI: ? Nel caso l'utente erri la sua identificazione o non venga trovato: ! Nel caso venga riscontrotato che e' un socio AFI: + Esempio di un file di report nel caso sara': "00000001.REP" # AFI REPORT * SOCIO: 1 * SYSOP: FRANCO_MULATO ? 01/05/1992 02:03:34 POPI_BONNICI ! 12/03/1992 02:03:23 PAOLO_ROSSI 5689 PAOLO_ROSSI_GIACOMINI + 12/03/1992 02:03:23 PAOLO_ROSSI 123 PAOLO_ROSSI_GIACOMINI Le linee sono dovranno avere come terminatore un CR e un LF codici ASCII 13 e 10, nel mentre il file potra' opzionalmente terminare con un ^Z codice ASCII codice 26. === Appendice A ============================================================== Routine di criptazione, decriptazione in Turbo Pascal (tm): function RevCript(s, key: _str255): _str255; Var i, j: Word; begin if (s <> '') and (key <> '') then begin i := 1; j := 0; repeat Inc(j); if s[j] <> #00 then begin if s[j] <> key[i] then s[j] := Chr(Ord(s[j]) xor Ord(key[i])); Inc(i); if i > Length(key) then i := 1; end; until j = Length(s); end; RevCript := s; end; Routine di criptazione, decriptazione in C: /* Traduce la stringa *s di 12 caratteri usando la chiave *key */ void traduci(char *s,char *key) { int i=0; int j=0; do if (s[i]) { if (s[i]!=key[j]) s[i]^=key[j]; if (!key[++j]) j=0; } while(++i<12); } === Appendice B ============================================================== Riepilogo dei nomi dei file: AFITUTOR.EXE - Eseguibile gestione database utenti e creazione dei diff. AFI_SOCI.DTA - DataBase utenti Nota: questi due file sono presenti esclusivamente sul concentratore. AFIMAT.EXE - Eseguibile door da installare sul BBS, l'estensione potrebbe cambiare se il programma gira su sistemi non DOS. AFI_LIST.EXE - Compilatore di AFI_LIST e AFI_DIFF, in alcune versioni di AFIMat, questo compilatore e' integrato all'AFIMat stesso. AFIUSER.BBS - File di aggiornamento nuovi soci e utenti non piu' soci. AFI_LIST. - File soci AFI in formato testo AFI_DIFF. - File di aggiornamento nuovi soci e utenti non piu' soci. .REP - Report generato da AfiMat e che verra' inviato periodicamente al concentratore. e' il giorno dell'anno cui viene generato il file e' il numero di tessera del socio ordinario che installa AfiMat, espesso in esadecimale Per quello che riguarda i nomi degli archivi di distribuzione dei vari AFIMat il nome dovra' essere cosi' composto: AMvvvppo.ccc Dove AM e' una costante acronimo di AfiMat. vvv e' la versione del programma dove il primo carattere e' la versione e i secondi due la revisione, una versione 2 revisione 3 risultera' 203. ppp e' l'acronimo del nome del programma(LO = LoraBBS, RA = Remote Access, SB = SuperBBS, MA = Maximus, DL = Dialog, OP = Opus, RE = Revolution). o e' il sistema operativo su cui gira (D = MS-DOS, 2 = OS2, X = UNIX, A = AMIGA-DOS, W = Windows) ccc e' l'estensione tipo del compattatore usato per compattare l'archivio. Sul compattatore si lascia libera scelta purche sia uno di quelli maggiormente usati sul sistema che gira quella determinata versione. Ad esempio, per una versione 1.01 di AFIMat, i nomi dei file risuterebbero: AM101LOD.ZIP versione per LoraBBS sotto MS-DOS AM101MAD.ZIP versione per Maximus sotto MS-DOS AM101MA2.ZIP versione per Maximus sotto OS2 AM101RAD.ZIP versione per Remote Access sotto MS-DOS AM101SBD.ZIP versione per SuperBBS sotto MS-DOS AM101DLA.LZH versione per Dialog sotto AMIGA-DOS === Appendice C ============================================================== Routine per il calcolo del CRC in Turbo Pascal: {$A+,B-,D-,E-,F+,I+,L-,N-,O+,R+,S+,V-} UNIT Crc; INTERFACE { Note: Your crc variable must be initialized to 0, before } { using tis routine. } { Translated to Turbo Pascal (tm) V4.0 March, 1988 by J.R.Louvau } { } Type str255 = String[255]; FUNCTION UpdCrc(cp: BYTE; crc: WORD): WORD; FUNCTION UpdC32(octet: BYTE; crc: LONGINT) : LONGINT; function CRC16Str(s: str255; start: Word): Word; function CRC32Str(s: str255; start: LongInt): LongInt; IMPLEMENTATION (* crctab calculated by Mark G. Mendel, Network Systems Corporation *) CONST crctab: ARRAY[0..255] OF WORD = ( $0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7, $8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef, $1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6, $9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de, $2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485, $a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d, $3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4, $b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc, $48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823, $c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b, $5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12, $dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a, $6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41, $edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49, $7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70, $ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78, $9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f, $1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067, $83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e, $02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256, $b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d, $34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405, $a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c, $26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634, $d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab, $5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3, $cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a, $4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92, $fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9, $7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1, $ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8, $6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0 ); (* * updcrc derived from article Copyright (C) 1986 Stephen Satchell. * NOTE: First argument must be in range 0 to 255. * Second argument is referenced twice. * * Programmers may incorporate any or all code into their programs, * giving proper credit within the source. Publication of the * source routines is permitted so long as proper credit is given * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, * Omen Technology. *) FUNCTION UpdCrc(cp: BYTE; crc: WORD): WORD; BEGIN { UpdCrc } UpdCrc := crctab[((crc SHR 8) AND 255)] XOR (crc SHL 8) XOR cp END; { Use a type LONGINT variable to store the crc value. } { Initialise the variable to $FFFFFFFF before running the crc routine. } { VERY IMPORTANT!!!! -> This routine was developed for data communications} { and returns the crc bytes in LOW to HIGH order, NOT byte reversed! } { To turn the valu into a 'normal' LONGINT, you must reverse the bytes! } { e.g. } { VAR } { l, crc: LONGINT; } { list: ARRAY[0..1023] OF BYTE; } { counter: INTEGER; } { } { BEGIN } { crc := $FFFFFFFF; (* initialise *) } { FillChar(list,SizeOf(list),1); (* dummy array *) } { FOR counter := 0 TO (Pred(SizeOf(list))) DO (* run thru *) } { crc := UpdC32(buf[counter],crc); (* finding crc *) } { FOR counter := 1 TO 4 DO (* reverse *) } { l := (l SHL 8) OR BYTE(crc); (* the bytes *) } { (* l now contains the 'normalized' crc *) } { } (* Converted to Turbo Pascal (tm) V4.0 March, 1988 by J.R.Louvau *) (* Copyright (C) 1986 Gary S. Brown. You may use this program, or *) (* code or tables extracted from it, as desired without restriction. *) (* *) (* First, the polynomial itself and its table of feedback terms. The *) (* polynomial is *) (* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 *) (* Note that we take it "backwards" and put the highest-order term in *) (* the lowest-order bit. The X^32 term is "implied"; the LSB is the *) (* X^31 term, etc. The X^0 term (usually shown as "+1") results in *) (* the MSB being 1. *) (* *) (* Note that the usual hardware shift register implementation, which *) (* is what we're using (we're merely optimizing it by doing eight-bit *) (* chunks at a time) shifts bits into the lowest-order term. In our *) (* implementation, that means shifting towards the right. Why do we *) (* do it this way? Because the calculated CRC must be transmitted in *) (* order from highest-order term to lowest-order term. UARTs transmit *) (* characters in order from LSB to MSB. By storing the CRC this way, *) (* we hand it to the UART in the order low-byte to high-byte; the UART *) (* sends each low-bit to hight-bit; and the result is transmission bit *) (* by bit from highest- to lowest-order term without requiring any bit *) (* shuffling on our part. Reception works similarly. *) (* *) (* The feedback terms table consists of 256, 32-bit entries. Notes: *) (* *) (* The table can be generated at runtime if desired; code to do so *) (* is shown later. It might not be obvious, but the feedback *) (* terms simply represent the results of eight shift/xor opera- *) (* tions for all combinations of data and CRC register values. *) (* *) (* The values must be right-shifted by eight bits by the "updcrc" *) (* logic; the shift must be unsigned (bring in zeroes). On some *) (* hardware you could probably optimize the shift in assembler by *) (* using byte-swap instructions. *) (* polynomial $edb88320 *) (* *) CONST crc_32_tab: ARRAY[0..255] OF LONGINT = ( $00000000, $77073096, $ee0e612c, $990951ba, $076dc419, $706af48f, $e963a535, $9e6495a3, $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988, $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91, $1db71064, $6ab020f2, $f3b97148, $84be41de, $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7, $136c9856, $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9, $fa0f3d63, $8d080df5, $3b6e20c8, $4c69105e, $d56041e4, $a2677172, $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940, $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59, $26d930ac, $51de003a, $c8d75180, $bfd06116, $21b4f4b5, $56b3c423, $cfba9599, $b8bda50f, $2802b89e, $5f058808, $c60cd9b2, $b10be924, $2f6f7c87, $58684c11, $c1611dab, $b6662d3d, $76dc4190, $01db7106, $98d220bc, $efd5102a, $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433, $7807c9a2, $0f00f934, $9609a88e, $e10e9818, $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01, $6b6b51f4, $1c6c6162, $856530d8, $f262004e, $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457, $65b0d9c6, $12b7e950, $8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65, $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb, $4369e96a, $346ed9fc, $ad678846, $da60b8d0, $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9, $5005713c, $270241aa, $be0b1010, $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f, $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, $2eb40d81, $b7bd5c3b, $c0ba6cad, $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a, $ead54739, $9dd277af, $04db2615, $73dc1683, $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8, $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1, $f00f9344, $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb, $196c3671, $6e6b06e7, $fed41b76, $89d32be0, $10da7a5a, $67dd4acc, $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, $d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252, $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b, $d80d2bda, $af0a1b4c, $36034af6, $41047a60, $df60efc3, $a867df55, $316e8eef, $4669be79, $cb61b38c, $bc66831a, $256fd2a0, $5268e236, $cc0c7795, $bb0b4703, $220216b9, $5505262f, $c5ba3bbe, $b2bd0b28, $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d, $9b64c2b0, $ec63f226, $756aa39c, $026d930a, $9c0906a9, $eb0e363f, $72076785, $05005713, $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38, $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21, $86d3d2d4, $f1d4e242, $68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, $18b74777, $88085ae6, $ff0f6a70, $66063bca, $11010b5c, $8f659eff, $f862ae69, $616bffd3, $166ccf45, $a00ae278, $d70dd2ee, $4e048354, $3903b3c2, $a7672661, $d06016f7, $4969474d, $3e6e77db, $aed16a4a, $d9d65adc, $40df0b66, $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9, $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, $cdd70693, $54de5729, $23d967bf, $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94, $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d ); FUNCTION UpdC32(octet: BYTE; crc: LONGINT) : LONGINT; BEGIN { UpdC32 } UpdC32 := crc_32_tab[BYTE(crc XOR LONGINT(octet))] XOR ((crc SHR 8) AND $00FFFFFF) END; function CRC16Str(s: str255; start: Word): Word; Var j: Byte; begin if s <> '' then for j := 1 to Length(s) do start := UpdCrc(Ord(s[j]), start); CRC16Str := start; end; function CRC32Str(s: str255; start: LongInt): LongInt; Var j: Byte; begin if s <> '' then for j := 1 to Length(s) do start := UpdC32(Ord(s[j]), start); CRC32Str := start; end; END. {unit} Routine per il calcolo del CRC in C: /* The CRC-16 used by XMODEM, YMODEM, and ZMODEM */ /* crctab calculated by Mark G. Mendel, Network Systems Corporation */ word crctab[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; /* updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. NOTE: First argument must be in range 0 to 255. */ #define updcrc(cp, crc) (crctab[((crc >> 8) & 255) ^ cp] ^ (crc << 8)) word crcstr (char *buf, word crc) { char *p; p = buf; while (*p) crc = updcrc (*p++, crc); return (crc); } /* crc deve essere inizializzato a 0 */ /* CRC 32 */ long crc32(int c, long crc) { static long cr3tab[] = { /* CRC polynomial 0xEDB88320 */ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; return( cr3tab[ ((int)crc ^ c) & 0xff ] ^ ((crc >> 8) & 0x00FFFFFFL ) ); } long crc32str(char *str) /* esempio calcolo CRC32 su stringa case-insensitive */ { char c; long crc = -1L; while( *str != NULL ) { c = toupper( *str ); crc = crc32( c, crc ); str++; } return( crc ); } === Appendice D ============================================================== Lista realizzatori e curatori progetto AFIMat. Per il generatore e gestione liste e DataBase Soci AFI: Marcello Ardini (2:332/402.2) Per la realizzazione delle door AFIMat per i singoli BBS: LoraBBS v. 2.20 MS-DOS Marcello Ardini (2:332/402.2) Maximus BBS v. 2.00 MS-DOS Alberto Pasquale (2:332/504.1) Remote Access v. 1.11 MS-DOS Giovanni Lopes (2:332/108.2) Super BBS v. MS-DOS Giovanni Lopes (2:332/108.2) Dialog AMIGA Stefano Crimi' (2:332/505.12) === Appendice E ============================================================== Alcune note e problemi incontrati durante lo sviluppo: - Da notare, che l'intero progetto e' stato sviluppato su sistema che utilizza come processore un Intel, quindi le strutture dati rispecchiano le caratteristiche che questo processore usa per manipolare i dati. Da notare che tra Intel e Motorola il metodo di scrittura dei dati cambia, cioe' sono invertiti byte piu' significativo con quello meno significativo. === Appendice F ============================================================== Aree files gestite mediante Tick. - AFIMAT distribuzione archivi con door AFIMat e specifiche progetto (questo documento). - AFIDIFF AFI_DIFF.nnn (con nnn numero del giorno dell'anno di creazione) L'area dovra' essere predisposta in sola ricezione, nel senso che e' permesso solo al concentratore inserire gli AFI_DIFF.nnn. - AFIREP Invio degli .REP al concentratore ( e' l'indirizzo in formato esadecimale del nodo di generazione del report) Una volta inviati i report potranno essere cancellati, e comunque cancellati dai nodi di transito. Nota: tutte queste aree file *NON* dovranno essere accessibili ne in file request ne in download da BBS. === (End of Document :-)) ==============================================