123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847 |
- #include <stdio.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/prctl.h>
- #include "auth.h"
- #include "driver.h"
- #include "ipc.h"
- #include "fingerdb.h"
- /********************************
- * *
- * This file contents *
- * server-side IPC functions *
- * *
- ********************************/
- /***************************
- * UTILS *
- ***************************/
- /**********************************************************************
- func waitSemaphoreWhileSocket
- wait semaphore and monitor socket at same time
- input
- sem - semaphore which need wait
- soc - socket which need monitor
- return
- 0 if semaphore has been got
- -ECONNRESET on socket drop
- negative on error
- ***********************************************************************/
- static int waitSemaphoreWhileSocket( sem_t* sem, int soc ){
-
- struct timespec t;
-
- while( !write(soc, NULL, 0) ) {
-
- if( clock_gettime(CLOCK_REALTIME, &t) ){
- perror( "[ipcd] clock" );
- return -EINVAL;//clock error
- }
- t.tv_sec += 2;
-
- if( !sem_timedwait(sem, &t) ) return 0;//sem got
- else if( errno != ETIMEDOUT ){
- perror( "[ipcd] sem" );
- return -EINTR;//semaphore error
- }
- }
-
- perror( "[ipcd] sock" );
- return -ECONNRESET;//socket drop
- }
- static void driverSwitchMode( struct driverInstance* this, unsigned char mode ){
-
- if( this->modeIndicator == mode ) return;
-
- //switch mode
- this->modeSwitcher = mode;
-
- if( this->modeIndicator == MODE_IDLE ) sem_post( &this->semaphoreIdle );
- else if( this->modeIndicator == MODE_SCANNING && this->driverState == STATE_WAIT_IPC ){
- sem_post( &this->semaphoreScan );
- goto l_wait_enter;
- }
-
- //wait exit mode notification
- sem_wait( &this->semaphoreIpc );
-
- l_wait_enter: //wait enter mode notification
- sem_wait( &this->semaphoreIpc );
- }
- /************************************************
- func getFingerImageFromScanner
- scan finger and get fingerprint
- caller must switch mode after this
- proto:
- if driver send message to ipcd, ipcd send message to socket
- <IPC_DRIVER_MESSAGE> <message (unsigned char)>
- return
- 0 on success
- -ECONNRESET on socket drop or error
- any negative codes from fingerScanPolling
- *************************************************/
- static int getFingerImageFromScanner( struct driverInstance* this, int socket ){
-
- unsigned char driverMessage;
-
- if( this->modeIndicator != MODE_SCANNING ) driverSwitchMode( this, MODE_SCANNING );
- if( this->driverState == STATE_WAIT_IPC ) sem_post( &this->semaphoreScan );
-
- //prompt the user to swipe the scanner
- if( write(socket, &IPC_DRIVER_MESSAGE, 1) != 1 ) goto l_abort;
- if( write(socket, &IPC_PROMPT_SWIPE_SCANNER, 1) != 1 ) goto l_abort;
-
- l_waitSemaphore:
- //wait semaphore and monitor socket
- if( waitSemaphoreWhileSocket(&this->semaphoreIpc, socket) ) goto l_abort;
-
- if( this->scanResult > 0 ){//message from driver
- driverMessage = this->scanResult;
- if( write(socket, &IPC_DRIVER_MESSAGE, 1) != 1 ) goto l_abort;
- if( write(socket, &driverMessage, 1) != 1 ) goto l_abort;
- sem_post( &this->semaphoreScan );
- goto l_waitSemaphore;
- }
-
- //scan done or error
- return this->scanResult;
-
- l_abort: //tell driver abort
- this->modeSwitcher = MODE_IDLE;
- sem_wait( &this->semaphoreIpc );
- if( this->scanResult > 0 ){
- sem_post( &this->semaphoreScan );
- goto l_abort;
- }
- this->modeSwitcher = MODE_SCANNING;
- return -ECONNRESET;
- }
- /*
- send to socket:
- <length> [content]
- return
- ret = 0 - ok
- ret = -1 - wrong field type
- ret = -2 - db error
- ret = -3 - socket error
- */
- static int printFieldContentToSocket( int socket, int recordId, const struct ipc_field* field ){
-
- int value;
- int len;
- char buf[1024];
-
- //read data from db into buffer
- if( field->type == 'i' ){
- //read data as integer and convert to text
- len = fingerdbGetField( recordId, field->name, &value, sizeof(value) );
- if( len < 0 ) return -2;
- if( len > 0 ){
- sprintf( buf, "%i", value );
- len = strlen( buf );
- }
- }else if( field->type == 't' ){
- //read data as regular text
- len = fingerdbGetField( recordId, field->name, buf, 1024 );
- if( len < 0 ) return -2;
- buf[len] = 0x00;//make sure string is null-terminated
- }else return -1;
-
- //send data to socket
- if( write(socket, &len, sizeof(len)) != sizeof(len) ) goto l_perror;
- if( len > 0 ){
- if( write(socket, buf, len) != len ) goto l_perror;
- }
-
- return 0;
-
- l_perror:
- perror( "[ipcd]" );
- return -3;
- }
- /***************************
- * OPERATIONS *
- ***************************/
- /*
- request: <IPC_TOUCHPAD> <mode>
- response: <mode> || <IPC_ERROR>
- */
- static void touchpadControl( struct driverInstance* this, int socket ){
-
- unsigned char cmd;
- unsigned char ans;
-
- if( recv( socket, &cmd, 1, MSG_WAITALL) != 1 ) goto l_perror;
-
-
- if( cmd == IPC_TOUCHPAD_OFF ) driverSwitchMode( this, MODE_IDLE );
- else if( cmd != IPC_TOUCHPAD_STATUS ){
-
- if( this->modeIndicator != MODE_TOUCHPAD ){
- if( cmd == IPC_TOUCHPAD_MOUSE ) this->touchpadMode = MODE_TOUCHPAD_MOUSE;
- else if( cmd == IPC_TOUCHPAD_WHEELS ) this->touchpadMode = MODE_TOUCHPAD_WHEELS;
- else if( cmd == IPC_TOUCHPAD_ARROWS ) this->touchpadMode = MODE_TOUCHPAD_ARROWS;
- else{
- ans = IPC_ERROR;
- goto l_ans;
- }
-
- driverSwitchMode( this, MODE_TOUCHPAD );
- } else {
- if( cmd == IPC_TOUCHPAD_MOUSE ) this->modeSwitcher = MODE_TOUCHPAD_MOUSE;
- else if( cmd == IPC_TOUCHPAD_WHEELS ) this->modeSwitcher = MODE_TOUCHPAD_WHEELS;
- else if( cmd == IPC_TOUCHPAD_ARROWS ) this->modeSwitcher = MODE_TOUCHPAD_ARROWS;
- else{
- ans = IPC_ERROR;
- goto l_ans;
- }
-
- sem_wait( &this->semaphoreIpc );
-
- }
- }
-
- if( this->modeIndicator != MODE_TOUCHPAD ) ans = IPC_TOUCHPAD_OFF;
- else{
- if( this->touchpadMode == MODE_TOUCHPAD_MOUSE ) ans = IPC_TOUCHPAD_MOUSE;
- else if( this->touchpadMode == MODE_TOUCHPAD_WHEELS ) ans = IPC_TOUCHPAD_WHEELS;
- else if( this->touchpadMode == MODE_TOUCHPAD_ARROWS ) ans = IPC_TOUCHPAD_ARROWS;
- else ans = IPC_ERROR;
- }
-
- l_ans:
- if( write(socket, &ans, 1) != 1 ) goto l_perror;
-
- return;
-
- l_perror:
- perror( "[ipcd]" );
- }
- /*
- request: <IPC_USER_AUTH> <mode> <userlen(int)> <username>
- response: <IPC_SUCCESS> || <IPC_ERROR> || <IPC_DRIVER_MESSAGE> <MSG>
- also messages from driver
- */
- static void authUser( struct driverInstance* this, int socket ){
-
- int res;
- char username[40];
- int usernameLength;
- unsigned char savedMode;
- unsigned char foundFlag;
- unsigned char authMode;
-
- foundFlag = 0x00;
- savedMode = this->modeIndicator;
-
- //read auth mode
- if( recv(socket, &authMode, 1, MSG_WAITALL) != 1 ) goto l_perror;
-
- //username length receive and check
- if( recv(socket, &usernameLength, sizeof(usernameLength), MSG_WAITALL) != sizeof(usernameLength) ) goto l_perror;
- if( usernameLength < 1 || usernameLength > 32 ) goto l_sendResult;
-
- //username receive
- if( recv(socket, username, usernameLength, MSG_WAITALL) != usernameLength ) goto l_perror;
- username[usernameLength] = 0x00; //make sure string null-terminated
-
- if( authMode == IPC_USER_AUTH_ACTIVE ){//auth in active mode
-
- //scan finger
- res = getFingerImageFromScanner( this, socket );
- if( res == -ECONNRESET ) goto l_exit;
- if( res ) goto l_sendResult;
-
- //search match in finger db
- res = authSearchMatch( this->data, username );
- if( res > 0 ) foundFlag = 0xff;
-
- }else if( authMode == IPC_USER_AUTH_PASSIVE ){//auth in passive mode
-
- //check current state
- if( this->passiveAuthModeIndicator != PA_STOP ){
- printf( "[ipcd] ERROR: Unexpected passive auth state.\n" );
- goto l_sendResult;
- }
-
- //setup passive auth mode
- this->passiveAuthModeSwitcher = PA_START;
-
- //switch to idle
- driverSwitchMode( this, MODE_IDLE );
-
- //notise idle mode about passive auth start and wait response
- sem_post( &this->semaphoreIdle );
- sem_wait( &this->semaphoreIpc );
-
- //check response
- if( this->passiveAuthModeIndicator != PA_START ){
- printf( "[ipcd] FATAL ERROR: Passive auth start return unexpected response 0x%02x\n", this->passiveAuthModeIndicator );
- goto l_sendResult;
- }
-
- //set username for auth and signal to main thread for continue
- this->passiveAuthUsername = username;
- sem_post( &this->semaphoreScan );
-
- //prompt the user to swipe the scanner
- if( write(socket, &IPC_DRIVER_MESSAGE, 1) != 1 ) goto l_abort;
- if( write(socket, &IPC_PROMPT_SWIPE_SCANNER, 1) != 1 ) goto l_abort;
-
- //wait semaphore and monitor socket
- res = waitSemaphoreWhileSocket( &this->semaphoreIpc, socket );
- if( !res ){//semaphore got
-
- //check response
- if( this->passiveAuthModeIndicator == PA_SUCCESS ) foundFlag = 0xff;
- else if( this->passiveAuthModeIndicator != PA_FAILED ){
- printf( "[ipcd] FATAL ERROR: Passive auth return unexpected response: 0x%02x\n", this->passiveAuthModeIndicator );
- goto l_sendResult;
- }
-
- //disabling passive auth
- this->passiveAuthUsername = NULL;
- this->passiveAuthModeSwitcher = PA_STOP;
- this->passiveAuthModeIndicator = PA_STOP;
- sem_post( &this->semaphoreScan );
-
- } else {//socket drop or any error
-
- l_abort:
- //signal to idle mode to stop passive auth
- this->passiveAuthModeSwitcher = PA_STOP;
- sem_post( &this->semaphoreIdle );
-
- //wait for the stop response
- l_waitStopResponse:
- sem_wait( &this->semaphoreIpc );
-
- //if it is response with auth result
- if( this->passiveAuthModeIndicator != PA_STOP ){
- sem_post( &this->semaphoreScan );
- goto l_waitStopResponse;
- }
-
- //set username to NULL for disable passive auth
- this->passiveAuthUsername = NULL;
- sem_post( &this->semaphoreScan );
- }
- }
-
- l_sendResult:
- //send result
- if( write(socket, foundFlag ? &IPC_SUCCESS : &IPC_ERROR, 1) != 1 ) goto l_perror;
- goto l_exit;
-
- l_perror:
- perror( "[ipcd]" );
-
- l_exit:
- //restore previous mode
- driverSwitchMode( this, savedMode );
- }
- /*
- proto:
- <cmd>
- <id> <userlen> [user] <descriptionlen> [description]
- ...
- <0>
- */
- static void listFinger( int socket ){
-
- void* db;
- int id;
- int i;
-
- db = fingerdbOpen();
- if( !db ) return;
-
- //cmd
- if( write(socket, &IPC_FINGER_LIST, 1) != 1 ) goto l_perror;
-
- l_searchNext:
- id = fingerdbSearchNextId( db );
- if( !id ){
- //end of list
- id = 0;
- if( write(socket, &id, sizeof(id)) != sizeof(id) ) goto l_perror;
- goto l_closedb;
- }
-
- //send id
- if( write(socket, &id, sizeof(id)) != sizeof(id) ) goto l_perror;
-
- //send fields
- for( i = 0; i < 2; i++ ){
- if( printFieldContentToSocket(socket, id, &ipcFieldList[i]) ) goto l_closedb;
- }
-
- goto l_searchNext;
-
- l_perror:
- perror( "[ipcd]" );
-
- l_closedb:
- fingerdbClose( db );
- }
- /*
- request: IPC_FINGER_DETECT
- answer: IPC_FINGER_DETECT <id(int)> || IPC_ERROR
- also messages from driver
- */
- static void fingerDetect( struct driverInstance* this, int socket ){
-
- int res;
- unsigned char savedMode;
-
- savedMode = this->modeIndicator;
-
- //finger scan
- res = getFingerImageFromScanner( this, socket );
- if( res == -ECONNRESET ) goto l_exit;
-
- //search matches
- if( !res ) res = authSearchMatch( this->data, NULL );
-
- //send result
- if( res < 0 ){
- if( write(socket, &IPC_ERROR, 1 ) != 1 ) goto l_perror;
- } else {
- if( write(socket, &IPC_FINGER_DETECT, 1 ) != 1 ) goto l_perror;
- if( write(socket, &res, sizeof(res)) != sizeof(res) ) goto l_perror;
- }
-
- goto l_exit;
-
- l_perror:
- perror( "[ipcd]" );
-
- l_exit:
- driverSwitchMode( this, savedMode );
- }
- /********************
- * ADMIN *
- ********************/
- /*
- request: <IPC_FINGER_ADD> <MODE>
- answer
- <IPC_FINGER_ADD> <int>
- <IPC_SUCCESS> <ID>
- <IPC_ERROR>
- also messages from driver
- */
- static void newFinger( struct driverInstance* this, int socket ){
-
- int res;
- unsigned char addMode;
- unsigned char savedMode;
-
- int attempts;
-
- int* currentXytCount;
- struct xyt_packed* currentXyt;
- int xyt1Count;
- int xyt2Count;
- struct xyt_packed xyt1[NBIS_XYT_MAX_COUNT];
- struct xyt_packed xyt2[NBIS_XYT_MAX_COUNT];
-
- savedMode = this->modeIndicator;
-
- //read mode
- if( recv(socket, &addMode, 1, MSG_WAITALL) != 1 ){
- perror( "[ipcd]" );
- return;
- }
-
- //check socket security
- if( checkSocketSecurity(socket) ){
- if( write(socket, &IPC_DENIED, 1) != 1 ) perror( "[ipcd]" );
- return;
- }
-
- //check mode
- if( addMode != IPC_FINGER_ADD_SINGLE && addMode != IPC_FINGER_ADD_BEST ){
- printf( "[ipcd] Unknown new finger add mode: 0x%02x\n", addMode );
- if( write(socket, &IPC_ERROR, 1) != 1 ) perror( "[ipcd]" );
- return;
- }
-
- //init some vars
- xyt1Count = 0;
- xyt2Count = 0;
- attempts = 0;
- currentXyt = xyt1;
- currentXytCount = &xyt1Count;
-
- l_scanAgain:
- //scan finger
- res = getFingerImageFromScanner( this, socket );
- if( res == -ECONNRESET ) goto l_exit;
- if( res ) goto l_sendError;
-
- //get minutiae on fingerprint
- *currentXytCount = nbisPgmToMinutiae( this->data, currentXyt );
- if( *currentXytCount < 0 ) goto l_sendError;
-
- //notify client about scan result
- if( write(socket, &IPC_FINGER_ADD, 1 ) != 1 ) goto l_perror;
- if( write(socket, currentXytCount, sizeof(*currentXytCount)) != sizeof(*currentXytCount) ) goto l_perror;
-
- if( addMode == IPC_FINGER_ADD_SINGLE ) goto l_register;
-
- //switch to minimal
- if( currentXyt == xyt1 ){
- if( xyt1Count > xyt2Count ){
- attempts = 0;
- currentXyt = xyt2;
- currentXytCount = &xyt2Count;
- }
- }else{
- if( xyt2Count > xyt1Count ){
- attempts = 0;
- currentXyt = xyt1;
- currentXytCount = &xyt1Count;
- }
- }
-
- //check attempts count
- if( attempts < 3 ){
- attempts++;
- goto l_scanAgain;
- }
-
- //select best fingerprint
- if( currentXyt == xyt1 ){
- currentXyt = xyt2;
- currentXytCount = &xyt2Count;
- }else{
- currentXyt = xyt1;
- currentXytCount = &xyt1Count;
- }
-
- l_register:
- //create new record in finger DB
- res = authEnroll( currentXyt, *currentXytCount );
-
- //send result
- if( res < 0 ){
- l_sendError:
- if( write(socket, &IPC_ERROR, 1 ) != 1 ) goto l_perror;
- } else {
- if( write(socket, &IPC_SUCCESS, 1 ) != 1 ) goto l_perror;
- if( write(socket, &res, sizeof(res)) != sizeof(res) ) goto l_perror;
- }
-
- goto l_exit;
-
- l_perror:
- perror( "[ipcd]" );
-
- l_exit:
- driverSwitchMode( this, savedMode );
- }
- /*
- proto
- <IPC_SUCCESS> or <IPC_ERROR>
-
- <len> [data] user
- <len> [data] desc
- <len> [data] threshold
- <len> [data] action
- */
- static void viewFinger( int socket ){
-
- int i;
- int id;
-
- //read id
- if( recv(socket, &id, sizeof(id), MSG_WAITALL) != sizeof(id) ) goto l_perror;
-
- //check socket security
- if( checkSocketSecurity(socket) ){
- if( write(socket, &IPC_DENIED, 1) != 1 ) goto l_perror;
- return;
- }
-
- //check id exist
- if( !fingerdbCheckIdExist(id) ){
- if( write(socket, &IPC_ERROR, 1) != 1 ) goto l_perror;
- return;
- }
-
- if( write(socket, &IPC_SUCCESS, 1) != 1 ) goto l_perror;
-
- //read content in fields and send it
- for( i = 0; i < 4; i++ ){
- if( printFieldContentToSocket(socket, id, &ipcFieldList[i]) ) return;
- }
-
- return;
- l_perror:
- perror( "[icd]" );
- }
- /*
- request: <IPC_FINGER_EDIT> <ID> <FIELD ID> <LENGTH> [NEW VALUE]
- answer: <IPC_SUCCESS> || <IPC_ERROR>
- */
- static void editFinger( int socket ){
-
- int i;
- int res;
- int id;
- unsigned char fieldId;
- int len;
- char buf[1024];
- int value;
- const struct ipc_field* field = NULL;
-
- //receive id, fieldid, len and new value
- if( recv(socket, &id, sizeof(id), MSG_WAITALL) != sizeof(id) ) goto l_perror;
- if( recv(socket, &fieldId, 1, MSG_WAITALL) != 1 ) goto l_perror;
- if( recv(socket, &len, sizeof(len), MSG_WAITALL) != sizeof(len) ) goto l_perror;
- if( len > 1023 || len < 0 ){//check len
- res = -1;
- goto l_sendAnswer;
- }
-
- if( len ){
- if( recv(socket, buf, len, MSG_WAITALL) != len ) goto l_perror;
- }
- buf[len] = 0x00; //string must be null-terminated
-
- //check socket security
- if( checkSocketSecurity(socket) ){
- if( write(socket, &IPC_DENIED, 1) != 1 ) goto l_perror;
- return;
- }
-
- //check requested field
- for( i = 0; ipcFieldList[i].name; i++ ) if( ipcFieldList[i].id == fieldId ){
- field = &ipcFieldList[i];
- goto l_found;
- }
-
- printf( "%s) WARNING! Wrong field requested: 0x%02x\n", __FUNCTION__, fieldId );
- res = -1;
- goto l_sendAnswer;
-
- l_found:
- //convert text to int if need
- if( field->type == 'i' ){
-
- //if len == 0, then clear field
- if( !len ) goto l_setAsText;
-
- if( sscanf(buf, "%i", &value) != 1 ){
- res = -1;
- goto l_sendAnswer;
- }
- //set value as int
- res = fingerdbSetField( id, field->name, &value, sizeof(value) );
- }else if( field->type == 't' ){
- l_setAsText: //set new value as text
- res = fingerdbSetField( id, field->name, buf, len );
- } else {
- printf( "%s) WARNING: unknow field type: %c\n", __FUNCTION__, field->type );
- res = -1;
- }
-
- l_sendAnswer: //send answer
- if( write(socket, res ? &IPC_ERROR : &IPC_SUCCESS, 1) != 1 ) goto l_perror;
-
- return;
-
- l_perror:
- perror( "[ipcd]" );
- }
- /*
- request <IPC_FINGER_TEST> <id>
- response: <IPC_FINGER_TEST> <score> || <IPC_ERROR>
- also messages from driver
- */
- static void testFinger( struct driverInstance* this, int socket ){
-
- int id;
- int res;
- unsigned char savedMode;
-
- savedMode = this->modeIndicator;
-
- //read id
- if( recv(socket, &id, sizeof(id), MSG_WAITALL) != sizeof(id) ) goto l_perror;
-
- //check socket security
- if( checkSocketSecurity(socket) ){
- if( write(socket, &IPC_DENIED, 1) != 1 ) perror( "[ipcd]" );
- return;
- }
-
- //check id exist
- if( !fingerdbCheckIdExist(id) ){
- if( write(socket, &id, sizeof(id)) != sizeof(id) ) goto l_perror;
- return;
- }
-
- //scan finger and calculate match score
- res = getFingerImageFromScanner( this, socket );
- if( !res ) res = authTest( id, this->data );
-
- //send result
- if( res < 0 ){
- if( write(socket, &IPC_ERROR, 1) != 1 ) perror( "[ipcd]" );
- } else {
- if( write(socket, &IPC_FINGER_TEST, 1) != 1 ) perror( "[ipcd]" );
- else if( write(socket, &res, sizeof(res)) != sizeof(res) ) perror( "[ipcd]" );
- }
-
- driverSwitchMode( this, savedMode );
-
- return;
-
- l_perror:
- perror( "[ipcd]" );
- }
- /*
- request: <IPC_FINGER_REMOVE> <ID>
- answer: <IPC_SUCCESS> or <IPC_FAILED>
- */
- static void removeFinger( int socket ){
-
- int id;
-
- //read id
- if( recv(socket, &id, sizeof(id), MSG_WAITALL) != sizeof(id) ) goto l_perror;
-
- //check socket security
- if( checkSocketSecurity(socket) ){
- if( write(socket, &IPC_DENIED, 1) != 1 ) perror( "[ipcd]" );
- return;
- }
-
- //remove record from DB ande send result
- if( !fingerdbRemoveFinger(id) ){
- if( write(socket, &IPC_SUCCESS, 1) != 1 ) goto l_perror;
- }else {
- if( write(socket, &IPC_ERROR, 1) != 1 ) goto l_perror;
- }
-
- return;
-
- l_perror:
- perror( "[ipcd]" );
- }
- /***************************
- * HANDLER SWITCHER *
- ***************************/
- static void connectionHandler( struct driverInstance* this, int socket ){
-
- unsigned char cmd;
-
- l_recvCmd:
- //read command from socket
- if ( recv(socket, &cmd, 1, MSG_WAITALL) != 1 ) return;
-
- //user cmd
- if( cmd == IPC_TOUCHPAD ) touchpadControl( this, socket );
- else if( cmd == IPC_USER_AUTH ) authUser( this, socket );
- else if( cmd == IPC_FINGER_LIST ) listFinger( socket );
- else if( cmd == IPC_FINGER_DETECT ) fingerDetect( this, socket );
- //admin cmd
- else if( cmd == IPC_FINGER_ADD ) newFinger( this, socket );
- else if( cmd == IPC_FINGER_VIEW ) viewFinger( socket );
- else if( cmd == IPC_FINGER_EDIT ) editFinger( socket );
- else if( cmd == IPC_FINGER_TEST ) testFinger( this, socket );
- else if( cmd == IPC_FINGER_REMOVE ) removeFinger( socket );
- else{
- printf( "[ipcd] Received unknown ipc command: 0x%02x\n", cmd );
- if( write(socket, &IPC_ERROR, 1) != 1 ){//unknown command
- perror( "[ipcd] (unk cmd)" );
- return;
- }
- }
-
- goto l_recvCmd;
- }
- /*************************
- * IPCD ENTRY POINT *
- *************************/
- void* ipcdEntryPoint( void* arg ){
-
- struct driverInstance* this = arg;
-
- int mySocket;
- int clientSocket;
- struct sockaddr_un socketAddress;
-
- prctl( PR_SET_NAME, "ipcd", 0, 0, 0 );
-
- //Create local socket.
- mySocket = socket( AF_UNIX, SOCK_STREAM, 0 );
-
- if( mySocket == -1 ) {
- printf( "[ipcd] Unable create socket %s\n", IPC_SOCKET );
- return NULL;
- }
-
- memset( &socketAddress, 0, sizeof(struct sockaddr_un) );
-
- // Bind socket to socket name.
- socketAddress.sun_family = AF_UNIX;
- strncpy( socketAddress.sun_path, IPC_SOCKET, sizeof(socketAddress.sun_path) - 1 );
-
- if( bind(mySocket, (const struct sockaddr*) &socketAddress, sizeof(struct sockaddr_un)) ){
- perror( "[ipcd] bind" );
- return NULL;
- }
-
- //Prepare for accepting connections.
- if( listen(mySocket, 5) ){
- perror( "[ipcd] listen" );
- return NULL;
- }
-
- //This is the main loop for handling connections.
- for(;;) {
- //Wait for incoming connection.
- clientSocket = accept( mySocket, NULL, NULL );
- if( clientSocket == -1 ) {
- perror( "[ipcd] accept" );
- break;
- }
-
- //handle command
- connectionHandler( this, clientSocket );
-
- //Close socket.
- close( clientSocket );
-
- }
-
- close( mySocket );
-
- return NULL;
- }
|