Väldigt simpel miniräknare

mars 5th, 2008 av admin No comments »

Fick frågan av en gammal kompis som precis börjat programmera i PHP hur man gör en miniräknare. Så jag visade honom… jag spelade in en film där jag steg för steg visar hur man på ett väldigt simpelt sätt kan göra detta. Detta är absolut ett nybörjar script, men för honom så var det ett bra sätt att förstå hur man skapar funktioner, samt hur man kan jobba med switch-satser, if-satser och formulär.

Jag vill varna för stavfel och gramatikfel… jag hade inget manus eller mall att gå efter. Jag bara skrev scriptet rakt upp och ner, så en del formuleringar och annat kan vara lite ”off”.

– Filmen är borttagen -

Här är koden

[php]
//Vi börjar med att skapa en funktion som kan räkna ut det vi vill att den ska
function calc($value1, $value2, $x){

//Vi vill sedan skapa en if-sats som kan kontrollera om de inskickade värdena är toma.
//Om dem är det så returnerar vi ett felmeddelande istället för summan av en uträkning.
//Vi börjar dock med att ta bort alla eventuella blanksteg (mellanslag)
$value1 = trim($value1);
$value2 = trim($value2);
if(empty($value1) || empty($value2) || empty($x)){
$sum = ”Du måste fulla i alla fält”;
}

//Om allt är OK i if-satsen ovan börjar vi uträkningarna, beroende på räknesättet.
else{
switch($x){
case ‘+’: $sum = $value1+$value2; break;
case ‘-’: $sum = $value1-$value2; break;
case ‘*’: $sum = $value1*$value2; break;
case ‘/’: $sum = $value1/$value2; break;
}
}
//Vi returnerar här $sum som innehåller antingen ett felmeddelande, eller summan av
//en uträkning
return $sum;
}

//Nu behöver vi en if-sats som kontrollerar när formuläret vi kommer skapa sist, skickas.
//Vi vill även skicka alla värden till funktionen calc så att vi får tillbaka summan av uträkningen
//Vi vill även skriva ut vad vi räknar ut, och vad summan blir… alternativt ett felmeddelande.
if(isset($_POST['skicka'])){
$sum = calc($_POST['tal1'], $_POST['tal2'], $_POST['x']);
echo ”{$_POST['tal1']} {$_POST['x']} {$_POST['tal2']} = $sum”;
}

//Sista steget är att skapa själva formuläret som används för att skicka de värden vi vill räkna ut.
//Samt vilket räknesätt… Detta sker i ren HTML
?>

Tal 1:
+

*
/Tal 2:

[/php]

En programmerares miljö

mars 4th, 2008 av admin No comments »

Eftersom programmering är ett av mina intressen, spenderar jag ganska mycket tid framför datorn och knackar kod. Det är därför väldigt att omgivningen är så bekväm och optimal som möjligt. Jag är inte en Jolt slukande, chips ätande power programmerare utan föredrar en annan typ av ”uppsättning” när jag ska sitta länge framför datorn.

Först och främst strukturerar jag upp mitt arbete och bestämmer vad som ska göras och i vilken ordning. Jag programmerar aldig på tom mage då det har en tendens att få hjärnan seg (inte så konstigt). Jag dricker väldigt mycket när jag sitter framför datorn, och då menar jag inte sprit. Det blir vatten eller Pepsi Max, alternativt en lättöl. Sen har jag alltid vissa rutiner innan jag börjar (har bara blivit så).

  1. Jag kontrollerar alltid e-posten och svarar på obesvarade mail.
  2. Avslutar andra påbörjade saker  som t ex påbörjade texter, photoshop saker mm.
  3. Ordnar en skön playlist i winamp (T ex. Daft Punk, No Doubt, Save Ferris, Timbaland, The Ventures… osv).
  4. Ofta så programmerar jag tillsammans med en annan (Erik), så vi brukar delar upp arbetet mellan oss.
  5. Utöver detta så eliminerar jag alla störande moment runt omkring mig.

För den mer teknikintresserade kör jag på följande utrustning och mjukvaror

  • Operativsystem: WinXP Pro och 2003 server. Vi använder 2003 på vår utvecklingsserver som vi ansluter remote till och färdigställer projekt.
  • Hårdvara: AMD 64 X2 Dual Core 3800+, 3GB Ram.
  • Skärm: 20″ LCD
  • Program: Dreamweaver, Notepad++, Notepad.
  • PHP: Version 5.2.4
  • Apache: Version 2.2.4
  • MySQL: Version 5.0.45

Det är väldigt personligt hur man programmerar och i vilken miljö man väljer att befinna sig i… men så här är det för mig och det fungerar perfekt.

Säkerhet i lager

mars 3rd, 2008 av admin No comments »

Det pratas idag extremt mycket om säkerhet i media på grund av alla hemsidor som blivit utsatta för attacker, webbhotell som släckts ner och massa annat.  ”Säkerhet” har blivit ett extremt hett ämne att diskutera, vilket jag faktisikt tycker är bra. Vi lär oss av våra misstag, vi får ta del av andras misstag, vilket gynnar oss som jobbar med säkerhet… oavsett inom vilket område du jobbar. Jag vill dela med mig av en liten ”modell” eller vad man vill kalla det där jag genom olika lager illustrerar hur man skulle kunna tänka när det gäller säkerhet. Mer specifikt, säkerhet för en server… detta eftersom servern, och dess innehåll oftast är det man vill skydda.

Det här med lager är inte mitt påhitt, men jag tycker det är ett bra sätt att visa hur jag menar.  Jag ”lånar” OSI modellen lite för att illustrera. Sen vet jag inte om det jag illustrerar existerar (ni får gärna rätta mig)… om det Inte gör det så döper jag modellen till BSPIL – Model (Basic Security Protection In Layers)

Lager 1 – Fysiska lagret
Begränsa fysisk åtkomst till din server. Hur du begränsar det beror på vad du ska skydda, men någon form av kontroll där man endast tillåter viss personal åtkomst till det man vill skydda. Det svåra är att bestämma vilka man ska lita på. Fel person och du kan råka ut för sabotage!

Lager 2 – Remote
Om din server tillåter fjärraccess är det extremt viktigt att även här kontrollera vilka som ska få åtkomst, samt vad de kan göra. Utöver detta är det även extremt viktigt hur anslutingen till servern ser ut. Trafiken bör köras genom en VPN tunnel, samt om det finns ett webbinterface så bör du köra med SSL. Kort sagt.. kryptera allting som man kan få åtkomst till externt!

Lager 3 – Portar och Processer
Väldigt viktigt att ha koll på vad som är öppet utåt(internet), och vilka processer(tjänster) som servern kör. I standard utförandet av en server (nyinstallerad) finns det en bunte öppna portar och körande processer. Portar man inte använder vill man stänga, processer som inte används vill man stoppa. Du bör använda dig av en brandvägg och router (fristående enheter, eller kombinerade) för att begränsa vad som är öppet utåt (portar mm). Att endast ha en mjukvaru-brandvägg på samma dator/server som du vill skydda är fel. Du bör ha båda delarna.. alltså en enhet som finns mellan datorn/servern och internet och en mjukvaru-brandvägg i datorn. Blockera alla portar som inte behövs utifrån (21, 22, 23, 25, 53 mm).

Låt oss anta att du vill ha åtkomst porten 23(TELNET) extern för att kunna styra routern. Det man kan göra då är att blockera alla portarna så att externa användare inte kan ansluta till dessa portarna. Du skapar sedan en VPN tunnel mellan dig och det lokala nätverk du vill ha åtkomst till, får en lokal ip-adress och på så sätt kan du lokalt få åtkomst till telnet.

När det gäller processer som körs bör man först och främst ha koll på vad man behöver. Du kan därefter ”döda” de processer som inte är av nytta (hur man gör det beror på operativet). Du bör endast köra de processer som behövs… Inte mer.

Lager 4 – Lösenord
Detta är oftast det sista hindret för en hackare och man bör därför ta lösenord och hantering av lösenord på fullaste allvar. Ett svagt lösenord (god, qwerty, dog, boll, anakin…..) är bland det farligaste som finns. Med punkterna nedan vill jag visa hur man bör (enligt mig) hantera lösenord.

  • Använd inte kända ord (katt, hus, mamma, anakin)
  • Blanda gärna bokstäver, siffror och specialtecken (LE_p4zz0, 1r1nzid3_, ytm0nt-3rIn.g)
  • Att ha längre lösenord är bra, men man behöver inte överdriva (8-16 tecken räcker)
  • Byt lösenord så ofta du kan (varje eller vart annan månad)
  • Skriv inte ner lösenord. Memorera dem!
  • Använd sunt förnufft vid lagring av dem på webbserver. (Hash+salt för att skydda mot bland annat brute force attacker)Detta är inte alt man bör ha i åtanke.. men det är en början när det gäller säkerhet.Jag kommer fylla på ”modellen” efterhand och kanske även göra någon slags grafisk illustrering.
  • install.php

    mars 3rd, 2008 av admin No comments »

    För den som är intresserad av att bygga ett lite större script som användare själva ska konfigurera, kan det vara lämpligt med en installationsfil som skapar all databasinformation, filer mm. Tänkte dela med mig av en installationsfil som vi (EGKG Data) har utvecklat till en gästbok som jag även senar kommer publicera i denna blogg.

    Som sagt, det är en installationsfil till en gästbok, men går väldigt lätt att modifiera till att installera vad som helst. Nu ingår det även HTML och CSS i denna koden för att få struktur och bättre utseende. Anledningen till att css’en är inbakad i samma fil är för att denna fil, efter installationen, ska raderas och då är det onödigt att ha en massa extra text i css filen som inte används.
    [php]
    ob_start();
    ?>
    "http://www.w3.org/TR/html4/loose.dtd">



    if(isset($_POST['install_do'])){
    if(!isset($_GET['done'])){
    //Variablar för databasanslutningen
    $db_adress = trim($_POST['install_adress']);
    $db_name = trim($_POST['install_db']);
    $db_user = trim($_POST['install_dbuser']);
    $db_pass = trim($_POST['install_dbpass']);

    //Variablar för admindelen
    $admin_u = trim($_POST['install_admin_u']);
    $admin_p = trim($_POST['install_admin_p']);
    $admin_r = trim($_POST['install_admin_r']);

    //Kontrollerar uppgifter för databasanslutningen
    if(empty($db_adress)) {
    $error_handle[0] = "Databas: Vänligen ange en korrekt adress”;
    $ch[0] = ”0″;
    $display_error1 = 1;
    }
    else{$error_handle[0] = ”Databas: Adress är OK”; $ch[0] = ”1″;}

    if(empty($db_name)) {
    $error_handle[1] = ”Databas: Vänligen ange ett korrekt databasnamn”;
    $ch[1] = ”0″;
    $display_error2 = 1;
    }
    else{$error_handle[1] = ”Databas: Databasnamn är OK”; $ch[1] = ”1″;}

    //Kontrollerar användaruppgifterna för administration
    if(empty($admin_u)){
    $error_handle[2] = ”Användaruppgifter: Vänligen ange ett användarnamn”;
    $ch[2] = ”0″;
    $display_error3 = 1;
    }
    else{$error_handle[2] = ”Användaruppgifter: Användaruppgifter: Användarnamn är OK”; $ch[2] = ”1″;}

    if(empty($admin_p)){
    $error_handle[3] = ”Användaruppgifter: Vänligen ange ett lösenord”;
    $ch[3] = ”0″;
    $display_error4 = 1;
    }
    else{$error_handle[3] = ”Användaruppgifter: Lösenord är OK”; $ch[3] = ”1″;}

    if(empty($admin_r)){
    $error_handle[4] = ”Användaruppgifter: Vänligen upprepa lösenordet”;
    $ch[4] = ”0″;
    $display_error5 = 1;
    }
    else{$error_handle[4] = ”Användaruppgifter: Upprepat lösenord är OK”; $ch[4] = ”1″; }

    if($admin_r !== $admin_p){
    $error_handle[5] = ”Användaruppgifter: Lösenorden matchar inte!”;
    $ch[5] = ”0″;
    $display_error5 = 1;
    $display_error4 = 1;
    }
    if($admin_r == $admin_p){
    $error_handle[5] = ”Användaruppgifter: Lösenorden är OK”;
    $ch[5] = ”1″;
    }

    }
    }

    ?>

    if(!isset($_GET['done'])){
    ?>
    Installation – Databasinställningar
    Fyll i nedanstående fält med korrekta uppgifter för din databas. Dessa uppgifter är nödvändiga för att vi skall kunna ansluta till databasen och skapa de tabeller som gästboken kommer använda.

    /> Adress (ex localhost)

    /> Databasnamn

    /> Ange önskat användarnamn

    /> Ange önskat lösenord (minst 6 tecken)

    /> Repetera lösenordet

    Se till så att mappen connection har skrivrättigheter

    }
    ?>

    //Skriver ut felmeddelanden
    if(isset($_POST['install_do'])){
    if(!isset($_GET['done'])){

    for($i = 0; $i <= 5; $i++){
    if($i == 0){echo '

    Felmeddelande
    ‘;}
    if($ch[$i] == ”0″){ echo $error_handle[$i]; echo ”
    ”;}
    if($i == 5){ echo ‘

    ‘;}
    }

    }
    }

    if(isset($_POST['install_do'])){
    if(!isset($_GET['done'])){
    //Om dessa satser stämmer fortsätter installationen
    if(!empty($admin_u)){
    if(!empty($admin_p)){
    if(!empty($admin_r)){
    if($admin_r == $admin_p){

    //Testar databasanslutningen
    $conn = @mysql_connect($db_adress, $db_user, $db_pass) or die(’

    Anslutning mysslyckad
    Vänligen kontrollera databasuppgifterna

    ‘);
    $try = @mysql_select_db($db_name, $conn) or die(’

    Anslutning misslyckad
    Vänligen kontrollera databasnamnet

    ‘);

    //Table för gästboken
    $table_gast = ”CREATE TABLE `$db_name`.`gast` (
    `id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `namn` VARCHAR( 50 ) NOT NULL ,
    `ort` VARCHAR( 50 ) NOT NULL ,
    `hemsida` VARCHAR( 50 ) NOT NULL,
    `inlagg` VARCHAR( 1000 ) NOT NULL,
    `ip` VARCHAR( 20 ) NOT NULL,
    `datum` VARCHAR( 30 ) NOT NULL
    ) ENGINE = MYISAM ”;

    //Table för inställningar
    $table_settings = ”CREATE TABLE `$db_name`.`settings` (
    `id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `title` VARCHAR( 100 ) NOT NULL ,
    `pages` INT( 10 ) NOT NULL ,
    `max_page` INT( 10 ) NOT NULL ,
    `inlagg` INT( 100 ) NOT NULL
    ) ENGINE = MYISAM ”;

    //Table för ban
    $table_ban = ”CREATE TABLE `$db_name`.`ban` (
    `id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `ip` VARCHAR( 50 ) NOT NULL
    ) ENGINE = MYISAM ”;

    //Table för administration
    $table_sec = ”CREATE TABLE `$db_name`.`sec` (
    `id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `user` VARCHAR( 100 ) NOT NULL ,
    `pass` VARCHAR( 50 ) NOT NULL ,
    `salt` VARCHAR( 50 ) NOT NULL,
    `x` int( 5 ) NOT NULL
    ) ENGINE = MYISAM ”;

    //Anropar variablarna som skapar tabellerna
    @mysql_query($table_gast) or die(’

    Table problem
    Ett problem uppstod när tablen skulle skapas!1

    ‘);
    @mysql_query($table_settings) or die(’

    Table problem
    Ett problem uppstod när tablen skulle skapas!1

    ‘);
    @mysql_query($table_sec) or die(’

    Table problem
    Ett problem uppstod när tablen skulle skapas!3

    ‘);
    @mysql_query($table_ban) or die(’

    Table problem
    Ett problem uppstod när tablen skulle skapas!4

    ‘);

    //Funktion som hashar lösenordet
    function hashGen ($admin_p, $x){
    $losenord = md5($admin_p);
    for($i = 0; $i <= $x; $i++){
    $losenord = sha1($losenord);
    }
    return $losenord;
    }

    //Funktion som returnar ett salt
    function saltGen ($y, $x){
    $salt = md5($y);
    for($i = 0; $i <= $x; $i++){
    $salt = sha1($salt);
    }
    return $salt;
    }

    //Funktion som returnar det slutgiltgliga lösenordet med salt
    function passGen ($baked_hash, $baked_salt){
    $pass = sha1("$baked_hash"."$baked_salt");
    return $pass;
    }

    //Skickar lösenordet till funktionen, tar emot när det är hashat
    $x = mt_rand(10, 99);
    $y = mt_rand(1000, 9999999);

    //Anropar tre funktioner som genererar och returnar salt och lösenord
    $baked_hash = hashGen($admin_p, $x);
    $baked_salt = saltGen($y, $x);
    $baked_pass = passGen($baked_hash, $baked_salt);

    //Skickar användaruppgifter till sec
    $insert_sec = "INSERT INTO sec (user, pass, salt, x) VALUES ('$admin_u', '$baked_pass', '$baked_salt', '$x')";
    @mysql_query($insert_sec) or die('

    Table problem
    Det gick inte att skicka uppgifter till databasen!

    ‘);

    //Skickar inställningar till settings
    $nmn = ”iGäst”;
    $pgs = 10;
    $lgt = 1000;
    $mxs = 3;
    $insert_settings = ”INSERT INTO settings (title, pages, max_page, inlagg) VALUES (’$nmn’, ‘$pgs’, ‘$mxs’, ‘$lgt’)”;
    @mysql_query($insert_settings) or die(’

    Table problem
    Det gick inte att skicka uppgifter till databasen!

    ‘);

    //Skapar connect.php och fyller i databas inställningar
    $myFile = ”connection/connect.php”; //sökväg och filnamn
    $fh = fopen(”$myFile”, ‘w’) or die(’

    Fil problem
    Det gick inte att skapa filen!
    Kontrollera rättigheter.

    ‘); //skapar filen och öppnar den för att skriva

    //innehåll i filen som skapas
    $stringData = ‘ $mysql_server = "'."$db_adress".'";
    $mysql_user = "'."$db_user".'";
    $mysql_password = "'."$db_pass".'";
    $mysql_database = "'."$db_name".'";

    $time = date("Y-m-d H:i:s");

    $conn = mysql_connect($mysql_server, $mysql_user, $mysql_password);
    mysql_select_db($mysql_database, $conn);
    ?>‘;
    fwrite($fh, $stringData); //skriver datan till filen
    fclose($fh); //stänger filen

    //Byter sida
    header(”location:install.php?done”);
    }
    }
    }
    }
    }
    }
    if(isset($_GET['done'])){
    echo ‘Installationen lyckades

    * Radera filen install.php!
    * Sätt tillbaka korrekt rättigheter på mappen connection!
    * Kontrollpanelen hittas i mappen sec och heter admin.php!

    ‘;
    }
    ?>



    ob_end_flush();
    ?>
    [/php]

    Hash+Salt+Multiple Runs

    mars 3rd, 2008 av admin No comments »

    Jag har precis skrivit klart ett script i PHP för ett litet projekt jag håller på med och tänkte faktiskt dela med mig av det. Jag vill börja med att säga att jag inte vet om den korrekta benämningen för en loop hash är ”multiple runs”, men jag hade det någonstans i bakhuvudet och det låter bra.

     Syftet med scriptet är alltså att skapa ett säkert lösenord som man sedan sparar undan i databasen (eller fil). Eftersom det inte är rekommenderat att endast hasha ett lösenord så behövs det även ett salt för att utöka säkerheten för brute force attacker mm. Jag kör även en multiple run för att ytterligare utöka säkerheten. Men vad man måste förstår är att detta enbart är vad jag vill kalla, ”ett segt moment” för en hackare som lyckats få åtkomst till lösenorden.

    Det ger dig tid att reagera och byta ut alla lösenord…

    Scriptet är uppbyggt i funktioner och allting är kommenterat. Jag har även längst ner skrivit hur man ska göra för att kontrollera ett lösenord från inlogging, mot det som finns i databasen eller vart du nu har sparat användaruppgifterna.

    [php]
    /*
    Skapad av Kristoffer Geiser - 2008-02-29
    Användare får använda, modifiera detta script så som de själva önskar.
    */

    //Funktion som behandlar lösenordet
    function password ($password, $runs){
    $password = md5($password);
    for($i=0; $i <= $runs; $i++){
    $password = sha1($password);
    }
    return $password;
    }
    //Funktion som skapar ett salt
    function salt (){
    $chars = "8!b9yea@of,g5ic¤j2d3k4_l7mhrn%#ps&t6uqvx-.1";
    $length = strlen($chars);

    for($i=0; $i <= $length; $i++){
    $runs = mt_rand(0,$length);
    $salt .= substr($chars, $runs, 1);
    }
    return sha1($salt);
    }
    //Funktion som fogar ihop löseordet och saltet i en loop med sha1
    function fuse ($password, $salt, $runs){
    for($i=0; $i <= $runs; $i++){
    $fused = sha1("$password @:_:@ $salt");
    }
    return $fused;
    }

    //Det lösenord som ska skyddas
    $losenord = "lösenordet";

    //Detta slumpar fram ett värde som används för multiple runs.
    //SPARAS I DATABASEN
    $runs = mt_rand(1,99);

    //Skickar lösenordet till funktionen password. Får tilbaka det hashat ett antal gånger.
    $gen_losen = password($losenord, $runs);

    //Anropar funktionen salt som skickar ett hashat salt.
    //SPARAS I DATABASEN
    $gen_salt = salt();

    //Anropar fuse som bakar ihop salt och löseord och hashar det ett antal gånger
    //SPARAS I DATABASEN
    $gen_fuse = fuse($gen_losen, $gen_salt, $runs);

    //########################################################################################
    //Exempel vid inmatat lösenord
    //########################################################################################
    /*
    För att förstå denna del så får ni tänka er att användaren redan är registrerad och att följande värden finns sparade i databasen:
    $runs
    $gen_salt
    $gen_fuse
    I delen nedan illustrerar vi hur man återanvänder funktionerna för att generera och matcha ett lösenord som en användare skickat
    när dem loggat in.
    */

    //$inmatat är variablen vars innehåll är det lösenord som användaren försöker logga in med
    //Se till att använda mysql_real_escape_string() eller något annat skydd innan du hämtar värden från databasen
    $inmatat = "lösenordet";
    //$db_salt är variablen vars innehåll är hämtat från databasen, baserat på exempelvis användarnamnet man matade in vid inloggningen
    $db_salt = "salt från databasen";
    //$db_runs är variablen vars innehåll är hämtat från databasen, baserat på exempelvis användarnamnet man matade in vid inloggningen
    $db_runs = "loop värdet från databasen";

    //Här anropas funktionerna som behövs och vi får tillbaka ett lösenord som sparas i $check_pass.
    //Vi kan sedan matcha detta lösenord mot det lösenord som finns i databasen, baserat på exempelvis användarnamnet
    //som matades in vid inloggningen
    $check_pass = fuse(password($inmatat, $db_runs), $db_salt, $db_runs);

    //Här är ett exempel på hur man kan matcha lösenordet
    //$databas_losen innehåller det ihop fogade lösenordet och saltet som lagrats i databasen vid registreringen
    if($check_pass == $databas_losen){ echo "Grattis!"; }
    else{ echo "Ditt lösenord matchade inte!"; }
    ?>[/php]