diff options
Diffstat (limited to 'vscclient.c')
-rw-r--r-- | vscclient.c | 403 |
1 files changed, 202 insertions, 201 deletions
diff --git a/vscclient.c b/vscclient.c index f29fd6b..f8edf14 100644 --- a/vscclient.c +++ b/vscclient.c @@ -30,29 +30,29 @@ #include "mutex.h" -int verbose = 0; +int verbose; int sock; static void -print_byte_array ( +print_byte_array( uint8_t *arrBytes, unsigned int nSize ) { int i; - for (i=0; i < nSize; i++) { - printf ("%02X ", arrBytes[i]); + for (i = 0; i < nSize; i++) { + printf("%02X ", arrBytes[i]); } - printf ("\n"); + printf("\n"); } static void -print_usage (void) { - printf ("vscclient [-c <certname> .. -e <emul_args> -d <level>%s] " - "<host> <port> \n", +print_usage(void) { + printf("vscclient [-c <certname> .. -e <emul_args> -d <level>%s] " + "<host> <port>\n", #ifdef USE_PASSTHRU " -p"); - printf (" -p use passthrough mode\n"); + printf(" -p use passthrough mode\n"); #else ""); #endif @@ -62,7 +62,7 @@ print_usage (void) { static mutex_t write_lock; static int -send_msg ( +send_msg( VSCMsgType type, uint32_t reader_id, const void *msg, @@ -81,36 +81,36 @@ send_msg ( mhHeader.type = htonl(type); mhHeader.reader_id = 0; mhHeader.length = htonl(length); - rv = write ( + rv = write( sock, &mhHeader, - sizeof (mhHeader) + sizeof(mhHeader) ); if (rv < 0) { /* Error */ - printf ("write header error\n"); - close (sock); + printf("write header error\n"); + close(sock); MUTEX_UNLOCK(write_lock); - return (16); + return 16; } - rv = write ( + rv = write( sock, msg, length ); if (rv < 0) { /* Error */ - printf ("write error\n"); - close (sock); + printf("write error\n"); + close(sock); MUTEX_UNLOCK(write_lock); - return (16); + return 16; } MUTEX_UNLOCK(write_lock); - return (0); + return 0; } -static VReader *pending_reader = NULL; +static VReader *pending_reader; static mutex_t pending_reader_lock; static condition_t pending_reader_condition; @@ -118,7 +118,7 @@ static condition_t pending_reader_condition; static void * event_thread(void *arg) { - unsigned char atr[ MAX_ATR_LEN]; + unsigned char atr[MAX_ATR_LEN]; int atr_len = MAX_ATR_LEN; VEvent *event = NULL; unsigned int reader_id; @@ -148,7 +148,7 @@ event_thread(void *arg) /* this reader hasn't been told it's status from qemu yet, wait for * that status */ while (pending_reader != NULL) { - CONDITION_WAIT(pending_reader_condition,pending_reader_lock); + CONDITION_WAIT(pending_reader_condition, pending_reader_lock); } MUTEX_UNLOCK(pending_reader_lock); /* now recheck the id */ @@ -168,15 +168,15 @@ event_thread(void *arg) * */ MUTEX_LOCK(pending_reader_lock); while (pending_reader != NULL) { - CONDITION_WAIT(pending_reader_condition,pending_reader_lock); + CONDITION_WAIT(pending_reader_condition, pending_reader_lock); } pending_reader = vreader_reference(event->reader); MUTEX_UNLOCK(pending_reader_lock); reader_name = vreader_get_name(event->reader); if (verbose > 10) { - printf (" READER INSERT: %s\n", reader_name); + printf(" READER INSERT: %s\n", reader_name); } - send_msg ( + send_msg( VSC_ReaderAdd, reader_id, /* currerntly VSCARD_UNDEFINED_READER_ID */ NULL, 0 @@ -188,7 +188,7 @@ event_thread(void *arg) case VEVENT_READER_REMOVE: /* future, tell qemu that an old CCID reader has been removed */ if (verbose > 10) { - printf (" READER REMOVE: %d \n", reader_id); + printf(" READER REMOVE: %d\n", reader_id); } send_msg( VSC_ReaderRemove, @@ -204,10 +204,10 @@ event_thread(void *arg) vreader_power_on(event->reader, atr, &atr_len); /* ATR call functions as a Card Insert event */ if (verbose > 10) { - printf (" CARD INSERT %d: ", reader_id); - print_byte_array (atr, atr_len); + printf(" CARD INSERT %d: ", reader_id); + print_byte_array(atr, atr_len); } - send_msg ( + send_msg( VSC_ATR, reader_id, atr, @@ -215,11 +215,11 @@ event_thread(void *arg) ); break; case VEVENT_CARD_REMOVE: - // Card removed + /* Card removed */ if (verbose > 10) { - printf (" CARD REMOVE %d: \n", reader_id); + printf(" CARD REMOVE %d:\n", reader_id); } - send_msg ( + send_msg( VSC_CardRemove, reader_id, NULL, @@ -253,14 +253,14 @@ do_command(void) char inbuf[255]; char *string; VCardEmulError error; - static unsigned int default_reader_id = 0; + static unsigned int default_reader_id; unsigned int reader_id; VReader *reader = NULL; reader_id = default_reader_id; string = fgets(inbuf, sizeof(inbuf), stdin); if (string != NULL) { - if (strncmp(string,"exit",4) == 0) { + if (strncmp(string, "exit", 4) == 0) { /* remove all the readers */ VReaderList *list = vreader_get_reader_list(); VReaderListEntry *reader_entry; @@ -269,21 +269,21 @@ do_command(void) reader_entry = vreader_list_get_next(reader_entry)) { VReader *reader = vreader_list_get_reader(reader_entry); vreader_id_t reader_id; - reader_id=vreader_get_id(reader); + reader_id = vreader_get_id(reader); if (reader_id == -1) { continue; } /* be nice and signal card removal first (qemu probably should * do this itself) */ if (vreader_card_is_present(reader) == VREADER_OK) { - send_msg ( + send_msg( VSC_CardRemove, reader_id, NULL, 0 ); } - send_msg ( + send_msg( VSC_ReaderRemove, reader_id, NULL, @@ -291,7 +291,7 @@ do_command(void) ); } exit(0); - } else if (strncmp(string,"insert",6) == 0) { + } else if (strncmp(string, "insert", 6) == 0) { if (string[6] == ' ') { reader_id = get_id_from_string(&string[7], reader_id); } @@ -304,7 +304,7 @@ do_command(void) } else { printf("no reader by id %d found\n", reader_id); } - } else if (strncmp(string,"remove",6) == 0) { + } else if (strncmp(string, "remove", 6) == 0) { if (string[6] == ' ') { reader_id = get_id_from_string(&string[7], reader_id); } @@ -317,7 +317,7 @@ do_command(void) } else { printf("no reader by id %d found\n", reader_id); } - } else if (strncmp(string,"select",6) == 0) { + } else if (strncmp(string, "select", 6) == 0) { if (string[6] == ' ') { reader_id = get_id_from_string(&string[7], VSCARD_UNDEFINED_READER_ID); @@ -332,12 +332,12 @@ do_command(void) } else { printf("Reader with id %d not found\n", reader_id); } - } else if (strncmp(string,"debug",5) == 0) { + } else if (strncmp(string, "debug", 5) == 0) { if (string[5] == ' ') { - verbose = get_id_from_string(&string[6],0); + verbose = get_id_from_string(&string[6], 0); } - printf ("debug level = %d\n", verbose); - } else if (strncmp(string,"list",4) == 0) { + printf("debug level = %d\n", verbose); + } else if (strncmp(string, "list", 4) == 0) { VReaderList *list = vreader_get_reader_list(); VReaderListEntry *reader_entry; printf("Active Readers:\n"); @@ -345,13 +345,13 @@ do_command(void) reader_entry = vreader_list_get_next(reader_entry)) { VReader *reader = vreader_list_get_reader(reader_entry); vreader_id_t reader_id; - reader_id=vreader_get_id(reader); + reader_id = vreader_get_id(reader); if (reader_id == -1) { continue; } - printf("%3d %s %s\n",reader_id, + printf("%3d %s %s\n", reader_id, vreader_card_is_present(reader) == VREADER_OK ? - "CARD_PRESENT": " ", + "CARD_PRESENT" : " ", vreader_get_name(reader)); } printf("Inactive Readers:\n"); @@ -359,18 +359,18 @@ do_command(void) reader_entry = vreader_list_get_next(reader_entry)) { VReader *reader = vreader_list_get_reader(reader_entry); vreader_id_t reader_id; - reader_id=vreader_get_id(reader); + reader_id = vreader_get_id(reader); if (reader_id != -1) { continue; } printf("INA %s %s\n", vreader_card_is_present(reader) == VREADER_OK ? - "CARD_PRESENT": " ", + "CARD_PRESENT" : " ", vreader_get_name(reader)); } } else if (*string != 0) { - printf("valid commands: \n"); + printf("valid commands:\n"); printf("insert [reader_id]\n"); printf("remove [reader_id]\n"); printf("select reader_id\n"); @@ -387,26 +387,26 @@ do_command(void) #define APDUBufSize 270 -// just for ease of parsing command line arguments. +/* just for ease of parsing command line arguments. */ #define MAX_CERTS 100 static int -connect_to_qemu ( +connect_to_qemu( const char *host, const char *port ) { struct addrinfo hints; - struct addrinfo* server; + struct addrinfo *server; int ret; - sock = socket ( + sock = socket( AF_INET, SOCK_STREAM, 0 ); if (sock < 0) { - // Error - printf ("Error opening socket!\n"); + /* Error */ + printf("Error opening socket!\n"); } memset(&hints, 0, sizeof(struct addrinfo)); @@ -418,22 +418,22 @@ connect_to_qemu ( ret = getaddrinfo(host, port, &hints, &server); if (ret != 0) { - printf ("getaddrinfo failed\n"); - return (5); + printf("getaddrinfo failed\n"); + return 5; } - if (connect ( + if (connect( sock, server->ai_addr, server->ai_addrlen ) < 0 ) { - // Error - printf ("Could not connect\n"); - return (5); + /* Error */ + printf("Could not connect\n"); + return 5; } if (verbose) { - printf ("Connected (sizeof Header=%zd)!\n", sizeof (VSCMsgHeader)); + printf("Connected (sizeof Header=%zd)!\n", sizeof(VSCMsgHeader)); } return sock; } @@ -441,7 +441,8 @@ connect_to_qemu ( static int on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) { uint32_t *capabilities = (incoming->capabilities); - int num_capabilities = 1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t)); + int num_capabilities = + 1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t)); int i; int rv; pthread_t thread_id; @@ -481,12 +482,12 @@ static int on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) } int -main ( +main( int argc, char *argv[] ) { - char* qemu_host; - char* qemu_port; + char *qemu_host; + char *qemu_port; VSCMsgHeader mhHeader; VSCMsgError *error_msg; @@ -500,40 +501,40 @@ main ( VCardEmulOptions *command_line_options = NULL; int passthru = 0; - char* cert_names[MAX_CERTS]; - char* emul_args = NULL; + char *cert_names[MAX_CERTS]; + char *emul_args = NULL; int cert_count = 0; int c; while ((c = getopt(argc, argv, "c:e:pd:")) != -1) { switch (c) { - case 'c': - if (cert_count >= MAX_CERTS) { - printf("too many certificates (max = %d)\n", MAX_CERTS); - exit (5); - } - cert_names[cert_count++] = optarg; - break; - case 'e': - emul_args = optarg; - break; - case 'p': + case 'c': + if (cert_count >= MAX_CERTS) { + printf("too many certificates (max = %d)\n", MAX_CERTS); + exit(5); + } + cert_names[cert_count++] = optarg; + break; + case 'e': + emul_args = optarg; + break; + case 'p': #ifdef USE_PASSTHRU - passthru = 1; + passthru = 1; #else - print_usage(); - exit(4); + print_usage(); + exit(4); #endif - break; - case 'd': - verbose = get_id_from_string(optarg,1); - break; + break; + case 'd': + verbose = get_id_from_string(optarg, 1); + break; } } if (argc - optind != 2) { print_usage(); - exit (4); + exit(4); } if (!passthru && cert_count > 0) { @@ -543,22 +544,22 @@ main ( * software emulation. add that emulation now. this is NSS Emulator * specific */ if (emul_args == NULL) { - emul_args = (char*)"db=\"/etc/pki/nssdb\""; + emul_args = (char *)"db=\"/etc/pki/nssdb\""; } #define SOFT_STRING ",soft=(,Virtual Reader,CAC,," /* 2 == close paren & null */ len = strlen(emul_args) + strlen(SOFT_STRING) + 2; - for (i=0; i < cert_count; i++) { - len +=strlen(cert_names[i])+1; /* 1 == comma */ + for (i = 0; i < cert_count; i++) { + len += strlen(cert_names[i])+1; /* 1 == comma */ } new_args = malloc(len); - strcpy(new_args,emul_args); - strcat(new_args,SOFT_STRING); - for (i=0; i < cert_count; i++) { - strcat(new_args,cert_names[i]); - strcat(new_args,","); + strcpy(new_args, emul_args); + strcat(new_args, SOFT_STRING); + for (i = 0; i < cert_count; i++) { + strcat(new_args, cert_names[i]); + strcat(new_args, ","); } - strcat(new_args,")"); + strcat(new_args, ")"); emul_args = new_args; } if (emul_args) { @@ -571,7 +572,7 @@ main ( } qemu_host = strdup(argv[argc - 2]); - qemu_port = strdup(argv[argc -1]); + qemu_port = strdup(argv[argc - 1]); sock = connect_to_qemu(qemu_host, qemu_port); MUTEX_INIT(write_lock); @@ -590,9 +591,9 @@ main ( /* Send init message, Host responds (and then we send reader attachments) */ VSCMsgInit init = { - .version=htonl(VSCARD_VERSION), - .magic=VSCARD_MAGIC, - .capabilities={0} + .version = htonl(VSCARD_VERSION), + .magic = VSCARD_MAGIC, + .capabilities = {0} }; send_msg(VSC_Init, mhHeader.reader_id, &init, sizeof(init)); @@ -600,144 +601,144 @@ main ( fd_set fds; FD_ZERO(&fds); - FD_SET(1,&fds); - FD_SET(sock,&fds); + FD_SET(1, &fds); + FD_SET(sock, &fds); /* waiting on input from the socket */ rv = select(sock+1, &fds, NULL, NULL, NULL); if (rv < 0) { /* handle error */ perror("select"); - return (7); + return 7; } - if (FD_ISSET(1,&fds)) { + if (FD_ISSET(1, &fds)) { do_command(); } - if (!FD_ISSET(sock,&fds)) { + if (!FD_ISSET(sock, &fds)) { continue; } - rv = read ( + rv = read( sock, &mhHeader, - sizeof (mhHeader) + sizeof(mhHeader) ); if (rv < sizeof(mhHeader)) { /* Error */ if (rv < 0) { perror("header read error\n"); } else { - printf ("header short read %d\n", rv); + printf("header short read %d\n", rv); } - return (8); + return 8; } mhHeader.type = ntohl(mhHeader.type); mhHeader.reader_id = ntohl(mhHeader.reader_id); mhHeader.length = ntohl(mhHeader.length); if (verbose) { - printf ("Header: type=%d, reader_id=%d length=%d (0x%x)\n", + printf("Header: type=%d, reader_id=%d length=%d (0x%x)\n", mhHeader.type, mhHeader.reader_id, mhHeader.length, mhHeader.length); } switch (mhHeader.type) { - case VSC_APDU: - case VSC_Flush: - case VSC_Error: - case VSC_Init: - rv = read ( - sock, - pbSendBuffer, - mhHeader.length - ); - break; - default: - printf ("Unexpected message of type 0x%X\n", mhHeader.type); - return 0; + case VSC_APDU: + case VSC_Flush: + case VSC_Error: + case VSC_Init: + rv = read( + sock, + pbSendBuffer, + mhHeader.length + ); + break; + default: + printf("Unexpected message of type 0x%X\n", mhHeader.type); + return 0; } switch (mhHeader.type) { - case VSC_APDU: - if (rv < 0) { - /* Error */ - printf ("read error\n"); - close (sock); - return (8); - } + case VSC_APDU: + if (rv < 0) { + /* Error */ + printf("read error\n"); + close(sock); + return 8; + } + if (verbose) { + printf(" recv APDU: "); + print_byte_array(pbSendBuffer, mhHeader.length); + } + /* Transmit recieved APDU */ + dwSendLength = mhHeader.length; + dwRecvLength = sizeof(pbRecvBuffer); + reader = vreader_get_reader_by_id(mhHeader.reader_id); + reader_status = vreader_xfr_bytes(reader, + pbSendBuffer, dwSendLength, + pbRecvBuffer, &dwRecvLength); + if (reader_status == VREADER_OK) { + mhHeader.length = dwRecvLength; if (verbose) { - printf (" recv APDU: "); - print_byte_array (pbSendBuffer, mhHeader.length); - } - /* Transmit recieved APDU */ - dwSendLength = mhHeader.length; - dwRecvLength = sizeof(pbRecvBuffer); - reader = vreader_get_reader_by_id(mhHeader.reader_id); - reader_status = vreader_xfr_bytes(reader, - pbSendBuffer, dwSendLength, - pbRecvBuffer, &dwRecvLength); - if (reader_status == VREADER_OK) { - mhHeader.length = dwRecvLength; - if (verbose) { - printf (" send response: "); - print_byte_array (pbRecvBuffer, mhHeader.length); - } - send_msg ( - VSC_APDU, - mhHeader.reader_id, - pbRecvBuffer, - dwRecvLength - ); - } else { - rv = reader_status; /* warning: not meaningful */ - send_msg ( - VSC_Error, - mhHeader.reader_id, - &rv, - sizeof (uint32_t) - ); - } - vreader_free(reader); - reader = NULL; /* we've freed it, don't use it by accident - again */ - break; - case VSC_Flush: - /* TODO: actually flush */ - send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); - break; - case VSC_Error: - error_msg = (VSCMsgError *) pbSendBuffer; - if (error_msg->code == VSC_SUCCESS) { - MUTEX_LOCK(pending_reader_lock); - if (pending_reader) { - vreader_set_id(pending_reader, mhHeader.reader_id); - vreader_free(pending_reader); - pending_reader = NULL; - CONDITION_NOTIFY(pending_reader_condition); - } - MUTEX_UNLOCK(pending_reader_lock); - break; + printf(" send response: "); + print_byte_array(pbRecvBuffer, mhHeader.length); } - printf("error: qemu refused to add reader\n"); - if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) { - /* clear pending reader, qemu can't handle any more */ - MUTEX_LOCK(pending_reader_lock); - if (pending_reader) { - pending_reader = NULL; - /* make sure the event loop doesn't hang */ - CONDITION_NOTIFY(pending_reader_condition); - } - MUTEX_UNLOCK(pending_reader_lock); + send_msg( + VSC_APDU, + mhHeader.reader_id, + pbRecvBuffer, + dwRecvLength + ); + } else { + rv = reader_status; /* warning: not meaningful */ + send_msg( + VSC_Error, + mhHeader.reader_id, + &rv, + sizeof(uint32_t) + ); + } + vreader_free(reader); + reader = NULL; /* we've freed it, don't use it by accident + again */ + break; + case VSC_Flush: + /* TODO: actually flush */ + send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0); + break; + case VSC_Error: + error_msg = (VSCMsgError *) pbSendBuffer; + if (error_msg->code == VSC_SUCCESS) { + MUTEX_LOCK(pending_reader_lock); + if (pending_reader) { + vreader_set_id(pending_reader, mhHeader.reader_id); + vreader_free(pending_reader); + pending_reader = NULL; + CONDITION_NOTIFY(pending_reader_condition); } + MUTEX_UNLOCK(pending_reader_lock); break; - case VSC_Init: - if (on_host_init(&mhHeader, (VSCMsgInit*)pbSendBuffer) < 0) { - return -1; + } + printf("error: qemu refused to add reader\n"); + if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) { + /* clear pending reader, qemu can't handle any more */ + MUTEX_LOCK(pending_reader_lock); + if (pending_reader) { + pending_reader = NULL; + /* make sure the event loop doesn't hang */ + CONDITION_NOTIFY(pending_reader_condition); } - break; - default: - printf ("Default\n"); - return 0; + MUTEX_UNLOCK(pending_reader_lock); + } + break; + case VSC_Init: + if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) { + return -1; + } + break; + default: + printf("Default\n"); + return 0; } } while (rv >= 0); - return (0); + return 0; } |