blob: e889879204e2afdec597bfbe76bc674be1f3b0b7 [file] [log] [blame]
Constantin Kaplinskyb30ae7f2006-05-25 05:04:46 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <unistd.h>
24#include <rfb/Password.h>
25#include <rfb/util.h>
26
27#include <termios.h>
28
29
30using namespace rfb;
31
32char* prog;
33
34static void usage()
35{
36 fprintf(stderr,"usage: %s [file]\n",prog);
37 exit(1);
38}
39
40
41static void enableEcho(bool enable) {
42 termios attrs;
43 tcgetattr(fileno(stdin), &attrs);
44 if (enable)
45 attrs.c_lflag |= ECHO;
46 else
47 attrs.c_lflag &= ~ECHO;
48 attrs.c_lflag |= ECHONL;
49 tcsetattr(fileno(stdin), TCSAFLUSH, &attrs);
50}
51
52static char* getpassword(const char* prompt) {
53 PlainPasswd buf(256);
54 fputs(prompt, stdout);
55 enableEcho(false);
56 char* result = fgets(buf.buf, 256, stdin);
57 enableEcho(true);
58 if (result) {
59 if (result[strlen(result)-1] == '\n')
60 result[strlen(result)-1] = 0;
61 return buf.takeBuf();
62 }
63 return 0;
64}
65
66
67int main(int argc, char** argv)
68{
69 prog = argv[0];
70
71 char* fname = 0;
72
73 for (int i = 1; i < argc; i++) {
74 if (strcmp(argv[i], "-q") == 0) { // allowed for backwards compatibility
75 } else if (argv[i][0] == '-') {
76 usage();
77 } else if (!fname) {
78 fname = argv[i];
79 } else {
80 usage();
81 }
82 }
83
84 if (!fname) {
85 if (!getenv("HOME")) {
86 fprintf(stderr,"HOME is not set\n");
87 exit(1);
88 }
89 fname = new char[strlen(getenv("HOME")) + 20];
90 sprintf(fname, "%s/.vnc", getenv("HOME"));
91 mkdir(fname, 0777);
92 sprintf(fname, "%s/.vnc/passwd", getenv("HOME"));
93 }
94
95 while (true) {
96 PlainPasswd passwd(getpassword("Password:"));
97 if (!passwd.buf) {
98 perror("getpassword error");
99 exit(1);
100 }
101 if (strlen(passwd.buf) < 6) {
102 if (strlen(passwd.buf) == 0) {
103 fprintf(stderr,"Password not changed\n");
104 exit(1);
105 }
106 fprintf(stderr,"Password must be at least 6 characters - try again\n");
107 continue;
108 }
109
110 PlainPasswd passwd2(getpassword("Verify:"));
111 if (!passwd2.buf) {
112 perror("getpass error");
113 exit(1);
114 }
115 if (strcmp(passwd.buf, passwd2.buf) != 0) {
116 fprintf(stderr,"Passwords don't match - try again\n");
117 continue;
118 }
119
120 FILE* fp = fopen(fname,"w");
121 if (!fp) {
122 fprintf(stderr,"Couldn't open %s for writing\n",fname);
123 exit(1);
124 }
125 chmod(fname, S_IRUSR|S_IWUSR);
126
127 ObfuscatedPasswd obfuscated(passwd);
128
129 if (fwrite(obfuscated.buf, obfuscated.length, 1, fp) != 1) {
130 fprintf(stderr,"Writing to %s failed\n",fname);
131 exit(1);
132 }
133
134 fclose(fp);
135
136 return 0;
137 }
138}