/*--- File pubinfo.c */ #include #include #include #include #include "boolean.h" #include "keyfield.h" #include "pubinfop.h" #include "global.h" #include "protserv.h" #include "rsaref.h" #include "ripem.h" #include "strutilp.h" #define LINEBUFSIZE 200 #if 0 /*--- function ReadUserRecord -------------------------------------------- * * Read key information for a user, from a flat file. * Records for different users are demarcated by any of: * Blank line * Line starting with '-' * End of file * * Entry: stream is positioned at the beginning of a user record. * maxLen is the size of rec. * * Exit: rec points to the user record read in from the file. * It is terminated by a zero byte. * dataLen is the number of bytes in the record. * Returns TRUE upon success. */ int ReadUserRecord(stream,rec,maxLen,dataLen) FILE *stream; char *rec; int maxLen; int *dataLen; { #define RECSIZE 512 char *cptr = rec; int lastch='\0'; int ch; *dataLen = 0; while(1) { if(EOF == (ch = getc(stream))) { if(cptr == rec) return 0; break; } if(lastch == '\n') { if(ch == '\n' || ch == '-') { break; } else { if(!(maxLen--)) { return 0; } *(cptr++) = ch; } } else { if(!(maxLen--)) { return 0; } *(cptr++) = ch; } lastch = ch; } *cptr = '\0'; *dataLen = cptr - rec; return 1; } #else /*--- function ReadUserRecord -------------------------------------------- * * Read key information for a user, from a flat file. * Records for different users are demarcated by any of: * Blank line * Line starting with '-' * End of file * * Entry: stream is positioned at the beginning of a user record. * maxLen is the size of rec. * * Exit: rec points to the user record read in from the file. * It is terminated by a zero byte. * dataLen is the number of bytes in the record. * Returns TRUE upon success. */ int ReadUserRecord(stream,rec,maxLen,dataLen) FILE *stream; char *rec; int maxLen; int *dataLen; { #define RECSIZE 512 char line[RECSIZE]; char *cptr = rec, *lptr; int first=1; *dataLen = 0; while(1) { if(!fgets(line,RECSIZE,stream)) break; /* At the beginning, skip past blank lines and -----BEGIN */ if(first) { if(LineIsWhiteSpace(line) || strncmp(line,"-----BEGIN",10)==0) { continue; } else { first = 0; } } if(!first) { /* Within the record, a blank line or -----END terminates. */ if(LineIsWhiteSpace(line)) break; if(strncmp(line,"-----END",8)==0) break; /* Copy this line into the buffer */ for(lptr=line; *lptr; lptr++) { if(!(maxLen--)) { return 0; } *(cptr++) = *lptr; } } } *cptr = '\0'; *dataLen = cptr - rec + 1; return cptr != rec; } #endif /*--- function FindUserInRecord ----------------------------------------- * * Scan a user record to find if it contains info for a given user. * We are looking for a "User: " field with a given value. * * Entry: user is the email address of a user. * userRec is a zero-terminated buffer of lines. * * Exit: Returns TRUE if the desired user is found. */ BOOL FindUserInRecord(user,userRec) char *user; char *userRec; { #define LINELEN 240 BOOL looking_user=TRUE, right_user=FALSE; char *cptr=userRec; char temp_buf[LINELEN]; while(looking_user) { if(!CrackKeyField(cptr,USER_FIELD,temp_buf,LINELEN)) { /* No more "User:" fields. */ looking_user = FALSE; } else { if(!EmailMatch(user,temp_buf)) { /* This User: line indicates a different user. * Look to see if there's another User: line. */ if(!NextLineInBuf(&cptr)) { continue; } } else { /* We have found the user's key. All OK. */ looking_user = FALSE; right_user = TRUE; } } } return right_user; } /*--- function PosFileLine --------------------------------------------- * * Position the input file, consisting of lines formatted as below, * to just after a given field name. * * The lines look like: * * * Entry: stream is the input file to search. * field is the name of the field to search for. * * Exit: Returns TRUE if the field is found, else FALSE. * The input stream is positioned just after the line * containing the field name. */ BOOL PosFileLine(stream,field) FILE *stream; char *field; { char line[LINEBUFSIZE]; int fieldlen = strlen(field); BOOL reading=TRUE; while(reading && fgets(line,LINEBUFSIZE,stream)) { if(strncmp(line,field,fieldlen)==0) { return(TRUE); } if(LineIsWhiteSpace(line)) reading=FALSE; } return(FALSE); } /*--- function GetFileLine --------------------------------------------- * * Search an input stream for a line starting with a given field name, * and return the rest of that line. * Lines are formatted as described in PosFileLine. * * Entry stream is the input stream. * field is the text of the field (including trailing * colon if applicable). * valuelen is the maximum number of bytes that can fit in "value". * * Exit value is the rest of the line, not including the * name of the field and the intervening white space. * Returns TRUE if the field was found, else FALSE. */ BOOL GetFileLine(stream,field,value,valuelen) FILE *stream; char *field; char *value; int valuelen; { char line[LINEBUFSIZE], *cptr; int fieldlen = strlen(field); while(fgets(line,LINEBUFSIZE,stream)) { if(strncmp(line,field,fieldlen)==0) { cptr = line+fieldlen; while(WhiteSpace(*cptr) && *cptr) cptr++; fieldlen = strlen(cptr); if(cptr[fieldlen-1]=='\n') cptr[fieldlen-1] = '\0'; strncpy(value,cptr,valuelen); return (TRUE); } } return(FALSE); } /*--- function ExtractValue ------------------------------------------------- * * Extract the value of a field. * * Entry: bptr points to a buffer containing a "name: value" field. * * Exit: */ int ExtractValue(bptr,val,maxLen) char *bptr; char *val; unsigned int maxLen; { while(*bptr && *bptr != ':') bptr++; if(*bptr) bptr++; while(*bptr && (*bptr == ' ' || *bptr == '\t')) bptr++; while(isprint(*bptr) && maxLen--) { *(val++) = *(bptr++); } *val = '\0'; return 1; } /*--- function CrackKeyField --------------------------------------------- * * Search a buffer for a field. * The buffer contains fields consisting of field names followed by * field values. A buffer looks like: * * name1: value1\n * name2: value2\n * more value2... \n * name3: \n * value3... * * In other words, a value can span several lines. Continuation lines are * indicated by a space right after a newline. * * Entry: bptr points to a buffer containing key info for a user. * The buffer is zero-terminated. * field is name of the field we are looking for, zero-terminated. * If field is NULL, we make no attempt to position bptr. * valSize is the size of the val buffer. * * Exit: val contains the value of the field, zero-terminated. * Embedded newlines have been removed. * Returns TRUE if the field was found. */ int CrackKeyField(bptr,field,val,valSize) char *bptr; char *field; char *val; int valSize; { int fieldlen = strlen(field); if(field) { /* Find the field with the proper name. */ while(strncmp(bptr,field,fieldlen) != 0) { /* This isn't it. Skip to the next line. */ while(*bptr && *bptr != '\n') bptr++; /* Return failure if we didn't find the fieldname (no next line). */ if(!*bptr) return FALSE; bptr++; /* Skip past EOL */ } bptr += fieldlen; } /* Copy lines (skipping leading white space) to val, until we * come to a line that doesn't start with white space. */ do { /* Skip leading white space */ while(*bptr && (*bptr==' ' || *bptr == '\t')) bptr++; /* Copy to end of line */ while(valSize && *bptr != '\n' && *bptr!='\r' && *bptr) { *(val++) = *(bptr++); valSize--; } /* Skip past EOL */ while(*bptr == '\n' || *bptr=='\r') bptr++; /* Keep going as long as following lines start with blanks */ } while(*bptr && (*bptr == ' ' || *bptr == '\t')); *val = '\0'; return 1; } /*--- function GetPubInfoFromFile ----------------------------------------- * * Read a key record from a flat file into a buffer, collapsing multiple * continuation lines into one long line where necessary. * * This routine is unused. * */ int GetPubInfoFromFile(stream,buf,bufLen,returnedLen) FILE *stream; char *buf; unsigned int bufLen; unsigned int *returnedLen; { #define ADDBYTE(cha) \ if(bufLen-- == 0) return 1; \ (*buf++) = cha; \ (*returnedLen)++; int ch; *returnedLen=0; /* Skip past leading blank lines. */ while(EOF != (ch=getc(stream)) && ch == '\n'); do { if(ch == EOF) return 1; /* Add the contents of this line, up to but not including the * newline, to the buffer. */ do { ADDBYTE(ch); ch = getc(stream); } while(EOF!=ch && ch != '\n'); /* If the next line is blank, we've reached the end of the entry. * If it starts with white space, it's a continuation of this line. * Otherwise, we start a new line. */ ch = getc(stream); if(ch == '\n') { ADDBYTE('\n'); ADDBYTE('\0'); return 0; } else if(EOF == ch) { return 1; } if(ch!=' ' && ch!='\t') { ADDBYTE('\n'); } } while(1); } /*--- function NextLineInBuf ------------------------------------------- */ int NextLineInBuf(buf) char **buf; { int gotone = 0; while(**buf && **buf!='\n' && **buf!='\r') (*buf)++; if(**buf == '\r') (*buf)++; if(**buf == '\n') (*buf)++; if(**buf) gotone = 1; return gotone; } /*--- function ExtractPublicKeyLines ------------------------------------------ * * Extract the public key info (bounded by lines of * -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----) * from one buffer to another. * * Entry: inBuf is a buffer containing lines delimited by LF or * CR/LF. It's zero-terminated. * outSize is the number of bytes in outbuf (max). * * Exit: outBuf contains the lines between the above delimiters, * if found. * Returns TRUE if found. */ BOOL ExtractPublicKeyLines(inBuf,outBuf,outSize) char *inBuf; char *outBuf; int outSize; { int beglen=strlen(PUB_KEY_STRING_BEGIN), endlen=strlen(PUB_KEY_STRING_END); char *begptr; int nbytes; while(strncmp(inBuf,PUB_KEY_STRING_BEGIN,beglen) != 0) { if(!NextLineInBuf(&inBuf)) return FALSE; } NextLineInBuf(&inBuf); begptr = inBuf; while(strncmp(inBuf,PUB_KEY_STRING_END,endlen) != 0) { if(!NextLineInBuf(&inBuf)) return FALSE; } nbytes = inBuf-begptr>outSize ? outSize : inBuf-begptr; strncpy(outBuf,begptr,nbytes); return TRUE; }