1/* Copyright (c) 1999,2003-2004,2008 Apple Inc. 2 * 3 * attachLeak.c - analyze memory leaks from CSSM_Init/ModuleAttach. 4 * 5 */ 6 7#include <stdlib.h> 8#include <stdio.h> 9#include <time.h> 10#include <Security/cssm.h> 11#include "cspwrap.h" 12#include "common.h" 13 14static CSSM_API_MEMORY_FUNCS memFuncs = { 15 appMalloc, 16 appFree, 17 appRealloc, 18 appCalloc, 19 NULL 20 }; 21 22static CSSM_VERSION vers = {2, 0}; 23 24static void usage(char **argv) 25{ 26 printf("usage: %s [options]\n", argv[0]); 27 printf(" Options: \n"); 28 printf(" l (do ModuleLoad on each loop)\n"); 29 printf(" u (do Module{Load,Unload} on each loop)\n"); 30 printf(" d (CSP/DL; default = bare CSP)\n"); 31 printf(" t (TP)\n"); 32 printf(" c (CL)\n"); 33 exit(1); 34} 35 36static int doPause(const char *state) 37{ 38 char resp; 39 40 fpurge(stdin); 41 printf("%s\n", state); 42 printf("q to abort, anything else to continue: "); 43 resp = getchar(); 44 return(resp == 'q'); 45} 46 47int main(int argc, char **argv) 48{ 49 int arg; 50 char *argp; 51 CSSM_HANDLE modHand = 0; 52 void *foo; 53 CSSM_SERVICE_TYPE svcType = CSSM_SERVICE_CSP; 54 const CSSM_GUID *guid = &gGuidAppleCSP; 55 const char *modName = "AppleCSP"; 56 CSSM_RETURN crtn; 57 CSSM_BOOL doLoad = CSSM_FALSE; 58 CSSM_BOOL doUnload = CSSM_FALSE; 59 60 /* force link against malloc */ 61 foo = malloc(1); 62 for(arg=1; arg<argc; arg++) { 63 argp = argv[arg]; 64 switch(argp[0]) { 65 case 'l': 66 doLoad = CSSM_TRUE; 67 break; 68 case 'u': 69 doLoad = doUnload = CSSM_TRUE; 70 break; 71 case 'd': 72 guid = &gGuidAppleCSPDL; 73 modName = "AppleCSPDL"; 74 break; 75 case 'c': 76 guid = &gGuidAppleX509CL; 77 svcType = CSSM_SERVICE_CL; 78 modName = "AppleX509CL"; 79 break; 80 case 't': 81 guid = &gGuidAppleX509TP; 82 svcType = CSSM_SERVICE_TP; 83 modName = "AppleX509TP"; 84 break; 85 case 'h': 86 default: 87 usage(argv); 88 } 89 } 90 91 if(doPause("Top of test")) { 92 goto done; 93 } 94 95 /* CSSM init, just once */ 96 if(!cssmStartup()) { 97 printf("Oops, error starting up CSSM\n"); 98 exit(1); 99 } 100 if(doPause("CSSM initialized")) { 101 goto done; 102 } 103 104 105 if(!doLoad) { 106 /* load, just once */ 107 crtn = CSSM_ModuleLoad(guid, 108 CSSM_KEY_HIERARCHY_NONE, 109 NULL, // eventHandler 110 NULL); // AppNotifyCallbackCtx 111 if(crtn) { 112 printf("Error loading %s\n", modName); 113 printError("CSSM_ModuleLoad", crtn); 114 return 0; 115 } 116 if(doPause("CSSM_ModuleLoad() complete")) { 117 goto done; 118 } 119 } 120 while(1) { 121 if(doLoad) { 122 /* load, each time */ 123 crtn = CSSM_ModuleLoad(guid, 124 CSSM_KEY_HIERARCHY_NONE, 125 NULL, // eventHandler 126 NULL); // AppNotifyCallbackCtx 127 if(crtn) { 128 printf("Error loading %s\n", modName); 129 printError("CSSM_ModuleLoad", crtn); 130 return 0; 131 } 132 if(doPause("CSSM_ModuleLoad() complete")) { 133 break; 134 } 135 } 136 crtn = CSSM_ModuleAttach (guid, 137 &vers, 138 &memFuncs, // memFuncs 139 0, // SubserviceID 140 svcType, 141 0, // AttachFlags 142 CSSM_KEY_HIERARCHY_NONE, 143 NULL, // FunctionTable 144 0, // NumFuncTable 145 NULL, // reserved 146 &modHand); 147 if(crtn) { 148 printf("Error attaching to %s\n", modName); 149 printError("CSSM_ModuleAttach", crtn); 150 return 0; 151 } 152 if(doPause("ModuleAttach() complete")) { 153 break; 154 } 155 CSSM_ModuleDetach(modHand); 156 modHand = 0; 157 if(doPause("ModuleDetach() complete")) { 158 break; 159 } 160 if(doUnload) { 161 /* unload, each time */ 162 crtn = CSSM_ModuleUnload(guid, NULL, NULL); 163 if(crtn) { 164 printf("Error unloading %s\n", modName); 165 printError("CSSM_ModuleUnload", crtn); 166 return 0; 167 } 168 if(doPause("ModuleUnload() complete")) { 169 break; 170 } 171 } /* unloading */ 172 } /* main loop */ 173 174done: 175 fpurge(stdin); 176 if(modHand) { 177 CSSM_ModuleDetach(modHand); 178 printf("Final detach complete; cr to exit: "); 179 } 180 else { 181 printf("Test complete; cr to exit: "); 182 } 183 getchar(); 184 return 0; 185} 186