1/*
2** Copyright (c) 1999, 2000, 2001, 2002, 2003
3** Adel I. Mirzazhanov. All rights reserved
4**
5** Redistribution and use in source and binary forms, with or without
6** modification, are permitted provided that the following conditions
7** are met:
8**
9**     1.Redistributions of source code must retain the above copyright notice,
10**       this list of conditions and the following disclaimer.
11**     2.Redistributions in binary form must reproduce the above copyright
12**       notice, this list of conditions and the following disclaimer in the
13**       documentation and/or other materials provided with the distribution.
14**     3.The name of the author may not be used to endorse or promote products
15**       derived from this software without specific prior written permission.
16**
17** THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND ANY EXPRESS
18** OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO, THE IMPLIED
19** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20** ARE DISCLAIMED.  IN  NO  EVENT  SHALL THE AUTHOR BE LIABLE FOR ANY
21** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22** DAMAGES (INCLUDING, BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE
23** GOODS OR SERVICES;  LOSS OF USE,  DATA,  OR  PROFITS;  OR BUSINESS
24** INTERRUPTION)  HOWEVER  CAUSED  AND  ON  ANY  THEORY OF LIABILITY,
25** WHETHER  IN  CONTRACT,   STRICT   LIABILITY,  OR  TORT  (INCLUDING
26** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <stdlib.h>
31#include <string.h>
32#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__)
33#include <strings.h>
34#endif
35#ifndef APGBFM
36#include "fips181.h"
37#include "randpass.h"
38#endif
39
40#include "base/rand_util.h"
41#include "convert.h"
42
43/*
44** GLOBALS
45*/
46
47/* small letters */
48char let[26] =
49 {
50 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
51 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
52 'u', 'v', 'w', 'x', 'w', 'z'
53 };
54/* capital letters */
55char clet[26] =
56 {
57 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
58 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
59 'U', 'V', 'W', 'X', 'W', 'Z'
60  };
61
62/*
63** FUNCTIONS
64*/
65
66/*
67** decapitalize() - This routine replaces all capital letters
68**                  to small letters in the word:
69** INPUT:
70**   char * - word.
71** OUTPUT:
72**   none.
73** NOTES:
74**   none.
75*/
76void
77decapitalize (char *word)
78{
79 int i = 0; /* counter */
80 int j = 0; /* counter */
81 int str_len = (int) strlen(word);
82 for(j = 0; j < str_len; j++)
83  for(i=0; i < 26; i++)
84   if(word[j] == clet[i])
85       word[j] = let[i];
86}
87
88#ifndef APGBFM
89/*
90** capitalize() - This routine designed to modify sullable like this:
91** adel ----> Adel
92** dot  ----> Dot
93** etc.
94** INPUT:
95**   char * - syllable.
96** OUTPUT:
97**   none.
98** NOTES:
99**   none.
100*/
101void
102capitalize (char *syllable)
103{
104 char tmp = 0x00;
105 int i = 0;
106 if (base::RandInt(0, 1) == 1)
107  {
108   (void)memcpy((void *)&tmp, (void *)syllable, sizeof(tmp));
109   for(i=0; i < 26; i++)
110     if ( let[i] == tmp )
111       if (is_restricted_symbol(clet[i]) != TRUE)
112         (void)memcpy ((void *)syllable, (void *)&clet[i], 1);
113  }
114}
115
116/*
117** numerize() - This routine designed to modify single-letter
118** syllable like this:
119** a ----> 1 or 2 or 3 etc.
120** u ----> 1 or 2 or 3 etc.
121** etc.
122** INPUT:
123**   char * - single-letter syllable
124** OUTPUT:
125**   none.
126** NOTES:
127**   none.
128*/
129void
130numerize (char *syllable)
131{
132 char *tmp = (char *)calloc(1, 4);
133 if ( strlen (syllable) == 1 )
134      {
135       (void) gen_rand_symbol(tmp, S_NB);
136       (void)memcpy ((void *)syllable, (void *)tmp, 1);
137      }
138 free ((void *)tmp);
139}
140/*
141** specialize() - This routine designed to modify single-letter syllable
142** like this:
143** a ----> # or $ or % etc.
144** u ----> # or $ or % etc.
145** etc.
146** INPUT:
147**   char * - single-letter syllable.
148** OUTPUT:
149**   none.
150** NOTES:
151**   none.
152*/
153void
154specialize (char *syllable)
155{
156 char *tmp = (char *)calloc(1, 4);
157 if ( strlen (syllable) == 1 )
158      {
159       (void) gen_rand_symbol(tmp, S_SS);
160       (void)memcpy ((void *)syllable, (void *)tmp, 1);
161      }
162 free ((void *)tmp);
163}
164
165/*
166** symb2name - convert symbol to it's name
167** INPUT:
168**   char * - one symbol syllable
169** OUTPUT:
170**   none.
171** NOTES:
172**   none.
173*/
174void
175symb2name(char * syllable, char * h_syllable)
176{
177 struct ssymb_names
178  {
179   char symbol;
180   const char * name;
181  };
182 static const struct ssymb_names ssn[42] =
183  {
184   {'1',"ONE"},
185   {'2',"TWO"},
186   {'3',"THREE"},
187   {'4',"FOUR"},
188   {'5',"FIVE"},
189   {'6',"SIX"},
190   {'7',"SEVEN"},
191   {'8',"EIGHT"},
192   {'9',"NINE"},
193   {'0',"ZERO"},
194   {33, "EXCLAMATION_POINT"},
195   {34, "QUOTATION_MARK"},
196   {35, "CROSSHATCH"},
197   {36, "DOLLAR_SIGN"},
198   {37, "PERCENT_SIGN"},
199   {38, "AMPERSAND"},
200   {39, "APOSTROPHE"},
201   {40, "LEFT_PARENTHESIS"},
202   {41, "RIGHT_PARENTHESIS"},
203   {42, "ASTERISK"},
204   {43, "PLUS_SIGN"},
205   {44, "COMMA"},
206   {45, "HYPHEN"},
207   {46, "PERIOD"},
208   {47, "SLASH"},
209   {58, "COLON"},
210   {59, "SEMICOLON"},
211   {60, "LESS_THAN"},
212   {61, "EQUAL_SIGN"},
213   {62, "GREATER_THAN"},
214   {63, "QUESTION_MARK"},
215   {64, "AT_SIGN"},
216   {91, "LEFT_BRACKET"},
217   {92, "BACKSLASH"},
218   {93, "RIGHT_BRACKET"},
219   {94, "CIRCUMFLEX"},
220   {95, "UNDERSCORE"},
221   {96, "GRAVE"},
222   {123, "LEFT_BRACE"},
223   {124, "VERTICAL_BAR"},
224   {125, "RIGHT_BRACE"},
225   {126, "TILDE"}
226  };
227 int i = 0;
228 int flag = FALSE;
229
230 if (strlen(syllable) == 1)
231    {
232     for (i = 0; i < 42; i++)
233      {
234       if(*syllable == ssn[i].symbol)
235        {
236         (void)memcpy((void*)h_syllable, (void*)ssn[i].name, strlen(ssn[i].name));
237	 flag = TRUE;
238        }
239      }
240     if (flag != TRUE)
241       (void)memcpy((void*)h_syllable, (void*)syllable, strlen(syllable));
242    }
243}
244
245/*
246** spell_word - spell the word
247** INPUT:
248**   char * - pointer to the word
249**   char * - pointer to the spelled word
250** OUTPUT:
251**   char * - pointer to the spelled word
252**    NULL  - something is wrong
253** NOTES:
254**   You should free() memory pointed by spelled_word after each use of spell_word
255*/
256char *
257spell_word(char * word, char * spelled_word)
258{
259 struct char_spell
260  {
261   char symbol;
262   const char *name;
263  };
264 static struct char_spell cs[94] =
265  {
266   {'1',"ONE"              },
267   {'2',"TWO"              },
268   {'3',"THREE"            },
269   {'4',"FOUR"             },
270   {'5',"FIVE"             },
271   {'6',"SIX"              },
272   {'7',"SEVEN"            },
273   {'8',"EIGHT"            },
274   {'9',"NINE"             },
275   {'0',"ZERO"             },
276   {'A', "Alfa"            },
277   {'B', "Bravo"           },
278   {'C', "Charlie"         },
279   {'D', "Delta"           },
280   {'E', "Echo"            },
281   {'F', "Foxtrot"         },
282   {'G', "Golf"            },
283   {'H', "Hotel"           },
284   {'I', "India"           },
285   {'J', "Juliett"         },
286   {'K', "Kilo"            },
287   {'L', "Lima"            },
288   {'M', "Mike"            },
289   {'N', "November"        },
290   {'O', "Oscar"           },
291   {'P', "Papa"            },
292   {'Q', "Quebec"          },
293   {'R', "Romeo"           },
294   {'S', "Sierra"          },
295   {'T', "Tango"           },
296   {'U', "Uniform"         },
297   {'V', "Victor"          },
298   {'W', "Whiskey"         },
299   {'X', "X_ray"           },
300   {'Y', "Yankee"          },
301   {'Z', "Zulu"            },
302   {'a', "alfa"            },
303   {'b', "bravo"           },
304   {'c', "charlie"         },
305   {'d', "delta"           },
306   {'e', "echo"            },
307   {'f', "foxtrot"         },
308   {'g', "golf"            },
309   {'h', "hotel"           },
310   {'i', "india"           },
311   {'j', "juliett"         },
312   {'k', "kilo"            },
313   {'l', "lima"            },
314   {'m', "mike"            },
315   {'n', "november"        },
316   {'o', "oscar"           },
317   {'p', "papa"            },
318   {'q', "quebec"          },
319   {'r', "romeo"           },
320   {'s', "sierra"          },
321   {'t', "tango"           },
322   {'u', "uniform"         },
323   {'v', "victor"          },
324   {'w', "whiskey"         },
325   {'x', "x_ray"           },
326   {'y', "yankee"          },
327   {'z', "zulu"            },
328   {33, "EXCLAMATION_POINT"},
329   {34, "QUOTATION_MARK"   },
330   {35, "CROSSHATCH"       },
331   {36, "DOLLAR_SIGN"      },
332   {37, "PERCENT_SIGN"     },
333   {38, "AMPERSAND"        },
334   {39, "APOSTROPHE"       },
335   {40, "LEFT_PARENTHESIS" },
336   {41, "RIGHT_PARENTHESIS"},
337   {42, "ASTERISK"         },
338   {43, "PLUS_SIGN"        },
339   {44, "COMMA"            },
340   {45, "HYPHEN"           },
341   {46, "PERIOD"           },
342   {47, "SLASH"            },
343   {58, "COLON"            },
344   {59, "SEMICOLON"        },
345   {60, "LESS_THAN"        },
346   {61, "EQUAL_SIGN"       },
347   {62, "GREATER_THAN"     },
348   {63, "QUESTION_MARK"    },
349   {64, "AT_SIGN"          },
350   {91, "LEFT_BRACKET"     },
351   {92, "BACKSLASH"        },
352   {93, "RIGHT_BRACKET"    },
353   {94, "CIRCUMFLEX"       },
354   {95, "UNDERSCORE"       },
355   {96, "GRAVE"            },
356   {123, "LEFT_BRACE"      },
357   {124, "VERTICAL_BAR"    },
358   {125, "RIGHT_BRACE"     },
359   {126, "TILDE"           }
360  };
361  int s_length = 0;
362  int i = 0;
363  int j = 0;
364  int word_len = (int) strlen(word);
365  char * tmp_ptr;
366  char hyphen = '-';
367  char zero   = 0x00;
368
369  /* Count the length of the spelled word */
370  for (i=0; i <= word_len; i++)
371   for (j=0; j < 94; j++)
372    if (word[i] == cs[j].symbol)
373     {
374      s_length = s_length + (int) strlen(cs[j].name) + 1;
375      continue;
376     }
377
378  /* Allocate memory for spelled word */
379  if ( (spelled_word = (char *)calloc(1, (size_t)s_length)) == NULL)
380    return(NULL);
381
382  /* Construct spelled word */
383  tmp_ptr = spelled_word;
384
385  for (i=0; i < word_len; i++)
386   for (j=0; j < 94; j++)
387    if (word[i] == cs[j].symbol)
388     {
389      (void) memcpy((void *)tmp_ptr, (void *)cs[j].name, strlen(cs[j].name));
390      tmp_ptr = tmp_ptr + strlen(cs[j].name);
391      /* Place the hyphen after each symbol */
392      (void) memcpy((void *)(tmp_ptr), (void *)&hyphen, 1);
393      tmp_ptr = tmp_ptr + 1;
394      continue;
395     }
396
397  /* Remove hyphen at the end of the word */
398  tmp_ptr = tmp_ptr - 1;
399  (void) memcpy((void *)(tmp_ptr), (void *)&zero, 1);
400
401  return (spelled_word);
402}
403
404#endif /* APGBFM */
405