- 개인 키 보기

openssl x509 -inform der -in TestRSACertValid.cert -text

 

- 공인 인증키 보기

openssl x509 -inform pem -in TestRSACertValid.pem -text

 

 

Posted by '김용환'
,


.net 컴파일 도중 다음과 에러 발생시
     Error while trying to run project: Unable to start debugging.
     The Machine Debug Manager service is disabled

 

 

제어판 -> 관리도구 -> 서비스 선택 -> Machine Debug Manager service을 시작시킨다.

 

'c sharp' 카테고리의 다른 글

c#의 4가지 큰 특징  (0) 2005.06.14
Posted by '김용환'
,

http://testbed.gridcenter.or.kr/kor/technical_doc/globus/openssl_ca_usage.html

 

 

OpenSSL(SSLeay) Simple CA Usage

작성자: 김상완(sangwan@kisti.re.kr) 날짜: 2002-04-09 이 문서는 OpenSSL (또는 SSLeay) 패키지에 들어 있는 인증서 발급 및 관리 기능을 사용하는 방법을 설명한다. 목차 1. 최초의 CA를 만들기 2. CA인증서를 globus 인증서 디렉토리에 추가하기 3. 인증요청서에 서명하기 OpenSSL은 Eric Young 이라는 사람이 만든 SSLeay 라이브러리를 공개소스화 한 것으로써, 그 기능이나 구성에서 SSLeay와 거의 차이점이 없다. 2002년 4월 현재 OpenSSL 최신버젼은 0.9.6이다. OpenSSL(SSLeay)은 SSL(Secure Socket Layer)을 사용하는데 필요한 기능을 구현해 놓은 라이브러리이면서 동시에 그 라이브러리의 기능을 이용할 수 있는 컴맨드라인 명령어를 제공한다. OpenSSL의 컴맨드라인 명령어의 이름은 openssl이고, SSLeay의 경우는 ssleay이다. 이 문서에서는 편의상 OpenSSL 로 통일하여 사용하도록 한다. OpenSSL을 일반적인 소스 컴파일 과정에 의해 설치하면, 설치 디렉토리아래에 CA.sh 라는 스크립트가 존재하는데, 이것은 가장 간단한 CA(Certificate Authority) 의 기능을 수행할 수 있도록 해 주는 간단한 쉘 스크립트이다. 스크립트 내에서 openssl의 여러 가지 기능이 호출되어 사용된다. 따라서, openssl이 현재 쉘의 PATH 환경변수에 등록이 되어 있어야 한다. 1. 최초의 CA를 만들기 [[목차]] CA 기능을 사용하기 위해서는 최상위 CA를 만들어야 한다. 임의의 작업 디렉토리로 이동한다. # cd /path/to/any_temporatory_directory 또는 홈디렉토리에 CA라는 디렉토리를 만들어 사용한다. # cd ~ ; mkdir CA ; cd CA 설치 디렉토리의 openssl.cnf 화일이 환경 설정을 위한 목적으로 사용된다. 인증서 Subject 의 DN(Distinguished Name)을 정의 하는 부분도 포함되어 있다. # vi /usr/local/openssl/lib/openssl.cnf 새로운 CA를 만들려면 CA.sh 스크립트를 -newca 옵션을 주어 실행한다. # sh /usr/local/ssl/bin/CA.sh -newca CA certificate filename (or enter to create) ;(Press Enter to use default value) Making CA certificate ... ; openssl is called here as follow from CA.sh ; openssl req -new -x509 -keyout ./demoCA/private/./cakey.pem \ ; -out ./demoCA/./cacert.pem -days 365 Using configuration from /usr/local/ssl/lib/ssleay.cnf Generating a 1024 bit RSA private key ........++++++ ......................++++++ writing new private key to './demoCA/private/./cakey.pem' Enter PEM pass phrase: ; CA 비밀번호 Verifying password - Enter PEM pass phrase: ; CA 비밀번호 ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- ; CA's Information Country Name (2 letter code) [AU]:KR State or Province Name (full name) [Some-State]:STATE ;(null in Globus, enter '.') Locality Name (eg, city) []:LOC_NAME ;(null in Globus, enter '.') Organization Name (eg, company) [Internet Widgits Pty Ltd]:ORG_NAME ;(Globus) Organizational Unit Name (eg, section) []:OU ;(null in Globus, enter '.') Common Name (eg, YOUR name) []:CA_NAME ;(enter the CA's name) Email Address []:WHO@WHERE ;(null in Globus, enter '.') # openssl.cnf 화일에서 [req_distinguished_name] 부분에 DN을 구성할 정보들에 대한 설정을 할 수 있다. 프롬프트, 기본값, 최소, 최대값등으 설정할 수 있다. 자세한 것은 openssl.cnf 화일을 참조하기 바람. 이상 실행결과 CA의 키와 인증서가 생성된다. 현재 디렉토리에 demoCA라는 디렉토리가 만들어지고, 이 디렉토리 아래에 화일이 생성되어 있을 것이다. CA의 키화일은 demoCA/private/cakey.pem이고, CA의 인증서 화일은 demoCA/cacert.pem 이다. CA의 키 화일은 다른 사람이 볼 수 없도록 위 과정에서 입력한 비밀번호로 암호화 되어 있는데, cakey.pem 화일에서 -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,0F72CE690870F16D 부분이 키를 암호화 하는데 사용된 암호화 알고리즘에 대한 정보를 나타낸다. CA.sh -newca 명령은 내부적으로 다음과 같은 openssl 명령이 호출되어 수행되는데, # openssl req -new -x509 -keyout ./demoCA/private/cakey.pem \ -out ./demoCA/cacert.pem -days 365 openssl은 컴맨드라인 명령어이고, 'req'는 X.509 형식의 인증 요청서(Certificate Signing Request)를 관리하기 위한 openssl의 내부 명령어이다. CA 인증서는 CA 자기 자신의 인증요청서에 자신이 스스로 서명한 것이다. CA 인증서의 내용을 확인하려면, openssl x509 명령을 이용한다. -in 옵션 다음에 인증서화일의 화일명을 써 주면 된다. 다음에서 확인할 수 있듯이 Issuer와 Subject가 동일함을 알 수 있다. # ssleay x509 -in demoCA/cacert.pem -text Certificate: Data: Version: 1 (0x0) Serial Number: 0 (0x0) Signature Algorithm: md5WithRSAEncryption Issuer: C=KR, ST=STATE, L=LOC_NAME, O=ORG_NAME, OU=OU, CN=CA_NAME/Email= WHO@WHERE Validity Not Before: Feb 1 09:51:55 2002 GMT Not After : Feb 1 09:51:55 2003 GMT Subject: C=KR, ST=STATE, L=LOC_NAME, O=ORG_NAME, OU=OU, CN=CA_NAME/Email =WHO@WHERE Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:d4:6d:06:e6:c8:35:04:45:b1:97:c3:23:98:21: ... 28:5c:b2:e6:27:89:5b:11:a3 Exponent: 65537 (0x10001) Signature Algorithm: md5WithRSAEncryption 70:d4:29:d8:45:e2:7c:ac:61:46:2c:37:41:08:a1:64:ab:96: ... -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- # 2. CA인증서를 globus 인증서 디렉토리에 추가하기 [[목차]] CA인증서를 globus에 추가시키는 방법은 globus.org 의 다음 링크에 설명이 자세히 나와있으니 참조하기 바람. http://www.globus.org/Security/v1.1/adding_trusted_ca.html CA의 인증서는 CA의 공개키에 대한 정보를 포함하고 있으며, 아무에게나 공개될 수 있는 정보이다. demoCA 디렉토리아래의 cacert.pem 화일이 CA의 인증서 화일이다. 만일 자체적으로 CA를 운영한다면 이 화일을 여러 사람이 볼 수 있는 공개된 장소에 두어야 한다. 자체적으로 CA를 운영하지는 않지만, 다른 CA를 globus에 설치하려고 하는 경우는 CA로 부터 CA자신의 인증서를 얻어 와야 한다. 이렇게 얻어온 CA의 인증서를 cacert.pem 이라는 화일로 저장하자. 먼저 cacert.pem 화일의 해쉬(hash)값을 얻는다. # ssleay x509 -in demoCA/cacert.pem -hash -noout 4305cfde ; 이것이 해쉬 값이다. cacert.pem 화일을 /etc/globus/share/certificates/hash_value.0 화일로 복사한다. /opt/globus 는 globus deploy 경로이다. # cp cacert.pem /opt/globus/share/certificates/(hash_value).0 다음 ca-signing-policy.conf 화일을 편집한다. # vi /opt/globus/share/certificates/ca-signing-policy.conf #------------------------------------------------------------------------ # token type | def.authority | value #--------------|---------------|----------------------------------------- # EACL entry #1| access_id_CA X509 '/C=US/O=Globus/CN=Globus Certification Authority' pos_rights globus CA:sign cond_subjects globus '"/C=US/O=Globus/*" "/O=Grid/O=Globus/*"' # EACL entry #2| access_id_CA X509 '/C=KR/O=Globus/CN=KISTI Supercomputing Center CA' pos_rights globus CA:sign cond_subjects globus '"/C=KR/O=Globus/*" "/O=Grid/O=Globus/*"' # end of EACL 위에서 새로 추가된 부분이 강조되어 표시되었다. 그리고 밑줄친 부분은 방금 가져온 CA인증서의 Subject에 해당된다. 인증서의 Subject 명을 확인하려면 다음 명령을 사용한다. # openssl x509 -in hash_value.0 -text -noout 위의 강조된 부분에서 세번째 cond_subjects 로 시작하는 줄은 이 CA가 서명 할 수 있는 Subject들을 나타낸다. '/C=KR/O=Globus/' 또는 '/O=Grid/O=Globus/'로 시작되는 모든(*, 와일드 카드 문자) Subject에 대해서 '/C=KR/O=Globus/CN=KISTI Supercomputing Center CA' 라는 CA가 서명할 수 있음을 나타낸다. 만일 이 조건을 만족하지 않는 Subject를 가진 인증서에 이 CA가 발행(또는 서명)한 것으로 표시되어 있다면, 위의 규칙을 위반한 것이므로, 정상적인 인증서로 취급되지 않는다. 3. 인증요청서에 서명하기 [[목차]] 단계 1에서 demoCA 디렉토리가 있는 곳으로 이동한다. # cd /path/to/any_temporatory_directory 인증 요청서 부분을 newreq.pem 이라는 화일로 저장한다. # more newreq.pem -----BEGIN CERTIFICATE REQUEST----- MIIBhzCB8QIBADBIMQ0wCwYDVQQKEwRHcmlkMQ8wDQYDVQQKEwZHbG9idXMxFTAT BgNVBAsTDGhwY25ldC5uZS5rcjEPMA0GA1UEAxMGTXlVc2VyMIGfMA0GCSqGSIb3 ...(중략)... OXwjpooNitFPcg2o1TG7PHaJpy0fMmVe4m5gWhmH+fXIaBa2F2sqo5Drlw7voL/5 hLYPAWps6pwek9E= -----END CERTIFICATE REQUEST----- CA.sh 에 -sign 옵션을 주어 실행한다. # sh /usr/local/ssl/bin/CA.sh -sign Using configuration from /usr/local/ssl/lib/ssleay.cnf Enter PEM pass phrase: Check that the request matches the signature Signature ok The Subjects Distinguished Name is as follows organizationName :PRINTABLE:'Grid' organizationName :PRINTABLE:'Globus' commonName :PRINTABLE:'cluster.hpcnet.ne.kr' Certificate is to be certified until Sep 24 11:09:03 2002 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated issuer :/C=KR/O=Globus/CN=My Certificate Authority subject:/O=Grid/O=Globus/CN=cluster.hpcnet.ne.kr ... -----BEGIN CERTIFICATE----- MIICXzCCAcigAwIBAgIBATANBgkqhkiG9w0BAQQFADBBMQswCQYDVQQGEwJLUjEP ... ziZoNMbnBCl78hEo4Ph3VNoLPXosYIa9a6dv6+6ihgs9YYc= -----END CERTIFICATE----- 위에서 출력되는 것은 다음과 같다. 환경설정으로 이용되는 화일이 어떤 것인지 출력된다. 서명할 인증 요청서의 Subject 내용이 표시된다. CA를 생설할 때 입력하였던 암호를 입력하고 서명하겠느냐고 물어보는 질문에 yes를 해주면, 인증요청서에 대한 인증서가 만들어 진다. 만들어진 인증서는 현재 디렉토리의 newcert.pem이라는 화일로 저장된다. 만일 newcert.pem 이라는 화일이 이미 존재 한다면 내용을 덮어쓰게 된다. 자체적으로 CA를 운영하는 경우에는 이 인증서를 인증을 요청한 사람에게 전달하여 주면 된다.
Posted by '김용환'
,

j2me에서는 키를 처리할 수 있는 방법은 두가지이다.

Canvas 클래스에서 key 이벤트 처리가 가능하다.

  • keyPressed()
  • keyRepeated()
  • keyReleased()
  • pointerPressed()
  • pointerDragged()
  • pointerReleased()
  • getGameAction()
  •  

    이외, Command, CommandListener를 이용하여 키를 처리할 수 있다.

     

    Posted by '김용환'
    ,
    Article
    An Overview of the File Connection Optional Package
     


     

    New J2ME developers are often surprised to discover that the Connected Limited Device Configuration (CLDC) and the profiles based on it are not required to support the reading or writing of files. The Generic Connection Framework (GCF) defined by the CLDC does provide the basic scaffolding for file I/O, primarily through the InputConnection, OutputConnection, and StreamConnection interfaces, but it's up to specific implementations to expose this capability to applications. This limitation isn't a bad thing: It allows the CLDC to be ported to devices without a file system. (Such devices are more popular than you might think: devices running Palm OS, for example, do not support file systems in main memory, only on memory expansion cards.) If a file system is supported, however, it would be nice to have a standard way of using it through the GCF. This is the purpose of the File Connection Optional Package.

    The File Connection Optional Package (FCOP) is one of two optional packages defined by JSR 75 through the Java Community Process. The other, the PIM Optional Package, is discussed in another tech tip. Because the FCOP specification is still a draft standard and no reference implementation is yet available, the information presented here is still subject to change.

    If you're not familiar with optional packages, see the article "J2ME Optional Packages" for details on how they work. Simply put, an optional package is a set of programming interfaces that can be added to a J2ME profile or configuration to provide a category of functionality that some users of that configuration or profile will need but not all. FCOP can be supported on any J2ME platform, because it depends only on the core classes defined by the CLDC, and thus included in the Connected Device Configuration (CDC) as well.

    You can write applications that use FCOP in two ways. If all you want to do is read files, you can use the "file:" URL prefix to obtain an InputConnection interface to a file. For example:

    ... import javax.microedition.io.*; String url = "file:///data.txt"; InputConnection conn = null; int mode = Connector.READ_ONLY; try { conn =(InputConnection) Connector.open( url, mode ); } catch( IOException ioe ){ // no file } ...

    This code can be used on any platform that exposes the file system through the GCF, whether it supports FCOP or not. The Connected Device Configuration (CDC) and the profiles based on it all support this method of reading files, for example. Such a platform may also allow writing to files if you specify the Connector.READ_WRITE or Connector.WRITE_ONLY mode, returning a StreamConnection or an OutputConnection as appropriate.

    The second way to use FCOP is through the new FileConnection interface. Before doing so, however, an application should ensure that FCOP is available, by checking for the presence of the microedition.io.file.FileConnection.version property:

    ... // Check that the File Connection Optional Package is there String v = System.getProperty( "microedition.io.file.FileConnection.version" ); if( v != null ){ // FCOP available } else { // FCOP not available } ...

    The value of the property is the version number of FCOP, which for the first release is "1.0".

    When FCOP is supported, all GCF connections made using the "file:" protocol return an instance of javax.microedition.io.file.FileConnection. FileConnection extends StreamConnection by adding methods for file and directory manipulation. The added functionality is similar to that available in J2SE's java.io.File class. The general format for opening a file is a URL of the form:

    file://host/path

    This is the format defined in Section 3.10 of RFC 1738, the document that defines the general format of a URL. Devices are unlikely to support file access across a network, so in almost every case the URL will refer to the local host, and the host part of the URL is commonly omitted. What's left, then, is the path part, consisting of a root (identifying the root directory of a mounted file system) and a file or directory path. On a Windows platform, for example, a valid URL might be:

    file:///c:/Program Files/Windows NT/Pinball/table.bmp

    On a device with memory expansion slots the URL might look like this:

    file:///SDCard/users.txt

    Because the number and names of mounted file systems vary from device to device, a support class is provided that lets applications list the available file systems. This FileSystemRegistry class (defined in the javax.microedition.io.file package) also notifies interested applications whenever the user inserts or removes a memory expansion card from the device.

    The file URL passed to Connector.open() normally refers to an existing file or directory. For example, here's how to obtain the list of files in a directory:

    ... String url = "file:///SDCard"; FileConnection conn = null; try { conn = (FileConnection) Connector.open( url ); if( conn.isDirectory() ){ Enumeration names = conn.list(); while( names.hasMoreElements() ){ String name = (String) e.nextElement(); // do something } } else { // not a directory! } } catch( IOException e ){ // could not access the URL } catch( SecurityException e ){ // no permission to read the directory } ...

    The URL can also refer to files or directories that don't yet exist. You can create a file using FileConnection.create(), for example:

    ... String url = "file:///SDCard/myfile.txt"; FileConnection conn = null; try { conn = (FileConnection) Connector.open( url, Connector.WRITE_ONLY ); if( conn.create() ){ // create the file OutputStream out = conn.openOutputStream(); // now write data to the file } conn.close(); } catch( IOException e ){ // error } catch( SecurityException e ){ // no permission to create/write } ...

    Note that almost every method in the FileConnection class has the potential to throw a SecurityException. The FCOP specification does not define a specific security model for controlling access to the file system, leaving that task to the configuration or profile that incorporates FCOP.

    We've only touched on a few aspects of FCOP. For full details, check out the Javadoc for the FCOP classes.



    Back To Top

     

    출처 : http://developers.sun.com/techtopics/mobility/apis/ttips/fileconnection/

    'java UI' 카테고리의 다른 글

    jsp 2.0 사용시 예제  (0) 2009.01.01
    quartz 를 이용하기  (0) 2008.01.22
    [펌] DataSource의 복제를 통한 다중 플레이어 생성방법  (0) 2005.12.02
    jtable tutorial  (0) 2005.02.16
    The Eclipse runtime options  (0) 2005.02.15
    Posted by '김용환'
    ,

    See The JavaTM Virtual Machine Specification, 4.1 ClassFile.

    ================
    A class file contains a single ClassFile structure:

        ClassFile {
            (...cut...)
            u2 minor_version;
            u2 major_version;
            (...cut...)
        }

    The items in the ClassFile structure are as follows:

    (...cut...)
           minor_version, major_version

           The values of the minor_version and major_version items are the minor and major version numbers of the compiler that produced this class file. An
           implementation of the Java Virtual Machine normally supports class files having a given major version number and minor version numbers 0 through
           some particular minor_version.

           If an implementation of the Java Virtual Machine supports some range of minor version numbers and a class file of the same major version but a higher
           minor version is encountered, the Java Virtual Machine must not attempt to run the newer code. However, unless the major version number differs, it will
           be feasible to implement a new Java Virtual Machine that can run code of minor versions up to and including that of the newer code.

           A Java Virtual Machine must not attempt to run code with a different major version. A change of the major version number indicates a major
           incompatible change, one that requires a fundamentally different Java Virtual Machine.

           In Sun's Java Developer's Kit (JDK) 1.0.2 release, documented by this book, the value of major_version is 45. The value of minor_version is 3. Only
           Sun may define the meaning of new class file version numbers.

     

     

    http://www.kaffe.org/pipermail/kaffe/1999-March/088319.html

    Posted by '김용환'
    ,
    KSPICE Quality Academy에서는 9월 8, 9, 10 (3일), 10월 7, 8(2일)에 SPICE
    심사원 자격 교육을 실시합니다.
    본 교육은 SPICE 심사원 자격을 관리하는 국제 민간기구인 iNTACS
    (http://www.int-acs.org/) 규정에 따라 실시되며, 시험에 합격한분은 희망자에
    한해 iNTACS에 등록할 수 있습니다.
    교육은 ISO/IEC 15504 국제표준(IS version)에 따라 실시됩니다.

    세부사항은 아래와 같습니다. 교육시간표와 강사는 추후공지하겠습니다.

    1. 교육 세부사항

    (1) 교육일정 / 장소
    2005년 9월 8, 9, 10일 , 10월 7, 8일 (총 5일) 09:00- 17:00

    (2) 교육비 : 150만원
    단, ISO 9000 심사원, SEI Authorized 과정인 "Intriduction to CMMI"을
    수료자는 10% 할인 , 학생할인 50% 할인(단, Full-time에 학생에 한하여)

    (3) 교육장소 : 중앙대학교 창업보육센터 5층 중회의실


    2. 등록 일정 및 방법

    (1) 9월 4일 (일) 까지 수강료 납부
    납부 계좌 : (우리은행) 495-143426-13-001
    계좌명 : (사)한국소프트웨어 심사인 협회

    (2) * 등록방법 : E-mail 접수(webmaster@kaspa.org) 등록 기재사항 :
    성명/직급/소속/전화/E-mail/ 등록순서대로 선착순 30명 제한

    (3) 등록시 사전 알림사항
    - 1일 주차권(10,000원, 본인부담) 필요하신분께선 미리 알려주세요.

    - 세금계산서가 필요하신 분께선 등록하실 때 미리 알려주세요.
    (세금계산서 발행시 필요한 사항 : 기입날짜, 사업자등록번호, 업태, 업종 )


    기타 궁굼한 사항은 고려대학교 정호원 교수 (3290-1938), hwjung@korea.ac.kr
    문의 바랍니다.
    Posted by '김용환'
    ,

    X.509의 프로토콜 구조 및 동작 연구

     

    - 서론

    - PKI의 구성요소

    - PKI 기본구조의 구성 요소 및 상호 기능

    - PKI 프로토콜의 구격

    - X.509 PKI Topology Structure

    - X.509 인증서 발급 절차

    - 인증서 취소 목록

    - 참고문헌

    Posted by '김용환'
    ,

     
     
    ▶ 난이도중하
     
    MIDP가 모바일 디바이스에 있어서 훌륭한 플랫폼인 이유는 MIDP가 제공하는 보안에서 기인한다. MIDP의 보안 모델은 본래 Java 프로그래밍 모델에서 유래한 것으로서, MIDlet 코드가 가상머신 상에서 작동하므로 바이너리 코드상에 존재하는 위험한 오류를 피할 수 있는 기능이 있다. 잘못 쓰여진 코드나 악의적인 목적으로 작성된 코드는 디바이스를 고장낼 위험이 있다. 이러한 최악의 경우에는 잘못 작성된 Java 코드가 실행중인 Java 환경을 중지시켜 디바이스의 나머지 부분은 피해를 입지 않도록 보호된다.
    MIDP 2.0의 보안 지원은 JVM으로만 끝나는 것은 아니다. 여기서는 다른 종류의 MIDP 2.0 기능들이 어떻게 사용자와 디바이스를 악의적 소프트웨어로부터 보호하는지에 대해 설명한다. J2ME Wireless Toolkit 2.0(베타 2 이후 버전)을 사용해 MIDP 2.0 보안 아키텍처를 살펴본다.
     

    MIDP 2.0 스펙은 허가/거부 방식으로 퍼미션(Permissions)을 관리한다. 네트워크 커넥션을 만드려면 MIDlet에 필요한 퍼미션이 허가돼야 한다.

     
    예를 들어, MIDlet에서 HTTP 프로토콜을 통해 서버와 통신하고자 한다면 HTTP 커넥션에 대한 퍼미션이 열려야 한다. MIDP 2.0에 정의된 퍼미션은 네트워크 프로토콜에 대응되는 형태이지만, MIDP 아키텍처에서는 추가적인 API를 제공하고 있으므로 자신만의 퍼미션을 정의할 수도 있다.
    각각의 퍼미션은 고유의 이름이 정해져 있다. MIDP 2.0의 퍼미션 목록은 다음과 같다.
     
    * javax.microedition.io.Connector.http
    * javax.microedition.io.Connector.socket
    * javax.microedition.io.Connector.https
    * javax.microedition.io.Connector.ssl
    * javax.microedition.io.Connector.datagram
    * javax.microedition.io.Connector.serversocket
    * javax.microedition.io.Connector.datagramreceiver
    * javax.microedition.io.Connector.comm
    * javax.microedition.io.PushRegistry
     
    퍼미션명과 클래스명이 비슷해보이지만 실제로는 서로 다르다. 한 예로 javax.microedtion.io.Connector.https 퍼미션은 javax.microedtion.io.Connector 클래스를 사용해 HTTP 커넥션을 만드는 것을 관리한다.
    MIDlet은 코드 형태가 아닌, 보호 도메인(Protection Domain)을 통해 퍼미션을 획득한다. 그러나 먼저 코드 보안에 대해 설명하기에 앞서 간단한 코드를 살펴보기로 하자.
    다음의 간단한 MIDlet(이 글의 소스코드는 http://wireless. java.sun.com/midp/articles/permissions/src/HTTPMIDlet.zip에서 다운받을 수 있다.)은 HTTP 커넥션을 생성하고 서버 응답의 일부를 얻는다.
     
    import java.io.*;
    import javax.microedition.io.*;
    import javax.microedition.lcdui.*;
    import javax.microedition.midlet.*;
    public class HTTPMIDlet
    extends MIDlet
    implements CommandListener, Runnable {
    private Display mDisplay;
    private Form mMainScreen;

    public HTTPMIDlet() {
    mMainScreen = new Form(“HTTPMIDlet”);
    mMainScreen.append(
    “Press OK to create an HTTP connection.”);

    Command exitCommand =
    new Command(“Exit”, Command.EXIT, 0);
    Command okCommand =
    new Command(“OK”, Command.OK, 0);
    mMainScreen.addCommand(exitCommand);
    mMainScreen.addCommand(okCommand);
    mMainScreen.setCommandListener(this);
    }

    public void startApp() {
    if (mDisplay == null)
    mDisplay = Display.getDisplay(this);
    mDisplay.setCurrent(mMainScreen);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {}

    // CommandListener 메쏘드

    public void commandAction(Command c, Displayable s) {
    if (c.getCommandType() == Command.EXIT)
    notifyDestroyed();
    else if (c.getCommandType() == Command.BACK)
    mDisplay.setCurrent(mMainScreen);
    else if (c.getCommandType() == Command.OK) {
    // 대기 메시지 출력
    Form waitForm = new Form(“Connecting...”);
    mDisplay.setCurrent(waitForm);
    // 접속 시도
    Thread t = new Thread(this);
    t.start();
    }
    }

    // Runnable 메쏘드

    public void run() { String url = “http://wireless.java.sun.com/”;

    Form resultsForm = new Form(“Results”);
    Command backCommand =
    new Command(“Back”, Command.BACK, 0);
    resultsForm.addCommand(backCommand);
    resultsForm.setCommandListener(this);

    HttpConnection hc = null;
    InputStream in = null;

    try {
    // 서버에 접속한다
    hc = (HttpConnection)Connector.open(url);

    // 응답을 받아온다
    in = hc.openInputStream();

    int length = 256;
    byte[] raw = new byte[length];
    int readLength = in.read(raw);

    String message = new String(raw, 0, readLength);
    resultsForm.append(message);
    }
    catch (Exception e) {
    resultsForm.append(
    new StringItem(“Exception: “, e.toString()));
    }
    finally {
    if (in != null) {
    try { in.close(); }
    catch (IOException ioe) {}
    }
    if (hc != null) {
    try { hc.close(); }
    catch (IOException ioe) {}
    }
    }
    mDisplay.setCurrent(resultsForm);
    }
    }
     

    HTTPMIDlet의 run() 메쏘드는 서버에 접속해 필요한 데이터를 얻은 뒤, 이를 화면에 출력하는 형태로 구성돼 있다. 지금은 보안 도메인에 대해서 생각하지 말고 프로그램을 빌드한 뒤 HTTPMIDlet을 실행시켜보자. OK 명령을 선택해 프로그램이 접속을 시도하면, HTTPMIDlet은 Connector.open( ) 메쏘드를 호출한다. 만약 J2ME Wireless Toolkit(http://java.sun.com/products/j2mewtoolkit)을 사용하고 있다면 에뮬레이터가 퍼미션을 선택할 것을 요구한다(그림 1).
    이 시점에서 해당 접속에 대한 퍼미션을 허가하거나 거부할 수 있다. 퍼미션을 영구적으로 허가하거나 거부할 수도 있다. 그러나 영구적 허가는 뒤에 설명할 MIDlet 슈트 설치에서만 의미가 있다. 만약 접속을 허가하면 애플리케이션이 정상적으로 작동된다. MIDlet은 HTTP 커넥션을 통해 얻은 데이터를 출력한다(그림 2).
    반면 뭔가 좋지 않은 기분이 들어 커넥션을 거부한다면 Connector. open( )은 SecurityException을 던지게 된다. HTTPMIDlet은 이 예외를 잡아 예외에 대한 설명 메시지를 출력한다. MIDlet은 네트워크 접속으로부터 발생하는 모든 종류의 SecurityException을 잡아서 처리토록 해야 한다(그림 3).
    에뮬레이터는 HTTP 커넥션이 성립될 때 사용자에게 퍼미션 허가를 요구해야 한다는 사실을 어떻게 아는가? 왜 퍼미션이 자동적으로 허가되거나 거부되지 않는가? 이는 HTTPMIDlet을 담고 있는 보호 도메인과 관련돼 있다.
     
    보호 도메인은 다음과 같은 두 부분으로 구성된다.
     
    - 허가된 퍼미션(MIDlet 슈트 내부에 부여됨)과 사용자에게 물어봐야 하는 퍼미션
    - 보호 도메인 허가에 대한 기준
     
    J2ME Wireless Toolkit의 ‘Run’ 버튼을 누르면, 현재 MIDlet 슈트는 Untrusted라는 보호 도메인 내에서 실행된다. 이 도메인 안에서 사용자에게 모든 퍼미션을 물어야 한다. HTTPMIDlet이 HTTP 커넥션을 얻고자 시도할 때 에뮬레이터가 퍼미션 허가 여부를 물어본 이유가 바로 이것이다.
    MIDlet 슈트의 실행시간 보호 도메인은 Edit>Preferences를 선택한 뒤 Security 탭을 통해 변경할 수 있다(그림 4).
    J2ME Wireless Toolkit에는 네 개의 보안 도메인이 있다. Minimum과 Untrusted, Trusted, Maximum 도메인이 그것들이다. Minimum 도메인 내의 MIDlet은 모든 퍼미션을 거부한다. Untrusted 도메인은 모든 퍼미션에 대해 허가 여부를 물어본다. Trusted 도메인은 MIDlet 보안의 열반상태로 표현되며, 모든 퍼미션이 허락된다. Maximum 도메인은 Trusted 도메인과 동일하다.
    Minimum 도메인을 선택하고 HTTPMIDlet을 다시 실행해보자. 이제 OK 버튼을 선택해 접속을 시도하면 즉시 퍼미션이 거부되며, HTTPMIDlet은 SecurityException을 보여준다.
    J2ME Wireless Toolkit의 보안 도메인은 보안 도메인을 구현하는 한 가지 방법일 뿐이다. 제조업자와 통신업자, 다른 MIDP 구현자들은 각자의 목적에 맞는 도메인을 직접 만들 수 있다.
     
    보호 도메인은 allowed 퍼미션과 user 퍼미션을 갖는다. user 퍼미션을 선택하면 사용자에게 퍼미션 허가 여부를 묻는다. user 퍼미션은 세 가지 형태의 변형(스펙에는 이를 ‘상호작용 모드’라고 지칭하고 있다.)이 있다. MIDlet이 퍼미션을 요구하는 최초의 시점에서, 구현에 따라 사용자에게 퍼미션의 허가 또는 거부를 묻는다. 세 가지 형태의 모드는 구현에 있어서 사용자가 선택한 퍼미션 허가 여부를 얼마나 기억하고 있어야 하는지를 나타낸다.
    oneshot 퍼미션의 경우, MIDP 구현은 사용자 선택을 전혀 기억하지 않으며, 퍼미션 허가가 필요할 때마다 매번 사용자에게 허가 여부를 묻는다. session 퍼미션의 경우, 구현은 MIDlet 종료시까지 사용자의 선택을 기억한다. 끝으로 blanket 퍼미션에서는 사용자의 선택이 MIDlet 슈트의 언인스톨 시점까지 계속적으로 유효하다.
    보호 도메인은 사용자가 명시적으로 허가하지 않은 권한에 대해서는 반드시 거부해야 한다. 예를 들어 HTTPOnly 보호 도메인이 다음과 같은 단일 퍼미션만을 포함하고 있다고 하자.

    allow: javax.microedition.io.Connector.http

    이 도메인은 명시된 퍼미션 이외에 대해서는 모두 거부한다. 퍼미션을 좀더 느슨하게 정의하고 싶다면, 다른 종류의 퍼미션에 대해서는 사용자가 선택하도록 다음과 같이 지정할 수 있다.

    allow: javax.microedition.io.Connector.http
    blanket: javax.microedition.io.Connector.https
    blanket: javax.microedition.io.Connector.socket


    이 경우, HTTP와 소켓 접속에 대해서는 사용자가 퍼미션 허가 여부를 결정해야 한다.
    보호 도메인의 정의와 설정은 MIDP 구현의 영역임을 기억하자. 애플리케이션 개발자로서 MIDP 2.0 스펙에 의해 정의된 보안 아키텍처에서 효과적으로 작업하는 것은 개발자의 몫이다.
     
    JAD 내의 특별한 속성은 MIDlet 슈트가 특정 퍼미션에서의 의존성을 표시하는 데 사용된다. 이 속성들을 사용해 ‘이 MIDlet 슈트는 HTTP 접속을 필요로 하며, 소켓 접속을 필요로 할 수도 있다’고 명시할 수 있다. 이 경우에는 디스크립터 내의 속성을 다음과 같이 작성할 수 있다.

    MIDlet-Permissions: javax.microedition.io.Connector.http
    MIDlet-Permissions-opt: javax.microedition.io.Connector.socket


    다행히도 이 속성들을 수작업으로 추가할 필요는 없다. J2ME Wireless Toolkit 2.0은 속성을 쉽게 추가할 수 있도록 도와준다. 즉 Settings...을 클릭한 뒤에 Permissions 탭을 선택한다. 그런 다음 필요한 퍼미션과 선택적 퍼미션들을 추가한다. 툴킷은 이 퍼미션들을 MIDlet 슈트 JAD 내에 자동으로 추가한다.
    필요한 퍼미션과 선택적 퍼미션을 JAD에 넣을 때 얻을 수 있는 이점은 무엇인가? JAD는 MIDlet 슈트가 특정 동작을 시도할 것을 인스톨 시점에서 디바이스에게 알릴 수 있는 편리한 기능을 갖고 있다. 만약 디바이스가 MIDlet 슈트가 요청하는 몇 개의 퍼미션을 허가하지 않는 보호 도메인 내에 MIDlet을 인스톨하려고 하면 인스톨에 실패한다. 이러한 메커니즘이 없다면 사용자는 MIDlet 슈트를 설치한 뒤에야 해당 MIDlet 슈트가 정상적으로 동작하지 않음을 알게 된다.
     

    지금부터 보호 도메인의 측면은 어떻게 MIDlet 슈트가 도메인 내에 진입하는지에 대한 설명이다.
    다운받은 코드는 상당히 위험하다. 특히 코드 작성자를 모르거나 코드가 어디에서 온 것인지를 모른다면 더욱 그렇다. 비록 가상머신 상에서 실행중인 MIDlet이 바이너리 코드보다는 안전하기는 하지만, 여전히 위험은 존재한다. 다운받은 MIDlet은 인가되지 않은 네트워크 커넥션을 만들 수 있으며, 이 커넥션들은 사용자 메모리를 사용한다. 악의적인 MIDlet은 사용자 정보를 수집하고, 이를 서버에 전송해 악의적인 목적으로 사용할 수 있다. MIDP 디바이스는 사용자에게 게임과 애플리케이션과 같은 다양한 선택 사항을 제공하는 유연성을 제공하지만, 이 유연성으로 인해 출처와 의도가 의심스러운 코드를 실행할 위험에 빠지게 만들기도 한다.

    사용자가 다운받은 MIDlet을 실행하는 데 있어서 좀더 안전하게끔 보호 도메인을 설정할 수 있다. MIDP 스펙에는 어떻게 보호 도메인이 규정되는지에 대해서는 매우 모호하게 정의되어 있다. 많은 부분이 구현자의 자유재량에 맡긴다. 이러한 영역에는 보호 도메인의 개수와 보호 도메인에 대한 정의 같은 부분이 포함된다. 그러나 스펙에서는 암호화된 서명과 인증서에 기반한 보호 도메인 개념을 제시하고 있다. 이 개념은 통신업자나 소프트웨어 개발자가 싸이닝 키 조합을 생성하고 인정받은 인증기관으로부터 인증서를 획득하도록 하는 것이다. 통신업자나 개발자는 MIDlet 슈트 JAR의 서명을 계산하고, 서명과 인증을 애플리케이션 디스크립터에 저장한다.

    싸인된 MIDlet 슈트는 사용자에게 MIDlet 슈트가 변경되지 않았으며 식별 가능한(따라서 법적 의무를 지는) 원천으로부터 온 것임을 증명한다. 디바이스 상의 MIDP 구현은 디스크립터의 서명을 검사함으로써 사용자의 신원을 검증한다. 개발자의 공개키를 사용하면 MIDP 슈트 자체의 무결성을 검증할 수 있다.

    J2ME Wireless Toolkit 2.0 버전에는 키와 MIDlet 슈트의 싸이닝을 편리하게 관리해주는 툴이 포함되어 있다. 예를 들어 HTTPMIDlet 프로젝트를 서명하는 경우를 가정해보자. Project>Package>Create Package를 통해 MIDlet 슈트를 패키징한 뒤, Project>Sign을 사용해 싸이닝할 수 있다(그림 5).

    이 윈도우에는 툴킷에게 알려진 모든 싸이닝 키 조합이 나타난다. Java keystore에 생성해둔 키 조합을 사용해 MIDlet 슈트를 싸인하고 싶다면, J2ME Wireless Toolkit의 Import Key Pair를 사용해 키 조합을 가져오면 된다.
    싸이닝에 사용할 새로운 키 조합을 생성하고 싶은 경우에는 New Key Pair를 클릭한다. 키명(key alias), 도메인명(domain name), 회사명(company name)을 적절한 값으로 채운다(그림 6).

    툴킷은 새로운 키 조합을 생성하고 이를 사용 가능한 싸이닝 키 조합 목록에 표시한다. 이 시점에서 툴킷은 해당 키 조합을 어떤 보호 도메인과 연관시킬 것인가를 묻는다. 에뮬레이터는 이때 선택한 보호 도메인 내에 MIDlet을 설치하게 된다. 이 예에서는 Trusted를 선택한다(그림 7).

    키 조합을 생성하고 보호 도메인을 선택했으면, MIDlet 슈트를 싸이닝하는 방법은 매우 간단하다. 사용할 키 조합의 명칭을 선택하고 Sign MIDlet Suite를 클릭한다. 만약 File>Utilities를 통해 Sign MIDlet Suite 윈도우를 띄웠다면, 툴킷은 싸인할 MIDlet 슈트의 디스크립터 위치를 물을 것이다. 만약 HTTPMIDlet 프로젝트를 사용하는 경우라면 디스크립터는 J2ME Wireless Toolkit 디렉토리 내의 apps/HTTPMIDlet/bin/HTTPMIDlet.jad가 될 것이다. Project>Sign을 KToolbar 메뉴로부터 선택했다면, 툴킷은 현재 활성화된 프로젝터의 디스크립터를 사용한다.
    MIDlet 슈트의 싸이닝이 끝나면 툴킷이 이를 알리는 메시지를 띄운다. 만약 싸이닝 여부를 확인하고 싶다면 디스크립터를 텍스트 편집기로 열어본다. 두 개의 새로운 속성인 MIDlet-Certificate-1-1과 MIDlet-Jar-RSA-SHA1가 추가되어 있을 것이다. 이 두 속성은 모두 바이너리 데이터를 텍스트로 인코딩하는 데 사용되는 base64 형태로 저장된다.
    싸인된 MIDlet 슈트를 생성한 뒤에는 무엇을 해야 할까? J2ME Wireless Toolkit을 사용해, MIDlet 슈트를 에뮬레이터에 설치하고 올바른 보호 도메인 상에서 작동되는지를 확인해본다. 모든 MIDP 구현(툴킷 에뮬레이터 포함)에는 MIDlet과 MIDlet 슈트를 관리하는 애플리케이션 관리 소프트웨어(AMS. Application Management Software)가 포함되어 있다. MIDlet 슈트의 인스톨과 실행, MIDlet 실행 종료 후의 정리는 모두 AMS가 관리한다(혹시 MIDlet 내의 startApp()를 누가 호출하는지에 대해 궁금한 적이 있는가? 바로 AMS가 호출한다.).
    툴킷 에뮬레이터에는 OTA(Over The Air) 프로비저닝을 처리할 수 있는 AMS가 포함되어 있다. 에뮬레이터의 AMS가 MIDlet 슈트 디스크립터에 대한 링크를 포함하고 있는 웹 페이지를 가리키도록 하자. 그러면 AMS는 MIDP 스펙에 정의되어 있는 OTA 프로토콜을 사용해 MIDlet 슈트를 다운받은 후 설치한다.
    다행히도 이 기능을 사용하기 위해 직접 서버를 셋업할 필요는 없다. J2ME Wireless Toolkit 2.0(베타 2 또는 그 이상의 버전)에는 OTA 서버 에뮬레이션이 포함되어 있어 싸인된 MIDlet 슈트의 OTA 설치를 쉽게 테스트해볼 수 있다.

    MIDlet 슈트를 패키징 및 싸이닝 했다고 가정하고 Project>Run via OTA를 KToolbar 메뉴로부터 선택한다. 에뮬레이터가 나타나고 AMS 로고 화면이 나타난다(그림 8).
    Apps를 선택해 설치된 MIDlet 슈트의 목록을 표시한다(그림 9).
    싸이닝을 마친 MIDlet 슈트를 설치하기 위해 Install Application을 선택하고 select 버튼을 클릭한다. AMS는 URL을 요청한다. 그러나 로컬 OTA 서버의 주소가 자동으로 입력될 것이다(그림 10).
    이제 Go 명령을 선택한다. AMS는 툴킷의 OTA 서버에 접속하고, 설치할 MIDlet 슈트를 선택할 것을 요청한다(그림 11). 하나의 애플리케이션만 나타날 것이다.
    Install을 선택해 설치를 시작한다. AMS는 MIDlet 슈트에 대한 몇 가지 기본 정보를 보여주고 계속 설치할지 여부를 묻는다(그림 12).

    Install을 다시 한번 선택하면, AMS는 MIDlet 슈트를 설치하고 이를 실행가능한 MIDlet 슈트 목록에 추가한다. HTTPMIDlet 예를 실행하면, 에뮬레이터가 퍼미션을 묻지 않고도 HTTP 커넥션이 연결됨을 확인할 수 있다. 어떻게 이런 일이 가능한가? 이는 키 조합을 생성할 때, 해당 키 조합을 Trusted 보호 도메인과 연관시켜 두었기 때문이다. 에뮬레이터는 Run via OTA를 사용할 때 MIDlet 슈트를 Trusted 도메인 내에 설치했다. 따라서 HTTPMIDlet이 HTTP 커넥션을 시도할 때, Trusted 보호 도메인으로부터 퍼미션을 얻을 수 있는 것이다.
     
     
    지금까지 MIDP 디바이스 상의 보안 아키텍처에 대한 의미와 MIDP 2.0에서 보호하고 있는 네트워크 동작에 대해 살펴보았다. J2ME Wireless Toolkit은 MIDlet이 필요로 하는 퍼미션을 쉽게 선택할 수 있도록 도와준다. MIDlet은 보호 도메인이라는 장소 안에 증명서(credentials)에 따라서 정렬되어 저장된다. 보호 도메인은 퍼미션의 집합과 도메인 내 입장에 필요한 기준의 집합이다. MIDP 2.0 스펙에는 MIDlet 슈트를 암호화 싸이닝하는 방법을 포함하고 있다. 이 방법은 J2ME Wireless Toolkit에 포함되어 있으며, 이 툴에는 키 조합과 MIDlet 슈트 싸이닝에 필요한 간단한 방법을 제공한다. 끝으로 툴킷의 Run via OTA 기능을 사용해 싸이닝한 MIDlet 슈트의 설치를 쉽게 테스트해볼 수 있다.
    MIDP 2.0의 보안 아키텍처는 유연한 동시에 강력하다. J2ME Wireless Toolkit을 사용하면 새로운 보안 아키텍처를 이용해 사용자가 보다 안전하게 실행할 수 있는 소프트웨어를 개발할 수 있다.
     

     

    'j2me' 카테고리의 다른 글

    JVM 관련 이메일 보냄  (0) 2006.03.21
    j2me상에서의 키 핸들링 방법  (0) 2006.02.28
    Java on PocketPC, the Unofficial FAQ  (0) 2006.02.07
    노키아의 MIDP System Properties  (0) 2006.02.03
    J2me properties  (0) 2006.02.03
    Posted by '김용환'
    ,

    출처 http://slacksite.com/other/ftp.html

    Active FTP vs. Passive FTP, a Definitive Explanation

    Contents:


    Introduction

    One of the most commonly seen questions when dealing with firewalls and other Internet connectivity issues is the difference between active and passive FTP and how best to support either or both of them. Hopefully the following text will help to clear up some of the confusion over how to support FTP in a firewalled environment.

    This may not be the definitive explanation, as the title claims, however, I've heard enough good feedback and seen this document linked in enough places to know that quite a few people have found it to be useful. I am always looking for ways to improve things though, and if you find something that is not quite clear or needs more explanation, please let me know! Recent additions to this document include the examples of both active and passive command line FTP sessions. These session examples should help make things a bit clearer. They also provide a nice picture into what goes on behind the scenes during an FTP session. Now, on to the information...


    The Basics

    FTP is a TCP based service exclusively. There is no UDP component to FTP. FTP is an unusual service in that it utilizes two ports, a 'data' port and a 'command' port (also known as the control port). Traditionally these are port 21 for the command port and port 20 for the data port. The confusion begins however, when we find that depending on the mode, the data port is not always on port 20.


    Active FTP

    In active mode FTP the client connects from a random unprivileged port (N > 1023) to the FTP server's command port, port 21. Then, the client starts listening to port N+1 and sends the FTP command PORT N+1 to the FTP server. The server will then connect back to the client's specified data port from its local data port, which is port 20.

    From the server-side firewall's standpoint, to support active mode FTP the following communication channels need to be opened:

    • FTP server's port 21 from anywhere (Client initiates connection)
    • FTP server's port 21 to ports > 1023 (Server responds to client's control port)
    • FTP server's port 20 to ports > 1023 (Server initiates data connection to client's data port)
    • FTP server's port 20 from ports > 1023 (Client sends ACKs to server's data port)

    When drawn out, the connection appears as follows:

    In step 1, the client's command port contacts the server's command port and sends the command PORT 1027. The server then sends an ACK back to the client's command port in step 2. In step 3 the server initiates a connection on its local data port to the data port the client specified earlier. Finally, the client sends an ACK back as shown in step 4.

    The main problem with active mode FTP actually falls on the client side. The FTP client doesn't make the actual connection to the data port of the server--it simply tells the server what port it is listening on and the server connects back to the specified port on the client. From the client side firewall this appears to be an outside system initiating a connection to an internal client--something that is usually blocked.


    Active FTP Example

    Below is an actual example of an active FTP session. The only things that have been changed are the server names, IP addresses, and user names. In this example an FTP session is initiated from testbox1.slacksite.com (192.168.150.80), a linux box running the standard FTP command line client, to testbox2.slacksite.com (192.168.150.90), a linux box running ProFTPd 1.2.2RC2. The debugging (-d) flag is used with the FTP client to show what is going on behind the scenes. Everything in red is the debugging output which shows the actual FTP commands being sent to the server and the responses generated from those commands. Normal server output is shown in black, and user input is in bold.

    There are a few interesting things to consider about this dialog. Notice that when the PORT command is issued, it specifies a port on the client (192.168.150.80) system, rather than the server. We will see the opposite behavior when we use passive FTP. While we are on the subject, a quick note about the format of the PORT command. As you can see in the example below it is formatted as a series of six numbers separated by commas. The first four octets are the IP address while the last two octets comprise the port that will be used for the data connection. To find the actual port multiply the fifth octet by 256 and then add the sixth octet to the total. Thus in the example below the port number is ( (14*256) + 178), or 3762. A quick check with netstat should confirm this information.

    testbox1: {/home/p-t/slacker/public_html} % ftp -d testbox2
    Connected to testbox2.slacksite.com.
    220 testbox2.slacksite.com FTP server ready.
    Name (testbox2:slacker): slacker
    ---> USER slacker
    331 Password required for slacker.
    Password: TmpPass
    ---> PASS XXXX
    230 User slacker logged in.
    ---> SYST
    215 UNIX Type: L8
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp> ls
    ftp: setsockopt (ignored): Permission denied
    ---> PORT 192,168,150,80,14,178
    200 PORT command successful.
    ---> LIST
    150 Opening ASCII mode data connection for file list.
    drwx------   3 slacker    users         104 Jul 27 01:45 public_html
    226 Transfer complete.
    ftp> quit
    ---> QUIT
    221 Goodbye.
    

    Passive FTP

    In order to resolve the issue of the server initiating the connection to the client a different method for FTP connections was developed. This was known as passive mode, or PASV, after the command used by the client to tell the server it is in passive mode.

    In passive mode FTP the client initiates both connections to the server, solving the problem of firewalls filtering the incoming data port connection to the client from the server. When opening an FTP connection, the client opens two random unprivileged ports locally (N > 1023 and N+1). The first port contacts the server on port 21, but instead of then issuing a PORT command and allowing the server to connect back to its data port, the client will issue the PASV command. The result of this is that the server then opens a random unprivileged port (P > 1023) and sends the PORT P command back to the client. The client then initiates the connection from port N+1 to port P on the server to transfer data.

    From the server-side firewall's standpoint, to support passive mode FTP the following communication channels need to be opened:

    • FTP server's port 21 from anywhere (Client initiates connection)
    • FTP server's port 21 to ports > 1023 (Server responds to client's control port)
    • FTP server's ports > 1023 from anywhere (Client initiates data connection to random port specified by server)
    • FTP server's ports > 1023 to remote ports > 1023 (Server sends ACKs (and data) to client's data port)

    When drawn, a passive mode FTP connection looks like this:

    In step 1, the client contacts the server on the command port and issues the PASV command. The server then replies in step 2 with PORT 2024, telling the client which port it is listening to for the data connection. In step 3 the client then initiates the data connection from its data port to the specified server data port. Finally, the server sends back an ACK in step 4 to the client's data port.

    While passive mode FTP solves many of the problems from the client side, it opens up a whole range of problems on the server side. The biggest issue is the need to allow any remote connection to high numbered ports on the server. Fortunately, many FTP daemons, including the popular WU-FTPD allow the administrator to specify a range of ports which the FTP server will use. See Appendix 1 for more information.

    The second issue involves supporting and troubleshooting clients which do (or do not) support passive mode. As an example, the command line FTP utility provided with Solaris does not support passive mode, necessitating a third-party FTP client, such as ncftp.

    With the massive popularity of the World Wide Web, many people prefer to use their web browser as an FTP client. Most browsers only support passive mode when accessing ftp:// URLs. This can either be good or bad depending on what the servers and firewalls are configured to support.


    Passive FTP Example

    Below is an actual example of a passive FTP session. The only things that have been changed are the server names, IP addresses, and user names. In this example an FTP session is initiated from testbox1.slacksite.com (192.168.150.80), a linux box running the standard FTP command line client, to testbox2.slacksite.com (192.168.150.90), a linux box running ProFTPd 1.2.2RC2. The debugging (-d) flag is used with the FTP client to show what is going on behind the scenes. Everything in red is the debugging output which shows the actual FTP commands being sent to the server and the responses generated from those commands. Normal server output is shown in black, and user input is in bold.

    Notice the difference in the PORT command in this example as opposed to the active FTP example. Here, we see a port being opened on the server (192.168.150.90) system, rather than the client. See the discussion about the format of the PORT command above, in the Active FTP Example section.

    testbox1: {/home/p-t/slacker/public_html} % ftp -d testbox2
    Connected to testbox2.slacksite.com.
    220 testbox2.slacksite.com FTP server ready.
    Name (testbox2:slacker): slacker
    ---> USER slacker
    331 Password required for slacker.
    Password: TmpPass
    ---> PASS XXXX
    230 User slacker logged in.
    ---> SYST
    215 UNIX Type: L8
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp> passive
    Passive mode on.
    ftp> ls
    ftp: setsockopt (ignored): Permission denied
    ---> PASV
    227 Entering Passive Mode (192,168,150,90,195,149).
    ---> LIST
    150 Opening ASCII mode data connection for file list
    drwx------   3 slacker    users         104 Jul 27 01:45 public_html
    226 Transfer complete.
    ftp> quit
    ---> QUIT
    221 Goodbye.
    

    Other Notes

    A reader, Maarten Sjouw, pointed out that active FTP will not function when used in conjunction with a client-side NAT (Network Address Translation) device which is not smart enough to alter the IP address info in FTP packets.


    Summary

    The following chart should help admins remember how each FTP mode works:

     Active FTP :
         command : client >1023 -> server 21
         data    : client >1023 <- server 20
    
     Passive FTP :
         command : client >1023 -> server 21
         data    : client >1023 -> server >1023
    

    A quick summary of the pros and cons of active vs. passive FTP is also in order:

    Active FTP is beneficial to the FTP server admin, but detrimental to the client side admin. The FTP server attempts to make connections to random high ports on the client, which would almost certainly be blocked by a firewall on the client side. Passive FTP is beneficial to the client, but detrimental to the FTP server admin. The client will make both connections to the server, but one of them will be to a random high port, which would almost certainly be blocked by a firewall on the server side.

    Luckily, there is somewhat of a compromise. Since admins running FTP servers will need to make their servers accessible to the greatest number of clients, they will almost certainly need to support passive FTP. The exposure of high level ports on the server can be minimized by specifying a limited port range for the FTP server to use. Thus, everything except for this range of ports can be firewalled on the server side. While this doesn't eliminate all risk to the server, it decreases it tremendously. See Appendix 1 for more information.

    References

    An excellent reference on how various internet protocols work and the issues involved in firewalling them can be found in the O'Reilly and Associates book, Building Internet Firewalls, 2nd Ed, by Brent Chapman and Elizabeth Zwicky.

    Finally, the definitive reference on FTP would be RFC 959, which sets forth the official specifications of the FTP protocol. RFCs can be downloaded from numerous locations, including http://www.faqs.org/rfcs/rfc959.html.

    'web' 카테고리의 다른 글

    apache redirect 설정.  (0) 2007.06.14
    Trust in E-commerce  (0) 2006.07.20
    [펌] Axis Webservice 설치및 테스트  (0) 2005.09.03
    [펌] web.xml 사용법  (0) 2005.07.23
    Tomcat 4.1.12 버전에서 서블릿 접근  (0) 2005.02.08
    Posted by '김용환'
    ,