1 /* $NetBSD: login.c,v 1.1.1.3 2014/12/10 03:34:28 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Portions copyright (c) 2008 Nominet UK. All rights reserved. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the above copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 */ 42 43 /* Id */ 44 45 /* login [-m module] [-s $slot] [-p pin] [-n count] */ 46 47 /*! \file */ 48 49 #include <config.h> 50 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include <time.h> 55 #include <unistd.h> 56 57 #include <isc/commandline.h> 58 #include <isc/result.h> 59 #include <isc/types.h> 60 61 #include <pk11/pk11.h> 62 #include <pk11/internal.h> 63 64 #if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) 65 #define getpassphrase(x) getpass(x) 66 #endif 67 68 #ifndef HAVE_CLOCK_GETTIME 69 #ifndef CLOCK_REALTIME 70 #define CLOCK_REALTIME 0 71 #endif 72 73 int 74 clock_gettime(int32_t id, struct timespec *tp) 75 { 76 struct timeval tv; 77 int result; 78 79 result = gettimeofday(&tv, NULL); 80 if (result) 81 return (result); 82 tp->tv_sec = tv.tv_sec; 83 tp->tv_nsec = (long) tv.tv_usec * 1000; 84 return (result); 85 } 86 #endif 87 88 int 89 main(int argc, char *argv[]) { 90 CK_RV rv; 91 CK_SLOT_ID slot = 0; 92 CK_SESSION_HANDLE *hSession; 93 CK_UTF8CHAR *pin = NULL; 94 char *lib_name = NULL; 95 int error = 0; 96 int c, errflg = 0; 97 unsigned int count = 1000; 98 unsigned int i, j; 99 struct timespec starttime; 100 struct timespec endtime; 101 102 while ((c = isc_commandline_parse(argc, argv, ":m:s:p:n:")) != -1) { 103 switch (c) { 104 case 'm': 105 lib_name = isc_commandline_argument; 106 break; 107 case 's': 108 slot = atoi(isc_commandline_argument); 109 break; 110 case 'p': 111 pin = (CK_UTF8CHAR *)isc_commandline_argument; 112 break; 113 case 'n': 114 count = atoi(isc_commandline_argument); 115 break; 116 case ':': 117 fprintf(stderr, 118 "Option -%c requires an operand\n", 119 isc_commandline_option); 120 errflg++; 121 break; 122 case '?': 123 default: 124 fprintf(stderr, "Unrecognised option: -%c\n", 125 isc_commandline_option); 126 errflg++; 127 } 128 } 129 130 if (errflg) { 131 fprintf(stderr, "Usage:\n"); 132 fprintf(stderr, 133 "\tlogin [-m module] [-s slot] [-p pin] [-n count]\n"); 134 exit(1); 135 } 136 137 /* allocate sessions */ 138 hSession = (CK_SESSION_HANDLE *) 139 malloc(count * sizeof(CK_SESSION_HANDLE)); 140 if (hSession == NULL) { 141 perror("malloc"); 142 exit(1); 143 } 144 for (i = 0; i < count; i++) 145 hSession[i] = CK_INVALID_HANDLE; 146 147 /* Initialize the CRYPTOKI library */ 148 if (lib_name != NULL) 149 pk11_set_lib_name(lib_name); 150 151 if (pin == NULL) 152 pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); 153 154 rv = pkcs_C_Initialize(NULL_PTR); 155 if (rv != CKR_OK) { 156 if (rv == 0xfe) 157 fprintf(stderr, 158 "Can't load or link module \"%s\"\n", 159 pk11_get_lib_name()); 160 else 161 fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv); 162 free(hSession); 163 exit(1); 164 } 165 166 if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { 167 perror("clock_gettime(start)"); 168 goto exit_program; 169 } 170 171 /* loop */ 172 for (i = 0; i < count; i++) { 173 /* Open sessions */ 174 rv = pkcs_C_OpenSession(slot, CKF_SERIAL_SESSION, 175 NULL_PTR, NULL_PTR, &hSession[i]); 176 if (rv != CKR_OK) { 177 fprintf(stderr, 178 "C_OpenSession[%u]: Error = 0x%.8lX\n", 179 i, rv); 180 error = 1; 181 if (i == 0) 182 goto exit_program; 183 break; 184 } 185 186 /* Logon */ 187 rv = pkcs_C_Login(hSession[i], CKU_USER, 188 pin, strlen((char *)pin)); 189 if (rv != CKR_OK) { 190 fprintf(stderr, 191 "C_Login[%u]: Error = 0x%.8lX\n", 192 i, rv); 193 error = 1; 194 if (i == 0) 195 goto exit_program; 196 break; 197 } 198 199 /* Logoff */ 200 rv = pkcs_C_Logout(hSession[i]); 201 if (rv != CKR_OK) { 202 fprintf(stderr, 203 "C_Logout[%u]: Error = 0x%.8lX\n", 204 i, rv); 205 error = 1; 206 if (i == 0) 207 goto exit_program; 208 break; 209 } 210 } 211 212 if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { 213 perror("clock_gettime(end)"); 214 goto exit_program; 215 } 216 217 endtime.tv_sec -= starttime.tv_sec; 218 endtime.tv_nsec -= starttime.tv_nsec; 219 while (endtime.tv_nsec < 0) { 220 endtime.tv_sec -= 1; 221 endtime.tv_nsec += 1000000000; 222 } 223 printf("%u logins in %ld.%09lds\n", i, 224 endtime.tv_sec, endtime.tv_nsec); 225 if (i > 0) 226 printf("%g logins/s\n", 227 i / ((double) endtime.tv_sec + 228 (double) endtime.tv_nsec / 1000000000.)); 229 230 for (j = 0; j < i; j++) { 231 if (hSession[j] == CK_INVALID_HANDLE) 232 continue; 233 /* Close sessions */ 234 rv = pkcs_C_CloseSession(hSession[j]); 235 if ((rv != CKR_OK) && !errflg) { 236 fprintf(stderr, 237 "C_CloseSession[%u]: Error = 0x%.8lX\n", 238 j, rv); 239 errflg = 1; 240 } 241 } 242 243 exit_program: 244 free(hSession); 245 246 rv = pkcs_C_Finalize(NULL_PTR); 247 if (rv != CKR_OK) 248 fprintf(stderr, "C_Finalize: Error = 0x%.8lX\n", rv); 249 250 exit(error); 251 } 252