[실전 security ②] 웹 서버 보안 기초

보안, 암호화 2008. 8. 4. 22:02 posted by 무병장수권력자


실전! 개발자를 위한 Security 체크 포인트
② 웹 서버 보안 기초 - HTTP, Cookie, Session


작성자 : 김문규
최초 작성일 : 2008. 8. 4
* 본 포스트는 SDS e-campus의 '실전 개발자를 위한 Security 체크포인트' 강의 내용을 발췌하여 재구성한 개인적인 학습노트 입니다.

1. HTTP
웹 서버 프로그래밍을 할 때 HTTP 프로토콜에 대한 이해는 필수입니다. 구글링, 네이버링을 통해서 기본적인 사항을 꼭 파악하시길 바랍니다.
다음은 www 관련 스펙을 정리하는 W3C 주소 입니다. 참고하세요.
http://www.w3.org/Protocols/

2. Cookie
1) 쿠키란?
사용자 정보를 유지하기 위해 웹 브라우저에 의해 사용자의 PC에 저장되는 정보 (파일 혹은 메모리)
서버에서 클라이언트로 전송되는 것
<name : value> 쌍 입니다.

사용자 삽입 이미지

2) 동작 순서
1 Request Client가 Server측에 문서요청을 합니다.
2 Call Server는 Cookie를 검사하기 위해 CGI를 호출합니다.
3 Set Cookie가 없는 경우에 CGI는 Set-Cookie header를 포함한 출력을
Server에 return 합니다.
4 SetCookie Set-Cookie header에 부가 header를 덧붙여 Body와 함께 Client에
전송합니다.
5 Save Set-Cookie header를 받을 Client는 Cookie 정보(Name = Value,
Expires Date, Path, Domain)를 Cookie.txt라는 파일에 저장합니다.
6 Read,
SendCookie
Cookies.txt에 등록된 동일한 Domain의 동일한 Path를 사용자가
요청하는 경우 Client는 Cookie 정보를 header를 이용해 Server로
전송합니다.
7 Call Server는 Client로부터 받은 Cookie 정보를 환경변수
(HTTP_COOKIE)에 저장하고 CGI를 호출합니다.
8 HTTP_COOKIE CGI는 HTTP_COOKIE로부터 Cookie 정보를 복원해서 Server로
전송합니다.

3) 보안상의 위험성
쿠키는 암호화 하지 않은 평문으로 주고 받을 경우에는 네트워크를 통해 쉽게 노출되고 또한 쉽게 변조될 가능성이 높습니다.

이런 쿠키를 획득하거나 변조하는 해킹 기술을 아래와 같습니다.
- 쿠키 스니핑 (Cookie Sniffing)
해커가 개인 PC에서 사용자의 정보를 담고 있는 Cookie를 네트워크 스니퍼를 통해 획득하는 기술
- 쿠키 스푸핑 (Cookie Spoofing)
타인의 시스템 자원에 접근할 목적으로 쿠키정보를 변조하여, 정당한 사용자인 것처럼 보이게 하거나 승인받은 사용자인 체하여 시스템에 접근함으로써 추적을 피하는 고급 해킹 기법

4) 쿠키인증 기법을 사용하는 사이트의 보안대책
 - 임의로 쿠키값을 조작하지 못하도록 쿠키 값을 암호화하여 전달합니다.
 - 쿠키 저장시 서버측에서 유효성 여부를 확인할 수 있는 대책을 강구합니다.
2.변수값에 쿠키변조 여부를 확인하는 체크섬을 추가하여 운영합니다.
   (MD5, SHA1과 같은 해쉬 알고리즘 활용)
 - 쿠키 저장 시 타인이 임의로 쿠키를 읽어 들일 수 없도록 도메인과 경로 지정에 유의합니다.
 - 수신된 웹메일의 본문에 포함된 스크립트 언어소스를 필터링하거나 무력화합니다.
2. 스크립트를 무력화하면 Cross-Site Scripting을 이용한 쿠키 훔쳐가기를 방지할 수 있습니다.

5) 일반 사용자들의 보안대책
 - 웹메일 서비스 옵션에서 '자바스크립트 허용여부'를 허용하지 않는 것으로 설정합니다. 
 - 로그인한 상태로 타인의 홈페이지를 방문하지 않습니다.
 - 브라우저의 인터넷 옵션에서 쿠키를 허용하지 않을 수 있으나, 대부분의 웹사이트가 쿠키를 사용하기 때문에 차단시 사이트에 로그인이 안될 수 있습니다.

3. Session
1) Cookie vs. Session
  Cookie Session
정의 사용자마다 관리해야 하는 데이터를
각 사용자의 웹 browser가 있는 Client
컴퓨터에 기록하는 것
웹서버와 특정 사용자의 연결이 끊어
지더라도 그 사용자에 대해서 계속 관리해야
하는 데이터를 웹 서버에 기록해 둔 것
저장
방식
Client 측 메모리 혹은 파일로 저장 Session ID만 Cookie 형태로 Client에 저장
되고 실제 정보는 서버 메모리, DB 형태로
저장 (IIS 웹서버와 여러 웹어플리케이션
서버에서 많이 사용)

2) Session의 안전성
이는 곧 Session ID의 안전성과 직결된다고 할 수 있습니다. Sessino의 안전성은 Session ID가 얼마나 추측 가능한 지에 의존한다고 할 수 있습니다.

3) Session의 보안상의 위험성
대표적인 세션을 이용한 해킹으로 Session Hijack이 있습니다. 이는 다른 사람이 사용하고 있는 입, 출력을 내가 사용하는 일을 말합니다. 나의 Session ID가 노출되어서 누군가가 나의 행세를 하게 되는 것이지요.

Session Hijack의 기법으로는 아래의 방법들이 있습니다.
- ID 예측 : Session ID가 특정한 패턴이 발견되어 해커가 이를 예측하고 해당 Session ID를 사용하는 해킹
- brute forcing : 해당 해킹 툴을 사용하여 가능성이 높은 패스워드 부터 차례로 입력하는 해킹

4) 사이트 보안 대책
이들을 대처하기 위해서는 아래의 내용대로 Session ID를 설계해야 합니다.
방법 보호타입
강한
Session ID
큰 랜덤 풀로부터 Session ID를 생성하십시오.
- 1과 100,000 사이의 값을 선택하는 강한 가짜 난수 생성기는 여전히 안전하지
- 않으므로, 32비트 이상의 값을 이용하여야 합니다.
- Session ID가 예측할 수 없다는 것을 확신하기 위하여 Session ID 생성기를
- 테스트하십시오.
강한 해시
또는 암호화
된 컨텐츠
타임스탬프 또는 가짜 난수와 같은 동적 데이터를 스트링의 처음에 위치
시키십시오.
- 이것은 brute forcing를 보다 어렵고 불가능하게 만듭니다.
Session
시간 제한
강제
특정 기간의 비활동 또는 정해진 시간 이후에 상태 정보와 Session ID를
무효화하십시오.
- 서버는 ID 또는 토큰 정보를 무효화해야 합니다.
- 이것은 Session 재사용 공격으로부터 어플리케이션을 보호하는 것입니다.
동시 로그인
제한 강제
사용자가 어플리케이션에 복수의 현재 인증된 Session을 못 가지게 하십시오.
- 이것의 악의적인 사용자가 타당한 Session ID를 Hijacking 또는 추측하지
- 못하게 합니다.
상태 정보의
컨텐츠
타당성 입증
어플리케이션이 User ID를 세팅한 시간과 같은 상태 정보는 Client에게 보내
집니다. 따라서 이것은 조작될 수 있고 입력 값 타당화 또는 SQL 인젝션
공격을 위한 벡터로서 이용될 수 있습니다.
항상 들어오는 데이터를 체크하십시오.
체크섬 또는
메시지 인증
기술 이용
상태 정보가 변조되지 않았음을 증명하기 위해 체크섬을 이용하십시오.
- 복잡한 알고리즘일 필요는 없지만 체크섬은 사용자에 의해 다시 만들어
- 져서는 안됩니다. 예를 들어, 사용자 명에 대한 체크섬을 생성하기 위하여,
- 서버에 알려진 비밀 값에 더하여 사용자의 MD5 해시의 마지막 4바이트를
- 취할 수 있습니다.
SSL 이용 민감한 정보를 포함하는 트래픽은 스니핑 공격을 막기 하여 암호화되어야
합니다. (보다 자세한 내용은 뒤의 SSL 부분에서 다루도록 하겠습니다.)

4. 맺음말
웹에서의 보안을 말하기에 앞서서 준비 운동 격인 예습이었습니다. 다음 포스트에서는 Cookie와 Session의 취약점을 보완하는 안전한 개발 포인트를 좀 더 구체적으로 공부할 예정입니다. 아~ 재밌어요.


[Spring Framework ⑤] Spring에서 iBatis 연동하기

개발 노트 2008. 8. 4. 10:26 posted by 무병장수권력자


Persistance Support of Spring Framework

작성자 : 김문규
최초 작성일 : 2008. 8. 1

Spring에서 DB에 연결하는 방법에 대해서 알아보려 합니다. 다음과 같이 세가지 방법이 있습니다.
 - JDBC를 이용하는 방법
 - JdbcDaoSupport 클래스를 이용해서 JDBC를 조금 편하게 템플릿화하는 방법
 - SqlMapClientDaoSupport 클래스를 이용해서 iBatis Framework를 연동하는 방법

각 방법이 어떻게 다른지를 설명드리고 튜토리얼 수준의 예제를 보여드리겠습니다.

1. JDBC
일반적으로 JDBC를 이용할 경우 아래의 순서를 따라서 구현됩니다. 
 - DriverManager에 해당 DBMS Driver를 등록
 - 해당 Driver로 부터 Connection 객체 획득
 - Connection 객체로부터 Statement 객체 획득
 - Statement의 method를 이용하여 SQL실행
 - ResultSet 으로 받아서 처리(executeUpdate 의 경우엔 제외)
 - 객체 close() (ResultSet, Statement, Connection)

여기서 실제로 개발자의 비지니스 로직이 들어가는 부분은 4번과 5번의 일부입니다. 나머지는 음... 기계적인 코드입니다. 실제 코드를 예로 들면 아래와 같습니다.

Connection.java

.........
Connection con = null;
Statement st = null;
ResultSet rs = null;
 
try {
    con=DriverManager("jdbc:mysql://localhost/dbname","root","1234");  // dbname에는 사용하는 database 이름, root 계정, 패스워드는 1234

    Statement st=con.createStatement();
    ResultSet rs=st1.executeQuery("select * form names");
 
    if( rs.next() ) {
        do {
            // result set을 잘 정리합니다. 물론 일일이
            ...
            // 비지니스 로직을 수행합니다.
            ...
        } while( rs.next() )
    }
} catch (Exception ex) {
    // 적절한 예외 처리
} finally {
    if( rs != null) rs.close();
    if( st != null ) st.close();
    if( con != null ) conn.close();
}
.........

의외로 너무 많은 부분인 반복되는 느낌입니다. 이런 부분은 Spring을 사용하면 많이 줄어들게 됩니다. 다음절에서 확인해 보지요.

2. DaoSupport in Spring Framework
Spring에는 Template이라는 것을 이용해서 이 과정을 알아서 처리해 줍니다.
 - JdbcTemplate
 - NamedParameterJdbcTemplate
 - SimpleJdbcTemplate
 
이를 편하게 사용하기 위해서 주로 아래의 Dao 클래스를 이용합니다.
 - JdbcDaoSupport
 - NamedParameterJdbcDaoSupport
 - SimpleJdbcDaoSupport

여기서 가장 다양한 기능을 가진 SimpleJdbcDaoSupport 클래스의 사용법을 코드에서 확인해 보도록 하겠습니다. (전체 코드는 이전 4번 튜토리얼 분석 포스트에서 사용했던 예제를 보시면 됩니다.)

applicationContext.xml

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
 
<bean id="productDao" class="springapp.repository.JdbcProductDao">
    <property name="dataSource" ref="dataSource"/>
</bean>

ProductDao.java

public class JdbcProductDao extends SimpleJdbcDaoSupport implements ProductDao {
    public int selectCount() {
        return getSimpleJdbcTemplate().queryForInt(
                "select count(*) from products");
    }
}

음..확실히 간편해 진것 같습니다.

하지만, 쿼리문이 코드 내부에 하드코딩되어 있다는 점이 약간 아쉬운 부분입니다. 쿼리문 변경 시에 코드도 같이 변경되고 재컴파일도 되어야 합니다. (뭐 솔직히 컴파일 하면 되긴 해요... ^^) 그리고 따로 설명하지 않겠지만 ParameterizeRowMapper 인터페이스를 이용해서 domain 객체와 결과를 연결하는 방법이 있는데 이 역시 하드코딩 되기 때문에 유지 보수의 유연성이 떨어지는 면이 없지 않습니다.

그래서, 쿼리 및 쿼리의 결과와 객체간의 연결을 외부에서 따로 관리하는 기능을 요구하게 되고 이런 기능을 가진 iBatis가 최근 많이 사용되고 있습니다. 다음 절에서 iBatis의 연동에 대해 알아보겠습니다.
 
3. Spring Framework와 iBatis 연동
1) iBatis
국내 SI 현실에 가장 잘 어울린다고 평가받고 있는 persistance framework 입니다. 그 이유는 SQL 쿼리문을 그대로 사용하기 때문에 기존 JDBC 개발자들에게 거부감이 덜하고  경험적(?)인 시스템의 이해가 빠르기 때문일 겁니다. 여타의 ORM framwork는 배우기도 힘들고 또는 제 3자 입장에서 이해하기도 힘들어서 우리나라 SI 업계처럼 개발팀이 이합집산하는 문화에는 어울리지 않는다는 군요.

각설하고 간단한 예를 보도록 하지요. iBatis에 대해서는 제가 따로 설명하지 않을 것입니다. 아래의 자료들을 보시면 간단하게 이해하실 수 있을 겁니다. 그리고, googling 하시면 JPetStore라는 예제가 있습니다. 이를 한번 실행시켜 보시는 것도 도움이 될 것입니다.

다음은 iBatis 관련해서 많은 자료를 만드신 이동국님의 Tutorial 변역본입니다. 8장밖에 안되지만 iBatis의 동작에 대해서 이해하는데 많은 도움이 되실 것입니다.
별첨으로 하나 더 첨부합니다. 이 파일은 sqlMap의 사용법에 대해 설명된 문서이고 역시 이동국님이 번역하신 자료입니다.

자~! 이제 iBatis의 사용법에 대해서 간단히 감을 잡으셨나요?
앞 절에서 언급한 것처럼 제 생각에는 2가지의 큰 장점을 가진다고 생각됩니다. (다른 장점이 있으시면 사알짝 좀 알려주세요~~)
 - SQL 쿼리문이 외부 설정 파일에서 관리된다.
 - domain 객체와 SQL result set의 연결이 외부 설정 파일에서 관리된다.

그런데 JDBC와 마찬가지로 iBatis에도 단순하게 기계적으로 반복되는 코드가 있습니다. 바로 SqlMapClient를 선언하는 부분이지요! (아래 코드 참조)
public MyAppSqlConfig {
    private static final SqlMapClient sqlMap;
    static {
        try {
            String resource = “com/ibatis/example/sqlMap-config.xml”;
            Reader reader = Resources.getResourceAsReader (resource);
            sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
        } catch (Exception e) {
            .......
    }
}
 
JDBC를 지원하기 위해 JdbcDaoSupport 클래스가 있지요? 그럼 SqlMapClient를 지원해 주는 것은? 네! SqlMapClientDaoSupport 클래스 입니다. 그럼 드디어 sqlMapClientDaoSupport 클래스에 대해 알아보겠습니다.

2) sqlMapClientDaoSupport
앞서 알아본 JdbcDaoSupport와 이름도 비슷하지만 사용법도 매우 유사합니다. 설정 파일과 관련된 자바 코드를 보시지요.
applicationContext.xml - sqlMapConfig.xml - Product.xml 이 연쇄적인 관계를 가지고 있습니다. 여기서 applicationContext.xml은 spring 설정 파일이고 나머지는 iBatis 설정 파일입니다.
비지니스 로직 수행 중 iBatisMessageDao의 함수들이 요청될 것이고 이떄 Product.xml에 있는 쿼리문들을 호출해서 수행하게 됩니다.
주석문을 달고 색깔로 구분해 놓았습니다. 연관 관계에 유의하시면서 주의 깊게 확인하시길 바랍니다. (오랜만에 칼라풀한 포스트 입니다. ^^)

applicationContext.xml

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
</bean>

// sqlMapClient를 선언해야 합니다.
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
     <property name="dataSource" ref="dataSource" />
     <property name="configLocation" value="WEB-INF/sqlmap/sqlMapConfig.xml" />
</bean>

// DAO 입니다.
<bean id="productDao" class="springapp.repository.iBatisProductDao">
     <property name="sqlMapClient" ref="sqlMapClient" />
</bean>

<bean id="productManager" class="springapp.service.SimpleProductManager">
        <property name="productDao" ref="productDao" />
</bean>

sqlMapConfig.xml

// classpath가 root 디렉토리 임에 유의 하셔야 합니다.
<sqlMapConfig>
    <sqlMap resource="../sqlmap/Product.xml" />
</sqlMapConfig>

Product.xml

<sqlMap namespace="ProductNamespace">
    // Product 도메인 객체 입니다. 여기저기서 사용되게 됩니다.
    <typeAlias alias="Product" type="springapp.domain.Product" />

    <!-- getProductList -->
    // getProductList와 관련된 결과 값의 형태를 정의합니다.
    <resultMap id="getProductResultMap" class="Product">
        <result property="id" column="id" />
        <result property="description" column="description" />
        <result property="price" column="price" />
    </resultMap>
 
    <select id="getProductList" resultMap="getProductResultMap" resultClass="Product">
        select id, description, price from products
    </select>

    <!-- saveProduct -->
    // saveProduct와 관련된 입력 값의 형태를 정의합니다.
    <parameterMap id="saveProductParamMap" class="Product">
        <parameter property="id"  />
        <parameter property="description"  />
        <parameter property="price"  />
    </parameterMap>
 
    // parameter를 지정하는 방식에 유의 하시길 바랍니다.
    <update id="saveProduct" parameterClass="Product" >
        update products set description = (#description#), price = (#price#) where id = (#id#)
    </update>
</sqlMap>

iBatisMessageDao.java
 
// 코드 내부에는 전혀 쿼리 문이 없습니다!! 여기에 별 5개 꼭 확인하세요!
public class iBatisProductDao extends SqlMapClientDaoSupport implements ProductDao {
    @SuppressWarnings("unchecked")
    public List<Product> getProductList() {
        List<Product> products = getSqlMapClientTemplate().queryForList("getProductList");
        return products;
    }

    public void saveProduct(Product prod) {
        getSqlMapClientTemplate().update("saveProduct", prod);
    }
}

2절에서 설명한 JdbcDaoSupport 클래스의 사용법과 비교했을 때 iBatis는 이를 한단계 더 추상화 되어 있음을 알 수 있습니다. 모든 쿼리문과 해당 쿼리 결과와 객체간의 관계를 XML 외부 설정으로 따로 관리하고 있다는 것이죠.
그렇기 때문에, 앞에서 말씀드린데로 이 방법은 java 코드내에 하드코딩하는 것보다 개발의 유연성을 높이고 추후 관리시에 유리한 장점을 가집니다. (추상화란 처음에는 귀찮고 나중에는 편리한 것이지요!)

다음은 이전 4번째 spring 프레임워크 포스트에서 사용했던 튜토리얼을 iBatis로 연동시킨 예제입니다. 위에 설명드린 내용이 어떻게 적용되어 있는지 한번 더 확인하실 수 있을 것으로 생각됩니다.


4. 맺음말
휴..정말 긴 튜토리얼 리뷰였습니다. 매일 생각없이 JDBC로 개발하던 저에게는 참으로 재미난 것이 아닐 수 없었습니다.
물론 때에 따라서는 JDBC 자체가 빛나는 순간이 있겠지만, 대부분의 경우에는 iBatis가 우리를 편하게 해주지 않을까 생각됩니다. iBatis 관련 공부 중 이런 글이 있었습니다.
"iBatis는 80%의 JDBC 기능을 20%의 자바 코드로 구현한 간단한 프레임워크이다."
맞습니다. 이는 만병통치약이 아닙니다. 다만 대부분에 경우에 잘 먹히는 고마운 녀석인 것이지요. 뭐 종합감기약 정도 ^^;
그렇기 때문에 여러분도 한번 직접 경험해 보시고 개인적인 판단을 세우시길 바랍니다. 여러분에게 맞지 않을 수 있으니까요. 이상입니다. 감사합니다.

5. 참고자료
1) 웹 개발자를 위한 스프링 2.5 프로그래밍 (가메출판사, 최범균 지음)


[실전 security ①] 보안 개요

보안, 암호화 2008. 8. 1. 09:27 posted by 무병장수권력자


실전! 개발자를 위한 Security 체크 포인트
① 보안 개요


작성자 : 김문규
최초 작성일 : 2008. 8. 1
* 본 포스트는 SDS e-campus의 '실전 개발자를 위한 Security 체크포인트' 강의 내용을 발췌하여 재구성한 개인적인 학습노트 입니다.

1. 보안 요소
보안의 아래의 표와 같이 크게 5가지의 영역으로 분리됩니다.

신원증명과 인증
(Identification &
Authentication)
시스템에 대한 사용권한을 얻고자 하는 사용자의 신분을 확인하고자
하는 것입니다.
접근 제어
(Access Control)
자원에 접근할 수 있는 권한을 부여하고 통제하는 것입니다.
허가되지 않은 사용자의 위협으로부터 시스템의 자원을 보호하는데
목적이 있습니다.
기밀성
(Confidentiality)
전달 또는 보관되는 데이터 내용의 비밀성을 보장하는 것을 말합니다.
암호화는 암호 알고리즘에 의하여 암호화되고 복호화 됩니다.
무결성
(Integrity)
전달된 데이터가 중간에 왜곡되지 않음을 보장하는 것을 말합니다.
부인 봉쇄
(Non Repudiation)
송신자의 송신 정보에 대한 확인을 함으로써 송신 부인에 대응하는
체계를 말합니다.
이를 위한 방식의 하나로 전자서명이 있습니다.

2. 보안 분야
각 영역은 network /server / application / data 측면에서 아래의 표와 같은 보안 영역이 존재합니다. data는 표에 나타나 있지 않네요.
사용자 삽입 이미지

1) Server 보안
서버 자원에 대한 접근성에 보안을 말합니다.
인증  서버에 접근하는 사용자의 신원증명 및 인증실시
권한부여  접근이 허가된 자원에 대한 접근만을 허가 및 기타에 대한 통제
관리  사용자의 권한 및 인증에 대한 정기적인 Audit 실시
모니터링  시스템의 사용내역에 대한 실시간/주기적 모니터링 실시
분산된 서버들에 대한 인증 등의 보안정책을 일단의 통합된 환경에서 지원 감시 및 모니터링하는
시스템으로 구축/운영함
ex) 통합서버 보안관리, 통합인증시스템

2) Network 보안
네트워크를 통해서 외부에서 내부로의 접근에 대한 통제, 관리를 말합니다.
접근통제  인증되지 않은 사용자의 접근자체를 원천적으로 봉쇄/관리
감사와 추적  네트워크 사용 정보를 로깅해 두었다가 이를 추후 감사 및 사고
 발생시에 증거로써 활용
보안 관리  네트워크 보안에 대한 현황 파악 및 경향 분석이 가능하도록 하며
 시스템에 대한 가동 현황을 주기적으로 관리자에게 보고하는 기능을
 제공
 - Firewall
 - IDS (Intrusion Detection System)
 - Mail Monitoring System

3) Application 보안
서버 상의 각 애플리케이션에서 발생가능한 위협에 대한 보안을 말합니다.
비밀성의 유지  어플리케이션에서 처리되는 개인정보 또는 금융정보 등에
 대한 전송 및 처리 시에 암호화를 적용하여 비밀성을 유지
신규 위협요소에 대한
지속적인 대응
 갈수록 증가하는 새로운 해킹 기법에 대한 대응 체계를 정립
 하여 지속적인 보수 작업 실시
어플리케이션
취약성 제거
 어플리케이션 자체의 취약성으로 인하여 발생할 수 있는
 불법적인 접근을 차단하기 위하여 어플리케이션 개발시 보안
 취약성 제거 필수.
 - 사이버 뱅킹
 - 엑스트라넷 : 인트라넷의 사외 확장 시스템
 - EDI : 전자 데이터 교환
 - 전자 상거래

4) Data 보안
데이터 베이스에 대한 보안을 말합니다.
접근제어 데이터베이스는 사용자가 가진 접근 권한에 따라서 논리적으로 분리되어 있어 비인가자의 접근을 제어하기 위한 privilege를 설정함.
데이터베이스 관리자(Database Administrator : DBA)는 누가 어떤
부분의 데이터에 접근 가능하며, 어느 수준까지(예> 필드 수준인지
레코드 수준인지) 접근 가능한지, 그리고 어느 기능까지만 (예> 읽기/
쓰기/변경/삭제/추가 등의 기능) 허락할 것인지를 결정해야함
데이터 암호화 데이터 유출로 인한, 정보의 누출을 방지하기 위해 저장되는 정보의
암호화 지원
※ 데이터암호화 고려사항
    - 저장된 데이터의 보호
    - 전송되는 데이터의 보호
추론 통제 추론 통제란 간접적으로 노출된 데이터 노출을 통해 다른 데이터를
추론하여 다른 데이터가 공개되는 것을 방지하는 것
추론은 보통 통계적인 자료에서 많이 발생 가능하며, 추론 문제에 대한 완벽한 해결책은 존재하지 않습니다.
일반적으로 추론 통제는 세 가지 예방방법
- 허용 가능한 질의를 제한
- 질의의 응답으로 제공되는 데이터를 한정함
- 제공되는 데이터를 숫자의 경우 반올림하거나 일관성이 없는 질의
  결과 등을 제공하여 통계적 추론이 불가능하도록 함
흐름 통제 흐름 통제는 접근 가능한 객체들간의 정보 흐름을 조정함.
임의의 객체에 포함되어 있는 정보가 명시적으로 또는 암시적으로
보다 낮은 보호 수준의 객체로 이동하는 것을 검사하여 만약 정보가
보다 낮은 수준의 보호 객체로 이동한다면 사용자는 보안 위협이
발생하게 되므로 통제 메커니즘에서 이를 거부하여 보안을 유지함

5) 일반적 웹 서비스 시스템에 적용
아래의 그림에서 보면 F/W, IDS가 네트워크 보안을 위한 장비가 될 것이며, Web Server에 서버 보안, WAS에는 애플리케이션 보안, DB에는 데이터 보안 기술이 적용되어야 합니다.

사용자 삽입 이미지

3. 최근 웹 위험 기술
사용자 삽입 이미지

4. 맺음말
웹 개발에 대한 진입 장벽이 낮아졌습니다. 이미 개인이 홈페이지를 쉽게 구축하는 시대가 와 버렸습니다. 그래서, 단순히 jsp좀 짜는 데요.... 이건 흠.... 아닌거 같습니다.
최근 SSO 관련 모듈을 개발 하면서 공부도 할 겸 인터넷 강의를 듣게 되었습니다. 앞서 말씀드린데로 e-campus의 보안 강의입니다. 조금은 오래된 내용이기도 하지만 정리도 잘 되어 있고 개인적으로 많은 도움이 되고 있네요. 아마도 차근차근 배워두면 피가되고 살이 되지 않을까 생각됩니다. 사고쳐서 혼날일도 줄어 들테고요.
사용자 삽입 이미지




에러의 내용 입니다.
심각: Parse Fatal Error at line 10 column 6: The processing instruction target m
atching "[xX][mM][lL]" is not allowed.
org.xml.sax.SAXParseException: The processing instruction target matching "[xX][
mM][lL]" is not allowed.


무엇이 문제일까요? 아~ 삽질한 시간이 장난이 아닙니다.
이유는!
xml 문서는 <?xml version='1.0' encoding='utf-8'?>로 시작해야 합니다.
그런데, 그렇지 않기 때문입니다.
1) 눈에 보이지 않는 white space가 삽입되어 있을 가능성이 높습니다.
2) 물론 빈줄도 안됩니다.

눈에 보기에 이상이 없다면 다음 처럼 해보시면 됩니다.
1) 메모장에 해당 XML을 복사한 후
2) 메모장에 복사한 내용을 다시 복사합니다. (이 부분이 중요합니다. 다시 복사 해야 합니다.)
3) 그 다음 편집기에 붙여 넣어 보세요.

아마도 감쪽같이 에러가 사라질 겁니다.


C++ 클래스에서 C 라이브러리를 사용하는 예제

개발 노트 2008. 7. 29. 08:53 posted by 무병장수권력자


C++ 클래스에서 C 라이브러리를 사용하는 예제

작성자 : 김문규
최초 작성일 : 2007. 3.23

오픈 소스 기반으로 작업을 할 때, 종종 C 라이브러리를 C++에서 링크(link)해야 할 경우가 있습니다. 이럴 때 막상하려 하면 난감할 때가 있지요? ^^; (저만 그런가 봅니다.)

예제를 통해 알아보도록 하겠습니다.

<foo.h>
#ifdef __cplusplus
extern "C" {
#endif

int foo(char *name);

#ifdef __cplusplus
}
#endif

 

<foo.c>
int foo(char *name)
{
        printf("%sn", name);
        return 1;
}

 

<bar.cpp>
#include <iostream>
#include "foo.h"
using namespace std;

int main()
{
        foo("hello");
        return 0;
}


이제
compile을 해 볼까요?

[root@superman test]$ gcc -c foo.c
[root@superman test]$ g++ -o main bar.cpp foo.o
[root@superman test]$ ./main
hello

성공하셨나요? ^^
 



Google's Master Plan

Google 2008. 7. 24. 11:34 posted by 무병장수권력자


사용자 삽입 이미지

아래의 링크를 따라가면 고화질로 자세히 확인해 볼 수도 있다.
http://undergoogle.com/tools/GoogleMasterPlan.html

구글이 그들이 나아가야 할 방향으로 정했던 것들이다. 2006년까지 본사 1층에 개시되었다고 한다. 직원간의 공감대 확보를 위해.... (좋은 생각이라 생각된다. 내가 다니는 회사는 이런 모습이 크게 부족하다.)

이미 만명이 되어버린 회사이지만 탄력있게 움직이는 모습이 부럽다. 21세기 IT 기업의 자부심이 되어 주길 바란다.

'Google' 카테고리의 다른 글

시덥잖은 Google App Engine 튜토리얼  (0) 2008.08.21
Google App Engine 계정을 드디어 받았습니다.  (2) 2008.08.20
Google Code Jam  (0) 2008.07.09
Google App Engine Overview  (0) 2008.06.11
Google 사투리 번역 서비스 출시  (0) 2008.04.01


[Spring Framework ④] Spring Tutorial 따라하기

개발 노트 2008. 7. 21. 11:05 posted by 무병장수권력자


Developing a Spring Framework MVC application step-by-step

작성자 : 김문규
최초 작성일 : 2008.07.22

다음의 내용은 spring framework 공식 홈페이지(www.springframework.org)의 튜토리얼을 정리한 것입니다.
저와 같은 spring 초보자를 위해서 개인적인 방식으로 재구성하였습니다. 처음 spring을 접하는 분들이 학습에 참고 자료로 활용하시길 바랍니다.  

코드 자체의 세세한 부분은 다루지 않을 것입니다. spring 프레임워크을 이용해서 기본적인 웹 서비스를 구현하는 방법을 보여주는 것에 주력할 것입니다. 따라서, 이 글에서는 설정 파일의 작성에 대해서 중점적으로 논의하겠습니다.

(이 글은 기본적인 자바 웹 개발에 경험이 있는 분을 기준으로 작성합니다.)

1. Source Structure


사용자 삽입 이미지

튜토리얼치고는 소스와 설정파일이 많은 편입니다. 이는 Spring 자체가 MVC를 지원하는 프레임워크이고 설정 파일도 논리적으로 분리하는 것을 권장하기 때문입니다. 튜토리얼에서도 이 개념은 유지하고 있습니다. 이는 차차 설명하기로 합니다.

1) 소스 구조
 최상위 폴더는 아래와 같습니다.
┌ bin - 컴파일된 class 저장
├ db - DB와 관련된 스크립트
├ src - 말 그대로 소스들
└ war - WAS에 deploy될 것들
을 가리킵니다.

각각의 폴더에 대해 조금 더 자세히 알아보도록 하겠습니다. 조금 생소한 부분만 설명합니다. 너무 쉬운 부분은 넘어가도록 하겠습니다.

/src
springapp은 최상위 package이고 여기에 domain, repository, service, web이라는 하위 package가 존재합니다. 아래의 기준으로 클래스 모듈을 위치 시킵니다.
. domain - data 모델링 객체
. repository - DAO 과 관련된 객체
. service - 비지니스 로직
. web - web 프리젠테이션 관련 객체

□ /war
. /WEB-INF/tld/spring-form.tld
spring에서 사용할 수 있는 tag library의 정의입니다. tag library는 기존 jsp에서 사용하던 tag를 spring에서 재정의 한 것으로 좀 더 사용이 편합니다.
. /WEB-INF/*.xml
설정 파일들입니다. 실질적으로 spring을 사용함에 있어 가장 먼저 이해하여야 할 부분입니다. 뒤에서 자세히 설명하도록 하겠습니다.
























2. Configuration 관련
1) web.xml
  □ org.springframework.web.context.ContextLoaderListener
     . 계층별로 나눈 xml 설정파일을 web.xml에서 load되도록 등록할 때 사용.
     . 기본값으로 applicationContext.xml을 사용함
   예시)
   <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
   <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>
              /WEB-INF/mars-ibatis.xml
              /WEB-INF/mars-service.xml
         </param-value>
   </context-param>

  □ <taglib>
     . spring tag library의 위치 설정

2) applicationContext.xml
  □ ContextLoaderListener(또는 ContextLoaderServlet)가 ApplicationContext를 만들 때 사용

  □ ApplicationContext란, 웹에 독립적인 애플리케이션의 모든 영역(dao, service, manager, 기타 등등) 에 대한 정의를 말합니다.

  □ connection pool에 대한 정의
     . org.apache.commons.dbcp.BasicDataSource
        : datasource를 정의, db driver, 보안 정보등을 알림
     . org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
        : 읽어들일 property 파일에 대한 정보를 알림

  □ transaction에 대한 지원을 위한 한 방법
  이 부분은 나를 비롯한 spring 초보자의 입장에서 아직 이해하기 어려운 부분이기 때문에 아래의 코드가 AOP 기법을 활용하여 transaction을 지원하고 있다는 것만 알아두기로 하자.


3) springapp-servlet.xml
  □ DispatcherServlet이 WebApplicationContext를 만들 때 사용

  □ WebApplicationContext이란, 특정 웹(DispatcherServlet)에 종속되는 영역(Controller 및 각종 웹관련 설정 bean들)에 대한 정의를 말합니다. (ApplicationContext과의 차이를 확인하세요.)

  □ 주로 웹 페이지 리소스에 대한 핸들러 클래스 빈의 정의가 존재합니다.

  □ org.springframework.context.support.ResourceBundleMessageSource
     . message.properties 파일에 정의된 속성 값을 사용할 수 있도록 함
     . 국제화에 응용되면 아주 좋아 보입니다~

  □ org.springframework.web.servlet.view.InternalResourceViewResolver
     . prefix와 suffix 값의 정의에 따라 리소스 표현을 축약할 수 있도록 함.
     예시)
    <bean id="viewResolver"
     class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
          value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>       
    </bean>
     라고 선언하면 /WEB-INF/jsp/testfile.jsp은 비지니스 로직 내부에서 testfile로 간단하게 표현 가능 함



3. Inside Code
spring web service는 아래의 흐름을 가집니다.
①(사용자) jsp 호출
②(웹서버) 설정 검색
③(웹서버) 요청 처리 클래스 호출
④(웹서버) 비지니스 로직 수행
⑤(웹서버) view로 결과 반환
⑥(사용자) jsp 화면


1) Controller
  □ 사용자에게 jsp가 호출되면 xxxxx-servlet.xml에 정의된 클래스 빈을 호출합니다.

  □ 예제에는 DB에 있는 정보를 가져다가 저장하는 페이지와 원하는 값을 저장하는 페이지 두가지가 있습니다. hello.jsp가 전자에 해당하고 priceincrease.jsp는 후자에 해당합니다. 각 페이지를 확인하시고 각 페이지의 핸들러 클래스 빈을 springapp-servlet.xml에서 추적해 보시길 바랍니다.

  □ 일반적인 controller의 사용 예 : springapp.web.InventoryController.java
     . 일단 기본적인 Controller의 예시로 Controller interface를 구현합니다. 대부분의 경우에 사용하면 되고, request에 대한 처리를 위해 handleRequest()로 진입합니다.
     . 여기서 비지니스 로직을 처리한 후, ModelAndView 객체를 반환합니다. 이 때 넘기고자 하는 데이터를 파라미터에 담아서 보낼 수 있습니다.

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String now = (new java.util.Date()).toString();
        logger.info("returning hello view with " + now);
        Map<String, Object> myModel = new HashMap<String, Object>();
        myModel.put("now", now);
        myModel.put("products", this.productManager.getProducts());
        return new ModelAndView("hello", "model", myModel);
    }

  □ 폼을 처리하는 controller의 예 : springapp.web.PriceIncreaseFormController.java
     .  jsp가 폼을 다루고 있을 경우에는 SimpleFormController Class를 상속하여 확장합니다.
     . onSubmit()은 jsp에서 버튼이 눌려진 경우 콜백 지점을 가리키도 formBacjingObject는 폼에 기본값을 저장하고자 할 때 사용합니다.
     . formBackngObject는 domain에 존재하는 모델링 객체를 이용하고 있음에 주의합니다.

    public ModelAndView onSubmit(Object command)
            throws ServletException {
        int increase = ((PriceIncrease) command).getPercentage();
        logger.info("Increasing prices by " + increase + "%.");
        productManager.increasePrice(increase);
        logger.info("returning from PriceIncreaseForm view to " + getSuccessView());
        return new ModelAndView(new RedirectView(getSuccessView()));
    }
    protected Object formBackingObject(HttpServletRequest request) throws ServletException {
        PriceIncrease priceIncrease = new PriceIncrease();
        priceIncrease.setPercentage(20);
        return priceIncrease;
    }

2) Model
  □ 비지니스 로직을 수행 중에 데이터를 읽고 쓰고 수정하고 삭제하기 위해 데이터 베이스에 대한 접근을 수행합니다. 해당 예제는 HSQLDB를 사용하고 있으며 이를 JDBC로 연결하고 있습니다.

  □ JDBC와 관련하여 몇개의 클래스를 추가 지원하고 있지만 미미합니다. 실제로는 iBatis, Hibernate를 지원하고 있다는 것이 더 큰 특징이라 하겠습니다.

  □ 간단한 예제를 확인하시길 바라며, 이 부분은 설명하지 않겠습니다.

3) View
  □ 예제에서는 JSTL(Java Server page Standard Tag Library)이라는 것을 사용하고 있기에 약간의 공부가 필요합니다.
     . 예를 들면, <input type='text' /> 이렇게 사용하던 것을 <form:input path="percentage"/> 이런식으로 사용합니다.
     . iteration, print 같은 주요 제어문과 폼이 tag로 정리되어 있습니다.
     . 더 자세한 내용은 http://java.sun.com/products/jsp/jstl/ 참조 바랍니다.



4. Ending
이 문서의 목적은 spring을 자세하게 설명하는 것이 아니라, 튜토리얼데로 spring MVC를 간단하게 한번 만들어 보는 것에 그 의의를 두고 있습니다. 튜토리얼과의 차별화를 위해 Top-down 방식을 취했으며 전체의 구성을 설명하고자 했습니다.
저도 약 2주전부터 틈틈히 공부하면서 알게된 것을 정리한 것이라 부족한 면이 많습니다. 시간이 나는데로 잘못된 부분은 수정하고 필요한 내용은 추가하겠습니다.
긍정적이고 발전적인 커멘트를 기다립니다. 감사합니다.








LDAP (Lightweight Directory Access Protocol)

네트워크 2008. 7. 16. 18:27 posted by 무병장수권력자


LDAP (Lightweight Directory Access Protocol)

* 출처
1.
http://k.daum.net/qna/openknowledge/view.html?category_id=DBO001&qid=3H6VS&q=LDAP&srchid=NKS3H6VS
2. http://kin.naver.com/detail/detail.php?d1id=1&dir_id=105&eid=IzQRcMRKmek+I9YYIQrxgEvEMnAeSXO/&qb=TERBUA==&pid=fc2/2loi5TGsstuEU/lsss--062324&sid=SH2-2ra4fUgAABCmQOE

1. LDAP 이란
LDAP는 조직이나, 개체, 그리고 인터넷이나 기업 내의 인트라넷 등 네트웍 상에 있는 파일이나 장치들과 같은 자원 등의 위치를 찾을 수 있게 해주는 소프트웨어 프로토콜이다. LDAP는 DAP의 경량판(코드의 량이 적다는 의미임)이며, 네트웍 내의 디렉토리 서비스 표준인 X.500의 일부이다. LDAP는 초기 버전에 보안 기능이 포함되어 있지 않기 때문에 가볍다. LDAP는 미국 미시간 대학에서 유래되었으며, 적어도 40개 이상의 회사에 의해 뒷받침되어왔다. 넷스케이프는 자신들의 커뮤니케이터 최신판에 LDAP를 포함하였다. 마이크로소프트는 액티브 디렉토리라고 부르는 제품의 일부로서 LDAP를 포함하였다. 노벨 네트웨어 디렉토리 서비스는 LDAP와 상호 운영된다. 시스코 또한 자신들의 네트워킹 제품에서 LDAP를 지원한다.

네트웍에서, 디렉토리란 어떤 자원이 네트웍 상의 어디에 있는가를 알려준다. 인터넷을 포함한 TCP/IP 네트웍에서, DNS는 특정 네트웍 주소와 도메인 이름사이의 관계를 나타내는 디렉토리 시스템이다. 그러나, 때로는 도메인 이름 조차 모를 수 있는데, LDAP는 개체가 어디에 있는지 알지 못하더라도 그것을 검색할 수 있게 한다 (비록 추가정보가 있으면, 검색시 도움은 되겠지만).

LDAP 디렉토리는 아래에 나타낸 것처럼, 계층으로 구성되는 단순한 트리 구조이다.

  . 루트 디렉토리 (시작위치 또는 트리 구조의 근원), 각각 아래로 뻗어나간다
  . 국가들, 각각 아래로 뻗어나간다
  . 기관들, 각각 아래로 뻗어나간다
  . 기관별 단위 (부서 등), 각각은 아래로 뻗어나간다
  . 개체들 (사람, 파일, 및 프린터 등과 같은 공유자원들
 
LDAP 디렉토리는 많은 서버들 사이에 분포될 수 있다. 각 서버는 전체 디렉토리의 사본을 가질 수 있으며, 그 내용이 주기적으로 동기화된다. LDAP 서버는 DSAc(Directory System Agent)라고도 불린다. 사용자로부터 요청을 받는 LDAP 서버는 요청에 대한 책임을 지며, 필요하다면 그것을 다른 DSA들로 전달하지만, 사용자에게는 공동 작용을 통한 단일 응답을 보장한다.

2. LDAP의 활용 예
LDAP은 일반적으로 RDBMS에 비해서 검색 속도가 빠르다. 따라서, 검색 위주의 서비스인 경우에는 상당히 좋은 성능을 발휘할 수 있음. 예를 들면,
  . 사용자 로그인 처리(SSO)
  . 전화번호 조회
  . 회사 내에서의 부서 또는 직원 정보 조회
  . 도서관에서의 도서 정보 조회 등...
자주 변경되는 정보를 관리하는 것은 LDAP보다는 RDBMS를 사용하는 것이 좋다.

LDAP은 LDAP 서버 간의 데이터 복제가 실시간으로 잘 된다. 따라서, 원격지에서 관리되고 있는 정보들을 근거리의 LDAP 서버로 복제해서 사용하는 경우도 많이 있다. 예를 들면,
  . 국내 서버와 유럽, 미국 등의 서버 간의 내부 직원 정보나 계정 정보 등을 LDAP에서 각각 관리
  . 출장 시 로컬의 LDAP 정보를 실시간으로 복제하고 현지에서 해당 지역의 LDAP 서버를 이용

LDAP은 오픈된 프로토콜이다. TCP 389 포트를 사용하면서 외부에서 접속 가능하도록 구성하는 것이 기본!
  . 공인인증서
  공인인증서의 경우 해당 공인인증기관의 LDAP 서버에 게시되고 외부에서 인증서에 대한 유효성 검증을 하기 위해서 CRL(인증서취소목록)을 게시하고 이 CRL 정보를 아무데서나 획득하여 인증서를 검증할 수 있도록 함.

'네트워크' 카테고리의 다른 글

base64 인코딩 ,디코딩의 원리  (1) 2009.01.14
HTTP (Hyper-Text Transfer Protocol) 개요  (0) 2008.10.11
IPv6  (0) 2008.07.07
SNMP (Simple Netwok Management Protocol)  (0) 2008.07.07


Function Pointer란?

개발 노트 2008. 7. 14. 22:15 posted by 무병장수권력자


Function Pointer의 사용

작성자 : 김문규
최초 작성일 : 2008. 7.14

1. Function Pointer(함수 포인터)는 무엇일까요?

예제로 바로 보지요.

void func(int x)
{
  printf("x = %d\n",x);
}

main()
{
  int a = 10;
  int* b = &a;
 
void (*test)(int);
  test = func;
  func(a);
}


파란 색으로 두줄은 완전하게 동일한 것입니다.

C, C++에서는 포인터를 이용해서 메모리 영역을 직접 가리킬 수 있습니다. 일반 변수들이 그러한 것은 익히 잘 알고 있을 것입니다. 배열 역시 그러합니다.
예) int *a = 10; 여기서 a는 10이 저장된 실제 메모리의 위치를 가리킨다.
예) int a[10]; 여기서 a는 int가 저장되는 공간 10개가 배치된 메모리의 주소 위치를 가리킨다.

그렇다면, 함수는? 간단하게 생각하자면 함수는 배열과 매우 유사하다.
함수의 이름은 함수가 저장된 위치를 가리킵니다.
예) int (*func)(int); func는 int 변수, int 반환값을 가지는 함수가 저장된 주소 위치를 가리킵니다.

별거 없지요? ^^ 이상 함수 포인터의 개념이었습니다.

2. 그럼 언제 사용하는 걸까요?

과연 언제 사용하면 좋을까요? 오픈 소스를 많이 보면 쉽게 용례를 찾을 수 있지만 생각나는 것 하나만 공유하고자 합니다.

예를 들어보지요.
그래픽 라이브러리를 이용해서 그림을 그리는 프로그램을 가정하겠습니다. 이 프로그램은 다양한 그래픽 환경에 대응해야 한다는 조건을 가집니다. (mplayer와 같은 플레이어에서 다양하게 video out을 지원하는 경우를 생각해 보면 되겠습니다.)

이 때, 우리는 두가지의 구현 방식을 고민하게 됩니다. (더 있을 수도 있겠지요? ^^)

(코드는 의미로만 해석해주길....)

(1) 단순 통짜로!

paint.c
if(lib == "X11") X11paint();
else if (lib == "SDL" ) SDLPaint();
.......

(2) 조금 세련되게

paint.h
static vo_driver_t vo_drivers [ ] = {
#ifdef LIBVO_X11
    {"x11", X11paint},
#ifdef LIBVO_SDL
    {"sdl", SDLPaint},
........
}

paint.c
    paint();

load_vo.c
for (........) {
    if(library == vo_drivers[i].type) paint = vo_drivers[i].func;
}

차이는 뭘까요?
구현에 있어 계층화(layering) 이루어져 있는가 하는 것입니다. 계층화는 초심자에게 프로그램을 더욱 복잡한 것처럼 보이게 하지만 실은 유지 보수를 쉽게하고 개념적인 이해를 더욱 빠르게 도와줍니다. 관심의 대상을 잘게 분리할 수록 집중해야 하는 부분이 명확해지는 것은 당연하지 않을까요?

구현(1)은 새로운 driver가 추가 될 때마다 paint.c를 수정해야 합니다.
반면에, 구현(2)에서는 하위 계층의 구현이 아무리 바뀌거나 추가 되어도 paint.h만 바꾸면 됩니다.
 
paint.c를 이용해서 플레이어 스킨 UI를 개발하는 사람이 있고, X11Paint()를 개발하는 사람이 다르다면 (2)방식이 조금이나마 더 co-work이 쉬울 것입니다. 그렇겠지요? ^^;

앞서도 말했지만 꼭 이것이 함수 포인터를 사용하는 경우는 아닐 것입니다. 단지 하나의 경우임을 생각해 주길 바랍니다.

이상! 함수 포인터의 사용 예시 였습니다.



Javascript Object Oriented Programming

개발 노트 2008. 7. 14. 21:50 posted by 무병장수권력자


Javascript Object Oriented Programming

작성자 : 김문규
최초 작성일 : 2008. 7.14

일반적으로 자바스크립트는 쓰기에 더럽고 관리하기 너무 힘들다고 합니다.
그런데 아쉽게도 이런말은 서투른 목수가 연장 탓을 하는 것과 비슷하다고 생각됩니다.

저도 자바스크립트를 처음 배울 당시에 진정한 스파게티 코드를 만들어 낸적이 있고, 동료가 MK가 짠거는 숲속을 헤매이는 기분이야..라는 말도 들었었지요. ㅡ,.ㅡ 뭐 지금도 별반다르지 않을 수도 있지만...

그래서, 같이 잘 살아보자는 마음으로 일단은 자바스크립트를 사용하면서 꼭 알아야 할 것 하나를 소개합니다.

일반적으로 초보가 작성하는 자바스크립트 코드는 아래와 같습니다.
<script language='javascript'>
 var user1 = new Array();
 user1[0] = "김문규";
 user1[1] = 20;

 user1[1]++;

 alert(user1[1]);
</script>
user[0]은 이름, user[1]은 나이라는 것은 본인 밖에 모르겠네요.
직관적이지 않아서 관리가 쉽지 않게 됩니다.
(물론 이 보다는 좀더 나은 코드를 적을 수도 있겠지만 더 좋은 대비를 위함입니다.)

이제 좀 하는 놈의 코드는 어떨까요? (객제 지향을 이용한)
<script language='javascript'>
 function User() {
  this.name = "";
  this.age = 0;
  this.addAge = function() {
   this.age++;
   return;
  }
 }
 var user1 = new User();
 user1.name = "김문규";
 user1.age = 20;
 user1.addAge();
 alert(user1.age);
</script>

차이가 보이시나요?
변수명이 직관적이어서 이해가 쉽고, 다른 인스턴스를 추가할 수도 있어서 아주 쿨합니다.
관리도 쉽고 코드의 확장성도 훨씬 좋아 보입니다.

그럼 이제부터는 좀 하는 놈이 되어 보아요~