#!/usr/bin/env python
# 
# Copyright 2016-present Ciena Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
# http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import sys, os
from EapolAAA import *
from enum import *
import noseMd5AuthHolder as md5AuthHolder
from socket import *
from struct import *
from md5 import md5
from scapy.all import *
from nose.tools import *
from CordTestBase import CordTester

class MD5AuthTest(EapolPacket, CordTester):

    md5StateTable = Enumeration("MD5StateTable", ("ST_EAP_SETUP",
                                                  "ST_EAP_START",
                                                  "ST_EAP_ID_REQ",
                                                  "ST_EAP_MD5_CHALLENGE",
                                                  "ST_EAP_STATUS",
                                                  "ST_EAP_MD5_DONE"
                                                  )
                                )
    md5EventTable = Enumeration("MD5EventTable", ("EVT_EAP_SETUP",
                                                  "EVT_EAP_START",
                                                  "EVT_EAP_ID_REQ",
                                                  "EVT_EAP_MD5_CHALLENGE",
                                                  "EVT_EAP_STATUS",
                                                  "EVT_EAP_MD5_DONE"
                                                  )
                                )
    def __init__(self, intf = 'veth0', password = "password", required_status = "EAP_SUCCESS"):
        self.passwd = password
        self.req_status = required_status
        self.fsmTable = md5AuthHolder.initMd5AuthHolderFsmTable(self, self.md5StateTable, self.md5EventTable)
        EapolPacket.__init__(self, intf)
        CordTester.__init__(self, self.fsmTable, self.md5StateTable.ST_EAP_MD5_DONE)
        self.currentState = self.md5StateTable.ST_EAP_SETUP
        self.currentEvent = self.md5EventTable.EVT_EAP_SETUP
        self.nextState = None
        self.nextEvent = None

    def _eapSetup(self):
        print 'Inside EAP Setup'
        self.setup()
        self.nextEvent = self.md5EventTable.EVT_EAP_START
        
    def _eapStart(self):
        print 'Inside EAP Start'
        self.eapol_start()
        self.nextEvent = self.md5EventTable.EVT_EAP_ID_REQ

    def _eapIdReq(self):
        print 'Inside EAP ID Req'
        p = self.eapol_recv()
        code, pkt_id, eaplen = unpack("!BBH", p[0:4])
        print "Code %d, id %d, len %d" %(code, pkt_id, eaplen)
        assert_equal(code, EAP_REQUEST)
        reqtype = unpack("!B", p[4:5])[0]
        reqdata = p[5:4+eaplen]
        assert_equal(reqtype, EAP_TYPE_ID)
        print "<====== Send EAP Response with identity = %s ================>" % USER
        self.eapol_id_req(pkt_id, USER)
        self.nextEvent = self.md5EventTable.EVT_EAP_MD5_CHALLENGE

    def _eapMd5Challenge(self):
        print 'Inside EAP MD5 Challenge Exchange'
        challenge,pkt_id =self.eap_md5_challenge_recv(self.passwd)
        resp=md5(challenge).digest()
        resp=chr(len(resp))+resp
        length= 5+len(resp)
        print "Generated MD5 challenge is %s Length : %d" % (resp,length)
        print "--> Send EAP response with MD5 challenge"
        eap_payload = self.eap(EAP_RESPONSE, pkt_id, EAP_TYPE_MD5, str(resp))
        self.eapol_send(EAPOL_EAPPACKET, eap_payload)
        self.nextEvent = self.md5EventTable.EVT_EAP_STATUS

    def _eapStatus(self):
       print 'Inside EAP Status -- Sucess/Failure'
       if self.req_status == "EAP_SUCCESS":
         status=self.eap_Status()
         print "<============EAP code received is = %d ====================>" % status
         assert_equal(status, EAP_SUCCESS)
         print"Received EAP SUCCESS"
       else:
         print 'Inside EAP Status -- Sucess/Failure ===> SUCCESS should not be received , Since Negative Testcase'
         self.s.settimeout(10)
         assert_equal(self.s.gettimeout(), 10)
         print "Check if the socket timed out ====> Since negative testcase socket should timeout because ONOS is not sending the EAP FAILURE Message"
         assert_raises(socket.error, self.s.recv, 1024)
       self.nextEvent = self.md5EventTable.EVT_EAP_MD5_DONE

    def _wrong_password(self):
       print 'Start Testcase for EAP-MD5 Wrong Password'
       #self._eap_md5_states()
       self.__init__(intf = 'veth0', password = "wrong_password", required_status = "EAP_FAILURE")
      

