Archive for 'windows'

Flex: ViewStack select by id

Flashben programozni szívás, Flexben is. Ezzel a problémával több mint egy órát tököltem, ezért szentelek neki egy gyors kis blogbejegyzést..

Van egy ViewStack komponensünk (MyViewStack), ebben pedig szépen elnevezett gyermek elemek. Elnevezés alatt azt értem, hogy mindegyiknek van saját “id”-je. Szeretnénk, hogy ne csak hagyományos módon az index alapján  ( MyViewStack.selectedIndex=1) lehessen elérni, hanem a “Stack” id-je alapján, amit stringként közlünk a megjelenítő metódussal.

A metódus adott: MyViewStack.selectedChild=, viszont a bemenet nyilván nem lehet egy sima változónév, Container-re kell hivatkoznunk. Naív módon próbálkoztam ilyen flashes közhelyekkel: this[target] és társai..

Persze nem ment. Mivel Container kellett neki minden áron, beimportáltam az  mx.core.Container csomagot és rájöttem, hogy mennyire  szépen meg lehet ezek után oldani a problémát:

import mx.core.Container;
private function showTarget(target:String) : void
{
    MyViewStack.selectedChild = Container(MyViewStack.getChildByName(target)) ;
}

IIS - MySQL Membership Provider telepítése

A cél egy integrált vitruális felhasználókat kezelő rendszer létrehozása volt IIS alá, ami független az IIS Manager Userektől és természetesen a Windows felhasználói fikókoktol is, ugyanakkor elérhető az IIS FTP, WebDAV és egyéb szolgáltatásaiból. A megoldás egyik alappillére a .Net Membership rendszere.

Az én megvalósításomban az adatbázis nem a megszokott Microsoft SQL, hanem MySQL. A telepítés kicsit macerás volt egy idegesítő hiba és a konfiguráció nüanszai miatt, ráadásul mivel nem vagyok .Net fejlesztő és VS-ből soha nem próbáltam ilyen kapcsolatot létrehozni, IIS-ből sem volt könnyebb.

Kapásból vakvágányra futottam, mert Google-ban keresgéltem, megszegve ezzel az MS fejlesztők és rendszergazdák elsőszámú szabályát: használd a Support weboldalakat, mert sz@runk a google-ra és nem hagyjuk, hogy a jó megoldásokat első oldalon hozza. Szal’ elkezdtem behackelni ezt a göncöt: http://www.codeproject.com/KB/database/mysqlmembershipprovider.aspx Már az SQL táblák létrehozása egy katasztrófa, hagyjuk is.

A jó megoldást a MySQL saját connectora jelenti: Connector/Net 6.2: Nem kell félni az MSI installertől, kiválóan működik.

A Connector mellé installálni kell a MySQL ODBC Drivert is. Töltsük le a MySQL oldaláról, majd telepítsük.

IIS Managerben elég bonyolult a sok kattintgatás, ezért inkább postolok egy helyes, jól működő web.config kódot:

<!-- Előbb eltávolítjuk az alapértelmezetteket, mert az IIS hiányolja őket és a sajátunk nem fog működni-->
<connectionStrings>
        <remove name="LocalSqlServer" />
        <remove name="LocalMySqlServer" />
        <add name="LocalMySqlServer" connectionString="Datasource=localhost;Database=dbname;uid=username;pwd=password;" providerName="MySql.Data.MySqlClient" />
</connectionStrings>

<system.web>
    <roleManager enabled="true" defaultProvider="MySQLRoleProvider">
      <providers>
        <clear />
        <add name="MySQLRoleProvider" type="MySql.Web.Security.MySQLRoleProvider, MySql.Web, Version=6.0.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" connectionStringName="LocalMySqlServer" applicationName="LoginControl" />
      </providers>
    </roleManager>

<!-- autogenerateschema="true", ha nem kézzel akarjuk létrehozni a táblákat..-->
 <membership defaultProvider="MySQLMembershipAppProvider">
       <providers>
        <clear />
        <add name="MySQLMembershipAppProvider" type="MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.0.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" autogenerateschema="true" connectionStringName="LocalMySqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="LoginControl" requiresUniqueEmail="true" passwordFormat="hashed" maxInvalidPasswordAttempts="7" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
      </providers>
    </membership>

    <compilation>
      <assemblies>
        <add assembly="MySql.Data, Version=6.0.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
      </assemblies>
    </compilation>

</system.web>

Jellegzetes hibalehetőségek, amikkel én is szívtam:

1. ODBC Dirver tényleg legyen rendben, akár teszteljük is, mielőtt bármit konfigurálnánk.

2. Ha az ODBC rendben, ne felejtsük a schema=”true”-t hozzáadni a MemberShip Providerhez, mert különben nem jönnek létre a szükséges táblák a MySQL adatbázisunkban.

3. Figyeljünk, hogy ne legyen hiba a connection stringben, nem szereti a jelszóban a különleges karaktereket.

Ha mindent jól csináltunk, az IIS Manager ASP.NET / .Net Users-be belépve egyrészt nem kapunk hibát, másrészt létrejönnek adatbázisunkban a szükséges táblák és akár meg is kezdhetjük a felhasználók feltöltését. Az IIS tökéletes felhasználókezelést nyújt, nemsokára posztolom az én Flexben készült “Fancy Remote” applikációmat, ami még fejlesztés alatt áll.

IIS7 Custom Basic Authentication

Már régóta kerülgetem a Codeplex-en ezt a projektet, soha nem jutottam el addig, hogy kipróbáljam. Az a baj az IIS Basic Authentication-nel, hogy nem tudunk vele virtuális felhasználókat kezelni, csak igen komplikált módon. Akkor is csak úgy, hogy az IIS configjában tárolódnak a felhasználók adatai. A célom az volt, hogy egy külső MySQL adatbázisba valamilyen okos formában tárolódjanak az IIS virtuális felhasználói és azokat az összes IIS-es szolgáltatásból (Védett könyvtárak, FTP, WebDav, stb..) elérjem, autentikálhatóak legyenek. Pontosan erre jó a Custom Basic Authentication nevű kis projekt. Pontosabban arra, hogy egy .Net Membership Providert elérhetővé tegyen Basic Authentication formában.

Telepítése nem túl bonyolult:
Töltsük le a http://www.codeplex.com/CustomBasicAuth weboldalról (az installert, ne a forrást).
Persze gondok lesznek, különben nem ínék róla :)
Az installer.cmd a gautil.exe-t használja, ami nagy marhaság a kedves fejlesztő részéről, hiszen a .Net Framework 2 óta ez a utility nincs benn a Frameworkben, csak az SDK-ban. Kiszolgálókra meg ugyebár mióta divat SDK-t pakolni :S Az MS hivatalos álláspontja egyébként az, hogy a GACUTIL egy fejlesztői eszköz, ezért is vette ki a Frameworkből.

Itt kicsit tétováztam, mert nem igazán tudtam, mire jó egyáltalán ez a kis programocska. Aztán kiderült, hogy igazából nincs rá szükség. Fogjuk a 3db dll fájlt és másoljuk a C:/Windows/assembly könyvtárba, így bekerülnek a GAC-ba. Majd az installer kikommentelt utolsó két parancsát futtassuk le parancssorból a fájlok mappájában:

iisschema.exe /install CustomBasicAuthentication_schema.xml
IisRegMgmt CustomBasicAuth LeastPrivilege.CustomBasicAuthentication.Management.CustomBasicAuthenticationModuleProvider LeastPrivilege.CustomBasicAuthentication.Management.dll

Voila, készen is vagyunk, az IISManager-ben a Site-unk Authentication panelján már ott kell lennie a Custom Basic Authentication opciónak is. Az Edit-re kattintva konfigurálhatjuk, hogy melyik providert használja. Tiltsuk le az összes többi Authentication módot és próbáljuk ki a böngészőből. Ha feldobja az autentikációs ablakot, akkor nyertünk. A sikeres bejelentkezéshez persze kell a működő provider is.

Ha esetleg nem működne a cucc, és még nincs a helyén, akkor az IIS Managerben a Modules panelon adjuk hozzá az installált modulokhoz a CustomBasicAuthentication-t is a legördülő listából.

IIS7 Pass-through Authentication + WebDAV

Miután sikerült beüzemelni a .Net Membership Providert és a Custom Basic Authentication kiegészítést, lehetővé vállt, hogy MySQL-ben tárolt virtuális felhasználóimat minden szolgáltatásnál használhassam. A WebDAV persze megint bekavart..

Amit én szerettem volna az a következő:
1. WebDAV SSL titkosítással
2. Egy központi WebDAV root folder és abban Virtuális mappaként bemappolva a felhasználók Site-jai úgy, hogy a webdav root-hoz és más domainjai alatt lévő tartalomhoz se férjenek hozzá.
Az egyes hosztolt weboldalak elérései így néznének ki:
http://www.host.hu/webdav/domain1.hu
http://www.host.hu/webdav/domain2.hu

Az elképzelés tökéletesen működhetne, de nem ment elsőre a dolog..
A főbb lépések így néztek ki:
1. A host.hu/webdav/domain1.hu - virtuális mappa WebDav Authentication Rule-jai közé hozzáadtam a “test” nevű felhasználót.
2. Adtam neki WebDAV jogokat, innentől kezdve elméletileg van joga a virtuális könyvtár fizikai helyére és annak összes alkönyvtárára WebDAV-on keresztül.
3. Csatlakoztam a “test” nevű felhasználóval és rendben meg is jelent a domain1.hu könyvtár tartalma:

log/                   --        Tue, 20 Jan 2009 09:07:05 GMT
tmp/                   --        Tue, 20 Jan 2009 09:07:13 GMT
www/                   --        Wed, 28 Jan 2009 15:35:31 GMT

A log és tmp könyvtárakkal semmi gond, minden jog érvényesült. Viszont a www-re listázáskor hibát kaptam, nem érvényesültek rá a domain1.hu-ra kiadott jogok. Csak a www-re? Mivan? Miért is?

Mivel az IIS konfigurációja elosztott, több szinten definiálható, ezért amikor egy kérés jön a webszerverhez, ő gyorsan körbenéz minden beállítási szinten: megnézi az applicationHost.config fájlban az alapbeállításokat, érvényesíti, a location tagekben (ha van) a site konfigurációját, érvényesíti, egy szinttel lejjebb, a könyvtárstruktúrában elhelyezett web.config fájlokban keres, érvényesít és halad méglejjebb az almappák web.config-jaihoz, stb, stb.. Hopp! Ez lesz a baj!

Mivel a http://www.host.hu/domain1.hu/www mappa igazábol a szerveren hosztolt domain1.hu site root-ja, az ottani web.config fájlt is érvényesíteni szeretné függetlenül attól, hogy én WebDAV-on keresztül egy másik alkalmazásból hívom meg a könyvtár elemeit. Szeretne hozzáférni a web.config-hoz, de nyilván nem tud, innentől kezdve nagyon egyszerű dolgunk van, hiszen csak azt kell megakadályoznunk, hogy a domain1.hu alkönyvtárait és az azok alatti könyvtárak web.config fájljait is keresse az IIS. A legszebb az egészben, hogy ehhez csak annyit kell tennünk, hogy a domain1.hu virtuális könyvtárához hozzáadjuk az allowSubDirConfig=”false” paramétert az applicationHost.config központi konfigurációs fájlban.

A dolog működik, viszont óriási biztonsági rést üt. Gondolkozzunk el egy picit, hogy hogyan működik a WebDAV. A HTTP protokoll hátán utaznak az infok, a 80-as porton. Az IIS elkülöníti a WebDAV és sima HTTP kéréseket, jogosultságilag is, azzal nincs is gond, hogy a WebDAV jogokat csak a webdav/domain1.hu, webdav/domain2.hu stb.. virtuális mappákra és azok felhasználóira adom ki így megakadályozva, hogy egyik felhasználó a másik cuccai közt bóklásszon.
De ha ezt sima HTTP-n keresztül teszi, akkor autentikáció után a böngészőbe csak a mefelelő elérési utat kell bepötyögnie és bármilyen fájlhoz hozzáfér amit a virtuálsi WebDAV-os mappákkal bemappoltam. Azt mondanán, hogy ez sem gond, hiszen ezt közvetlenül mondjuk a domain1.hu/titok.html-en keresztül közvetlenül is megteheti. Pedig nem. Mivel a web.config fájlokban olyan autentikációs és authorizációs illetve átirányítási utasítások lehetnek, melyek elfednek bitonyos fájlokat a működő aplikációkban, ezért ha mi hatástalanítjuk a allowSubDirConfig-al, szabad az út az ilyen módon védett tartalomhoz. a http://www.host.hu/webdav/ felől érkezve.

Ezért mindenképp meg kell akadályoznunk, hogy a bejelentkezett felhasználó HTTP (nem WebDav) kéréssel elérje a könyvtárakat (persze a saját könyvtárát el kell, hogy érje, hiszen ha HTTP nincs, WebDAV sincs). A megoldás pofon egyszerű és szép is:

1. A webdav/ könyvtárunkat fosszuk meg az Authorization beállításoknál az Allow All-tól. Ezzel megakadályozva, hogy az autentikált felhasználó bármit is elérjen a könyvtáron belül.
2. Osszunk ki egy szinttel lejjebb a webdav/domain1.hu felhasználójának a “test” usernek egy Allow-t.

Kész a shared hosting webdav elérés is. Enjoy!
Felelőséget persze nem vállalok az itt leírtakért, mert csak részben érintem a biztonsági kérdéseket. Ezen kívül rengeteg egyéb követelménynek kell teljesülnie egy biztonságos kiszolgálón.

Napi Script: Window wget alternatívák

Ez az első szkript, amit megosztanék a “Napi script” sorozatban. Terveim szerint felteszek majd sokkal komplexebb, speciális kódrészleteket is főleg PowerShell és VBScript nyelveken. Elsősorban olyan szkripteket, amik az adminisztrátorok mindennapos problémáit oldják meg windows rendszereken. Rengeteg (akár fizetős) segédprogram és alkalmazás kiváltható szkriptes megoldásokkal. Minimális programozási tudással lehet rajtuk változtatni, testreszabni, okosítani őket.

WGET: A unixos wget parancs nagyon hasznos, gyakran használjuk és éppen ezért windowson erősen érezhető a hiánya. A Windows CMD parancsai között nincs ilyen, helyette több alternatívát ismertetnék:

1. Wget.exe - Remek kis utility. Aki nem akar sokat szórakozni töltse le, másolja be valamelyik PATH mappába és már használhatja is úgy mint más rendszereken. Mivel a normál commandline-ban nem csak wget parancs nincs, hanem a szögfeldolgozási lehetőségek is igen gyérek, a visszakapott http válasszal, vagy fájlal már nem nagyon tudunk mit kezdeni. Ha mégi ilyen szándékaink vannak, más, szkriptelési megoldások után kell néznünk:

2. VBScript: Az alap, IXMLHTTPRequest interfészt használó HTTP kérést végrehajtó szkript alább látható. Nem többről van szó, mint egy http kérés indításáról és a válasz tartalmának kiíratásáról. A kikommentelt rész az url paraméterként való megadhatóságára szolgál ha CMD-ből, szeretnénk futtatni.

Option Explicit
On Error Resume Next

Dim url
url="http://blog.vargapeter.com"

'Dim paramz
'Set paramz = WScript.Arguments
'url = paramz(0)

Set objHTTP = CreateObject("MSXML2.XMLHTTP.3.0")
objHTTP.open "GET", url, false
objHTTP.send()
MsgBox objHTTP.responseText
Set objHTTP = Nothing

3. Powershell: Mivel PS-ből meg tudunk hívni .Net-es osztályokat, használjuk a System.Net.WebClient-et. A neve beszédes, van egy rakás metódusa és tulajdonsága. Lássunk egy egyszerű példát az előző kód mintájára:

$httpclient= new-object System.Net.WebClient
$httpclient.DownloadString("http://blog.vargapeter.com")

4. Mi van még? PS alatt azért jól el vagyunk látva, írtak többen is cmdleteket az egyszerűbb hívás érdekében:
WGet 2 for PowerShell
Jacobian’s wget for PowerShell

Hát ennyi.. használjuk azt a megoldást, ami céljainknak legjobban megfelel.
Holnap új téma, új szkriptek!

uTorrent több példányban

Hogyan lehet egy progit windowsban több példányban használni? Kétszer kell feltelpíteni? Nem. Nekem arra volt szükségem, hogy egy torrent program ne csak egy, hanem több példányban futhasson. Az uTorrent esetén ezt elég könnyű megoldani és mivel a progi egyébként is a szívem csücske, rá esett a választás. A módszer a következő:

1. Telepítjük az uTorrent legfrissebb változatát.
2. Duplikáljuk az uTorrent mappáját a ProgramFiles mappában uTorrent2 néven.
3. Az intéző címsorába pötyögjük be: %appdata%uTorrent
4. Hozzunk létre egy új mappát uTorrent2 néven az %appdata%-n belül.
5. Másoljunk minden .dat fájlt a %appdata%uTorrent2 mappába.
6. Készítsünk egy parancsikont a C:Program FilesuTorrent2uTorrent.exe-re.
7. Nyissuk meg a parancsikon tulajdonságait és a Target-et módosítsuk erre: “C:Program FilesuTorrent2uTorrent.exe” /RECOVER.

Enjoy!

IIS7 aldomain átirányítás

Az aldomainek (subdomain) leggyakrabban két átirányítási formája létezik: a redirect és a rewrite. Hagyományosan az átirányítás, azaz a rewrite csak annyit tesz, hogy egy 301-es üzenettel egy másik címre “dobja” a böngészőnket, így a böngészőbe írt url is megváltozik. A rewrite, vagyis az “átírás” ezzel szemben elfedi a kiszolgálás helyét. Lássunk két példát és IIS rule kódjaikat:

A böngészőbe ezt írjuk: http://valami.vargapeter.com/index.html
A kiszolgálás valós helye mindkét esetben:  http://vargapeter.com/valami/index.html.

Redirect

Eredmény:  http://domain.hu/valami/index.html

<rule name="aldomain" stopProcessing="true">
     <match url="^(.*)$" ignoreCase="false" />
     <conditions logicalGrouping="MatchAny">
           <add input="{HTTP_HOST}" pattern="^valami.vargapeter.com" />
     </conditions>
     <action type="Redirect" url="http://www.vargapeter.com/valami" redirectType="Permanent" />
</rule>

Rewrite

Eredmény: http://valami.domain.hu/index.html

<rule name="aldomain" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" pattern="^valami.vargapeter.com(.*)" />
    </conditions>
    <action type="Rewrite" url="valami/{R:1}" />
</rule>

Fontos, hogy az aldomainek minden esetben konfigurálva legyenek a DNS szervereken és az IIS-ben pedig a webhely (Site) kötéseihez -utálom ezt a szót- (bindings) hozzá legyenek adva.

A Rewrite talán érdekesebb picit, ezért még egy kis regexpel tarkított kódrészletet is bemutatnék, amivel praktikusan kezelhetjük aldomainjeink átirányítását. A szabály lényege, hogy a valami.vargapeter.com domaint a wwwroot/_sub/valami könyvtárra irányítja. Így nem kell öt szabályt létrehoznunk, ha öt domainünk van és külön-külön megadni a valós kiszolgálási helyüket, hanem “rendszerezve” a _sub mappában az aldomain első tagjával megegyező nevű mappa lesz a subwwwroot-juk.

<rule name="SubDomain" stopProcessing="true">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll">
        <add input="{HTTP_HOST}" pattern="^(.+).vargapeter.com(.*)" />
    </conditions>
    <action type="Rewrite" url="_sub/{C:1}/{R:1}" />
</rule>

MSSQL Időzített Backup

Az alábbiakban egy egyszerű módszert ismertetek, mely a Windows Task Schedulert használja időzített backupok készítésére egyes Microsoft SQL Server adatbázisainkról. Hasznos lehet, ha naponta vagy hetente szeretnénk  teljes backupot külső fájlba menteni külső szkriptekkel, hogy aztán további műveleteket végezhessünk velük. Az alábbi segédlet Microsoft Windows Server 2008 és SQL Server 2008 Management Studio programokhoz íródott.

Lássuk csak, mit kell tennünk:

1. Csatlakozzunk az MSSQL szerverünkhöz a Management Studio-n keresztül.

2. Válasszuk ki az adatbázist amiről biztonsági mentéseket akarunk készíteni.

3. A helyi menüből (jobb klikk) válasszuk a Tasks / Back Up.. funkciót.

4. A Back Up Database párbeszédablakban adjunk meg egy tetszőleges nevet a Backup Set-nek és a Destination listához adjuk hozzá annak a könyvtárnak az elérési útját ahová a backup fájlt szeretnénk menteni.

5. Baloldalt az Options részben állítsuk be, hogy a generált backup fájl tartalmához a visszaállítás hozzáírja-e az adatbázis tartalmát, vagy felülírja azt. Ha azt szeretnénk, hogy felülírja: “Append to an existing backup set”. Figyeljünk a fájlméretre! Ha nagy az adatbázisunk gondoskodjunk megfelelő méretű tárterületről a mentési periódus függvényében. Ha azt szeretnénk, hogy mindig csak a legutóbbi adatok legyenek a fájlban, válasszuk az “Overwrite all existing backup sets” opciót.

6. Érdemes lehet itt bejelölni még a “Verify backup when finished” és a “Checksum before..” funkciókat, ha paranoidok vagyunk érzékeny adatainkat illetően.

7. A későbbi futtatásokhoz szükség lesz az imént elvégzett beállítások adataival generált SQL fájlra. A Script gomb melletti legördülő menüből válasszuk a “Script action to File” opciót és mentsük el valahová a fájlt. Ha jól dolgoztunk, a bal alsó sarokban megjelenik egy helyes kis “Scripting completed succesfully.” felirat.

8. Ha leOKézzuk az ablakot, az első backup meg is kell, hogy történjen.

9. Az elkészített sql fájlt a parancssori Sqlcmd alkalmazáson keresztül fogjuk futtatni, ami a Microsoft SQL Server Native Client nevezetű eszköz fedőneve. Mindezt kézenfekvően egy batch fájlon keresztül. Készítsünk egy új szövegfájlt (Jegyzettömb), és a következő tartalommal mentsük el .bat kiterjesztéssel:

 sqlcmd -S .\SQLEXPRESS -i "C:\scripts\mssqlbackup\backup.sql"

10. Próbáljuk ki parancssorból, hogy működik-e.

11. Ha sikerült lefuttatnunk a batch scriptünket, a Windows Task Scheduler segítségével ütemezzük futtatását. A batch fájlba más utasításokat is írhatunk így egészen komplex backup scriptet készíthetünk.

Cool huh? :)

Windows 2008 login képernyő biztonságosabban..

A Vistából örökölt logon screen-t ne hagyjuk a Windows Server bejelentkezőképernyőjének! Óriási biztonsági rés!! 
Read more

PowerShell láz

Tegnap este belázasodtam és ágynak estem. Egy nagy alvás valamelyest helyretett és ma délutánra már jobban voltam. Arra gondoltam, hogy ha már itt döglődöm az ágyikómban, tölthetném valami hasznossal az időmet. Produktív munkára sajnos nem vagyok képes, mert olyan mint ha az agyam helyén fűrészpor lenne. Eszembe jutott, hogy van valahol egy PowerShell könyvem, amit ide-oda tologatok, de belelapozni még nem mertem. Az egyszerűbb példákat és a hello world szintű mintákat ilyen állapotban is sikerült megérteni és nagyon ígéretesnek tűnik a dolog.. Már próbálkozom aprócska programok írásával, ha valami értelmes születik amit más is tud hasznosítani, majd kiteszem ide.