Пример #1
0
static errno_t sf_attach(void** cookie, socket_t so)
{
    errno_t ret = 0;
    
    lck_mtx_lock(global_mutex);

    char name[PATH_MAX];
    
    proc_selfname(name, PATH_MAX);
    pp("proc_selfname: %s", name);
    if (strncmp(name, "nc", 3)) {
        pp("装载到进程: %s", name);
    } else {
        ret = ENOPOLICY;
    }
    
    lck_mtx_unlock(global_mutex);

    return ret;
}
Пример #2
0
static errno_t sf_connect_out(void* cookie, socket_t so, const struct sockaddr* to)
{
    errno_t ret = 0;
    
    lck_mtx_lock(global_mutex);
    
//    struct sockaddr_in* addr = (struct sockaddr_in*)to;
//    if (inet_pton(AF_INET, proxy_ip, &addr->sin_addr.s_addr) == 0) {
//        sf_printf("inet_pton(%s) 失败", proxy_ip);
//        return -1;
//    }
    
    char name[PATH_MAX];

    proc_selfname(name, PATH_MAX);
    pp("proc_selfname: %s", name);
    
    lck_mtx_unlock(global_mutex);

    return ret;
}
Пример #3
0
//process
// block/allow, or ask user and put thread to sleep
kern_return_t process(void *cookie, socket_t so, const struct sockaddr *to)
{
    //result
    kern_return_t result = kIOReturnError;
    
    //event
    firewallEvent event = {0};
    
    //rule
    int action = RULE_STATE_NOT_FOUND;
    
    //awake reason
    int reason = 0;
    
    //socket type
    int socketType = 0;
    
    //length of socket type
    int socketTypeLength = 0;
    
    //process name
    char processName[PATH_MAX] = {0};

    //what does rule say?
    // loop until we have an answer
    while(true)
    {
        //reset
        bzero(&event, sizeof(event));
        
        //extract action
        action = ((struct cookieStruct*)cookie)->ruleAction;
        
        //get process name
        proc_selfname(processName, PATH_MAX);

        //block?
        if(RULE_STATE_BLOCK == action)
        {
            //dbg msg
            IOLog("LULU: rule says block for %s (pid: %d)\n", processName, proc_selfpid());
            
            //gtfo!
            result = EPERM;
            
            //all done
            goto bail;
        }
        
        //allow?
        else if(RULE_STATE_ALLOW == action)
        {
            //dbg msg
            IOLog("LULU: rule says allow for %s (pid: %d)\n", processName, proc_selfpid());
            
            //ok
            result = kIOReturnSuccess;
            
            //all done
            goto bail;
        }
        
        //not found
        // ->ask daemon and sleep for response
        else if(RULE_STATE_NOT_FOUND == action)
        {
            //dbg msg
            IOLog("LULU: no rule found for %s (pid: %d)\n", processName, proc_selfpid());
            
            //zero out
            bzero(&event, sizeof(firewallEvent));
            
            //set type
            event.networkOutEvent.type = EVENT_NETWORK_OUT;
            
            //add pid
            event.networkOutEvent.pid = proc_selfpid();
            
            //init length
            socketTypeLength = sizeof(socketType);
            
            //get socket type
            sock_getsockopt(so, SOL_SOCKET, SO_TYPE, &socketType, &socketTypeLength);
            
            //save type
            event.networkOutEvent.socketType = socketType;
            
            //UDP sockets destination socket might be null
            // so grab via 'getpeername' and save as 'remote addr'
            if(NULL == to)
            {
                //copy into 'remote addr' for user mode
                if(0 != sock_getpeername(so, (struct sockaddr*)&(event.networkOutEvent.remoteAddress), sizeof(event.networkOutEvent.remoteAddress)))
                {
                    //err msg
                    IOLog("LULU ERROR: sock_getpeername() failed");
                    
                    //bail
                    goto bail;
                }
            }
            
            //copy remote socket for user mode
            else
            {
                //add remote (destination) socket addr
                memcpy(&(event.networkOutEvent.remoteAddress), to, sizeof(event.networkOutEvent.remoteAddress));
            }
            
            //queue it up
            sharedDataQueue->enqueue_tail(&event, sizeof(firewallEvent));
            
            //dbg msg
            IOLog("LULU: queued response to user mode, now going to sleep!\n");
            
            //lock
            IOLockLock(ruleEventLock);
            
            //sleep
            reason = IOLockSleep(ruleEventLock, &ruleEventLock, THREAD_ABORTSAFE);
            
            //TODO: fix panic, think if kext is unloaded (sets ruleEventLock to NULL) this can still wake up?
            // "Preemption level underflow, possible cause unlocking an unlocked mutex or spinlock"
            //  seems to happen when process is killed or kext unloaded while in the IOLockSleep!?
            
            //unlock
            IOLockUnlock(ruleEventLock);
            
            //thread wakeup cuz of signal, etc
            // ->just bail (process likely exited, etc)
            if(THREAD_AWAKENED != reason)
            {
                //dbg msg
                IOLog("LULU: thread awoke, but because of %d!\n", reason);
                
                //gtfo!
                result = EPERM;
                
                //all done
                goto bail;
            }
            
            //dbg msg
            IOLog("LULU: thread awoke, will check/process response\n");
            
            //try get rule action again
            // ->not found, block, allow, etc
            ((struct cookieStruct*)(cookie))->ruleAction = queryRule(proc_selfpid());
            
            //loop to (re)process
        }
        
    }//while
    
bail:
    
    return result;
}