pardus etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
pardus etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

18 Ağustos 2010 Çarşamba

Pardus 2010 Yaz Stajı 13. Gün

Bugün halihazırda tamamlamış olduğum kod üzerinde bir kaç iyileştirme yaptım. README, AUTHORS ve COPYING dosyalarını düzenledim.

Yaptığım iyileştirmeler, eğer yapılandırma dosyasında değer atanmamış ise varsayılan değerleri kullanacak. Başlangıçta eğer sistemde guest_name isminde bir kullanıcı var ise modülü çalıştırmayacak, guest_group isminde bir grup yok ise bunu oluşturacak ve en önemlilerinden birisi ise ev dizinini bağlarken noexec özelliği ile bağlamak.

noexec bize önemli derecede güvenlik sağlıyor. Bu özellik sayesinde kullanıcı bağlandığı ev dizini içerisinde ikilik dosya çalıştıramayacak. Aynı zamanda da kendisi de ikilik dosya yazıp bunu çalıştıramayacak.

Varsayılan değerleri kullanma kısmını da, yapılandırma dosyasını okurken bir hata oluşursa except bloğuna geçip aktarıyor ve hata ayıklama (debug) modunda ekrana dosya okunamadı diye hata veriyor ya da değerleri okurken boş çıkar ise onun varsayılan değerlerini aktarıyorum.

Kullanıcının varlığını ise pwd.getpwnam() ile sorguluyorum. Bunu try-except bloğu içerisinde yapıyorum. try içerisinde bu başarılı olur ise geriye başarısız diye değer döndürüyor, eğer başarısız olur ise except bloğuna geçiyor ve burada da hiç bir şey yapmadan normal koda devam ediyor.

Grubun varlığını da grp.getgrnam() ile sorguluyorum. Yok ise yine hata ayıklama modunda ekrana grup bulunamadı, grup oluşturulacak yazıyor ve grubu "groupadd %s" % guest_group ile oluşturuyorum.

Ayrıca daha önceden /etc/pam.d/ içerisindeki dosyalardaki control yerine uzun uzun yazılar yazıyorduk. Sadece sufficient yazmak yeterli şu an. Daha önceden de yazdığım yazıda bunu düzelteceğim.

Bahadır'ın aklındaki bir proje olan /etc/pam.d/ içerisindeki yapılandırma dosyalarını düzenleme projesini biraz araştırdım ve bunu Ubuntu'da yapmakta olan birileri olduğunu öğrendim.

İstek ise şu adreste: https://blueprints.launchpad.net/ubuntu/+spec/pam-config-framework

Ayrıca 2003 yılında da http://www.mail-archive.com/debian-wnpp@lists.debian.org/msg18384.html adresinde belirtildiği gibi istenmiş fakat zaman aşımından kapanmış.

Ubuntu'daki bu projeyi hazırlayan arkadaşa eposta yolladım. Bana bu paketin Ubuntu ve Debian için pam içerisine koyduklarını söyledi. Bunu biraz daha araştırıp Pardus'a uygulanabilirliğini araştırmayı düşünüyorum.

Sırada bir de PiSi paketi yapmak var. Daha önceden almaya karar verip paketini yaptığım paketleri düzenleyip ve yeni alacağım paketleri belirleyip bunlar üzerine çalışmalar yapacağım.

Yani Pardus 2010 Yaz Stajı, benim için tam hızıyla, zevkli, heyecanlı, öğretici yani her şeyiyle çok güzel devam ediyor.

11 Ağustos 2010 Çarşamba

Pardus 2010 Yaz Stajı 8. Gün

Hazırlamakta olduğum guestlogin projesinde şimdilik giriş yapılabiliyor ve /home/ dizininin altında guestX şeklinde bir dizini ev dizini olarak gösteriyordu.

Geçici ve parolasız girilen bir hesap için fazlasıyla tehlikeliydi. Bunun için tmpfs ve mktemp komutlarını araştırdım. Tabi bir de kullanıcıyı ev dizini olmadan oluşturmaya baktım.

Öncelikle ev dizini olmadan kullanıcı oluşturmak gayet kolay. Komutumuz:

adduser -M kullanici_adi

şeklinde. -M ev dizini olmadan yarat anlamına geliyor.

mktemp komutu ile /tmp/ dizini içerisinde rasgele bir klasör oluşturuyoruz. Bunu da

mktemp -td guestX.XXXXXX ile yapıyoruz. Buradaki guestX bildiğimiz gibi misafir kullanıcıya vermiş olduğum geçici kullanıcı adı. Noktadan sonraki 6 tane X ise rasgele oluşturacak 6 rakam-harf karışımına denk geliyor. Yani oluşturulan dizin /tmp/guest6.6jHx4f gibi bir şey oluyor.

Buraya kolay bir şekilde gelmiştim fakat önümde biraz araştırmam gereken bir konu vardı. mktemp komutu o XXXXXX leri doldurup stdout a gönderiyordu bunu. Bunu da benim bir şekilde bir değişkene atayıp o dizini tmpfs ile bağlayıp bir de o kullanıcıya atayıp ev dizini yapmam gerekiyordu. Geliştiricilerden Serdar'ın yardımıyla birlikte python ile bunu yapmak için subprocess'leri araştırdım.

Dosyanın başına import subprocess yaptıktan sonra :

procOutput = subprocess.Popen(["mktemp -td %s.XXXXXX" % username], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
homeDir = procOutput.communicate()[0][:-1]

satırları ile çözüme ulaştım. Burda yaptığım iş tam olarak alt bir süreç başlatmak. yanına yazdığım diğer argümanlar sayesinde stdout ve stderr'i okuyabilecektim.

bu Popen fonksiyonunun geri dönüş değerini bir değişkene atadıktan sonra communicate() fonksiyonu ile bakabiliyordum. Aslında bu bile sonucu bir değişkene atamak için yeterliydi fakat sonuç şu şekildeydi:

('/tmp/guest5.d6E3gh\n', None)

bu haliyle benim işimi görmüyordu. Bunun de küçük bir düzenleme yaptım. İlk baştaki lazım olduğu için communicate() den sonra [0] ı kullandım. O değişkenin içinde de en son karakter \n olduğu için [:-1] ile en son karakteri attım. Sonuç olarak elimde sadece

/tmp/guest5.d6E3gh

kaldı ve bu benim için yeterli bir bilgiydi. Bunu homeDir değişkenine atadıktan sonra bunu tmpfs ile bağladım. Bunu da:

os.system("mount -t tmpfs -o mode=700 none %s" % homeDir)

ile sağladım. Sırada ise kullanıcıyı oluşturma, bu dizini kullanıcıya verme ve onun ev dizini haline getirmek vardı. Kullanıcının sistem tarafından verilmiş adını (guestX olan) username değişkenine daha önceden attığım için aşağıdaki komutlar bunlar için yeterli oldu.

os.system("useradd -M %s 2>> /var/log/guestacc.log" % username)
os.system("chown %s:%s %s" % (username, username, homeDir))
os.system("usermod -d %s %s" % (homeDir, username))

Burda dikkatinizi çeken bir şey de 2>> olmalı. Normalde >> komutu ile stdout'u başka bir dosyaya yönlendirebiliyoruz ama stderr yine ekrana düşüyor. stderr'in dosyaya yazılması için 2>> ekliyoruz.

Başlangıç ayarlarını bu şekilde halletmiştim bir de çıkışta da bu dizini umount edip, kullanıcıyı ve ev dizinini sistemden silmem gerekiyordu. İlk olarak /etc/pam.d/system-auth dosyası üzerinde kullanıcı çıkış yaparkan bir metotun çalışması için bir ekleme yapmam gerekiyordu. Bu da:

session sufficient pam_python.so guestlogin.py

satırı idi. Bu satırı:

session required pam_unix.so

satırının hemen üstüne ekledim. Bu satırı eklediğimde ek olarak:

pam_sm_open_session

ve

pam_sm_close_session

metotları çalışıyordu. Benim işime yarayan ise close_session metotuydu.

Bu metot içinden kullanıcı adını pamh.get_user(None) ile aldım fakat burada os.environ['HOME'] komutu işe yaramıyordu. Bunun için de :

homeDir = os.path.expanduser("~%s" % username)

komutunu çözüm olarak buldum.

Diğer umount işlemlerini de normal bir şekilde devam ettirdim. Ve kod daha iyi bir durumdaydı.

Şimdilik yapmam gerekenlerden biri /tmp/ nin içersinde öyle bir dizin olsa bile mktemp komutu guestX.XXXXXX dizinini oluşturmayıp ona bağlamamı sağlıyorsa bu bir güvenlik açığı olur. Bunun bir araştırmasını yapıp, gerekirse oraya bir kontrol koymak olacak.

10 Ağustos 2010 Salı

Guest Account düzenlemeler

NOT: Bu güvenlik açığını başka şekilde hallettiğim için buradaki control kısmına sadece sufficient yazmam yeterli oldu. Ama yine de aşağıdaki yazıyı bırakıyorum.


Biraz önce yazdığım yazıdaki kodu kontrol ederken akıl almaz bir güvenlik açığı ile karşı karşıya geldiğimi öğrendim. Açık şu: Sistemdeki herhangi bir kullanıcı parola yazmadan giriş yapabiliyor. Bunun sebebi yazdığım metot her türlü SUCCESS döndürmesi. Bunun yerine hata döndürse bu sefer başka sorunlar ortaya çıkacak.

Bu şekilde aklıma /etc/pam.d/ nin içerisinde bir şeyleri değiştirmek geldi. man pam.d yaparak kolları sıvadım. Ve çözüm:

auth [user_unknown=ok success=done new_authtok_reqd=done default=ignore] pam_python.so guestlogin.py

İkinci yazdığımız sufficient yerine bunları yazıyorum. Şu an daha iyi durumda.

Şimdilik aklıma gelen düzeltme yapılması gereken yerlerden birisi de bu durumda her bilinmeyen/kayıtlı olmayan kullanıcı için SUCCESS döndürmesi. Bunun kontrolünü python betiğinin içerisinde uygulamam gerekiyor.