1 /* password.c -- password requester related things
2  * Copyright (C) 1996-1999 author
3  * This file is part of the xpk package.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18  * USA.
19  */
20 
21 /* Written by Dirk St�cker <stoecker@amigaworld.com>
22  * UNIX version by Vesa Halttunen <vesuri@jormas.com>
23  */
24 
25 /* FIX: uh.. this probably doesn't quite work. An encrypting library is needed
26  *      for testing so one needs to be implemented first. */
27 
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <sys/types.h>
32 #include "xpk/xpk.h"
33 #include "xpk/xpkprefs.h"
34 #include "texts.h"
35 #include "xpkmaster.h"
36 
37 /* NOTE: what are these anyway? */
38 #define TESTSIZE	13
39 
40 #define VERIFY_OFF	0
41 #define VERIFY_ON	1
42 #define VERIFY_ACTIVE	2
43 #define VERIFY_DONE	3
44 
45 static const struct PassCharData {
46   unsigned int Flag;
47   char Lower;
48   char Upper;
49 } TestField[TESTSIZE] = {
50 {XPKPASSFF_30x39,0x30,0x39}, {XPKPASSFF_41x46,0x41,0x46},
51 {XPKPASSFF_61x66,0x61,0x66}, {XPKPASSFF_47x5A,0x47,0x5A},
52 {XPKPASSFF_67x7A,0x67,0x7A}, {XPKPASSFF_20,   0x20,0x20},
53 {XPKPASSFF_SPECIAL7BIT,0x21,0x2F},
54 {XPKPASSFF_SPECIAL7BIT,0x3A,0x40},
55 {XPKPASSFF_SPECIAL7BIT,0x5B,0x60},
56 {XPKPASSFF_SPECIAL7BIT,0x7B,0x7E},
57 {XPKPASSFF_C0xDE,0xC0,0xDE}, {XPKPASSFF_DFxFF,0xDF,0xFF},
58 {XPKPASSFF_SPECIAL8BIT,0xA0,0xBF},
59 };
60 
61 /* this is no public structure !! */
62 struct RequestData {
63   unsigned int rd_BufSize;
64   unsigned short rd_Verify;
65   char *rd_Title;
66   char *rd_GivenBuffer;
67   char *rd_PassBuffer;
68   char rd_ScreenTitle[80];
69   char rd_KeyBuffer[9];
70 };
71 
72 /* returns XPKERR codes */
DoRequest(struct RequestData * rd)73 int DoRequest(struct RequestData *rd)
74 {
75   char *pass;
76   int err;
77 
78   err=XPKERR_UNKNOWN;
79 
80   while(!(rd->rd_Verify==VERIFY_ON || rd->rd_Verify==VERIFY_DONE)) {
81     pass=(char *)getpass(rd->rd_Title);
82 
83     if(rd->rd_Verify==VERIFY_ACTIVE) {
84       if(strcmp(pass, rd->rd_PassBuffer))
85 	err=XPKERR_WRONGPW;
86       else
87 	rd->rd_Verify=VERIFY_DONE;
88     } else {
89       if(rd->rd_Verify==VERIFY_ON) {
90 	rd->rd_Verify=VERIFY_ACTIVE;
91       }
92       if(err!=XPKERR_WRONGPW) {
93 	strcpy(rd->rd_PassBuffer, pass);
94 	err=XPKERR_OK;
95       }
96     }
97   }
98 
99   return err;
100 }
101 
XpkPassRequest(struct TagItem * ti)102 int XpkPassRequest(struct TagItem *ti)
103 {
104   struct RequestData *rd;
105   int mode = 0, useprefs = 1;
106   struct TagItem *tags = ti;
107 
108 #ifdef DEBUG
109   DebugTagList("XpkPassRequest", tags);
110 #endif
111 
112   if(!(rd = (struct RequestData *) calloc(sizeof(struct RequestData), 1)))
113     return XPKERR_NOMEM;
114 
115   while((ti = NextTagItem(&tags)))
116   {
117     switch(ti->ti_Tag)
118     {
119     case XPK_PassChars:
120       break;
121     case XPK_PasswordBuf:
122       rd->rd_GivenBuffer=(char *)ti->ti_Data;
123       mode += 10;
124       break;
125     case XPK_PassBufSize:
126       rd->rd_BufSize=(unsigned int)ti->ti_Data;
127       break;
128     case XPK_Key16BitPtr:
129       rd->rd_GivenBuffer=(char *)ti->ti_Data;
130       mode += 11;
131       break;
132     case XPK_Key32BitPtr:
133       rd->rd_GivenBuffer=(char *)ti->ti_Data;
134       mode += 12;
135       break;
136     case XPK_PubScreen:
137       break;
138     case XPK_PassTitle:
139       rd->rd_Title = ti->ti_Data ? (char *) ti->ti_Data : "";
140       break;
141     case XPK_TimeOut:
142       break;
143     case XPK_Preferences:
144       if(!ti->ti_Data) useprefs = 0;
145       break;
146     case XPK_PassWinLeft:
147       break;
148     case XPK_PassWinTop:
149       break;
150     case XPK_PassWinWidth:
151       break;
152     case XPK_PassWinHeight:
153       break;
154     case XPK_PassCenter:
155       break;
156     case XPK_PassVerify:
157       rd->rd_Verify = (ti->ti_Data ? VERIFY_ON : VERIFY_OFF);
158       break;
159     };
160   }
161 
162   if(!mode || (mode > 12) || (mode == 10 && !rd->rd_BufSize) ||
163      !rd->rd_GivenBuffer) {
164     free(rd);
165     return XPKERR_BADPARAMS;
166   }
167 
168   /* create title text */
169   if(!rd->rd_Title) {
170     if(mode == 10)
171       rd->rd_Title = strings[TXT_REQ_PASSWORD];
172     else {
173       rd->rd_Title = rd->rd_ScreenTitle;
174       sprintf(rd->rd_ScreenTitle, strings[TXT_REQ_KEY], (mode==11 ? 16 : 32));
175     }
176   }
177 
178   if(mode > 10) {
179     rd->rd_BufSize = (mode == 11 ? 5 : 9);
180     rd->rd_PassBuffer = rd->rd_KeyBuffer;
181   } else
182     rd->rd_PassBuffer = rd->rd_GivenBuffer;
183 
184   if(!(useprefs = DoRequest(rd))) {
185     if(mode == 11)
186       *((unsigned short *) rd->rd_GivenBuffer) = strtoul(rd->rd_PassBuffer, 0, 16);
187     else if(mode == 12)
188       *((unsigned int *) rd->rd_GivenBuffer) = strtoul(rd->rd_PassBuffer, 0, 16);
189   }
190 
191   free(rd);
192 
193   return useprefs;
194 }
195 
196 /* FIX: This is probably buggy */
XpkPassRequestTags(Tag tag,...)197 int XpkPassRequestTags(Tag tag, ...)
198 {
199   va_list args;
200   struct TagItem *taglist;
201   int ret, i, numargs=1;
202   Tag current;
203 
204   /* Count the number of tags */
205   current=tag;
206   va_start(args, tag);
207   while(current!=TAG_DONE) {
208     va_arg(args, void *);
209     current=va_arg(args, Tag);
210     numargs++;
211   }
212   va_end(args);
213 
214   /* Allocate memory for the tag array */
215   taglist=calloc(numargs, sizeof(struct TagItem));
216 
217   /* Copy the args to the array */
218   current=tag;
219   va_start(args, tag);
220   for(i=0; i<numargs; i++) {
221     taglist[i].ti_Tag=current;
222     taglist[i].ti_Data=va_arg(args, void *);
223     current=va_arg(args, Tag);
224   }
225   va_end(args);
226 
227   ret=XpkPassRequest(taglist);
228 
229   free(taglist);
230   return ret;
231 }
232