comparison cli-runopts.c @ 47:4b53a43f0082

- client pubkey auth works - rearrange the runopts code for client and server (hostkey reading is needed by both (if the client is doing pubkey auth. otherwise....))
author Matt Johnston <matt@ucc.asn.au>
date Fri, 06 Aug 2004 16:18:01 +0000
parents 3bea78e1b175
children 6f091656c100
comparison
equal deleted inserted replaced
46:3bea78e1b175 47:4b53a43f0082
29 #include "dbutil.h" 29 #include "dbutil.h"
30 #include "algo.h" 30 #include "algo.h"
31 31
32 cli_runopts cli_opts; /* GLOBAL */ 32 cli_runopts cli_opts; /* GLOBAL */
33 33
34 static void printhelp(const char * progname); 34 static void printhelp();
35 35 static void parsehostname(char* userhostarg);
36 static void printhelp(const char * progname) { 36 #ifdef DROPBEAR_PUBKEY_AUTH
37 static void loadidentityfile(const char* filename);
38 #endif
39
40 static void printhelp() {
37 41
38 fprintf(stderr, "Dropbear client v%s\n" 42 fprintf(stderr, "Dropbear client v%s\n"
39 "Usage: %s [options] user@host[:port]\n" 43 "Usage: %s [options] user@host\n"
40 "Options are:\n" 44 "Options are:\n"
41 "user Remote username\n" 45 "-p <remoteport>\n"
42 "host Remote host\n" 46 "-t Allocate a pty"
43 "port Remote port\n" 47 "-T Don't allocate a pty"
44 ,DROPBEAR_VERSION, progname); 48 #ifdef DROPBEAR_PUBKEY_AUTH
49 "-i <identityfile> (multiple allowed)"
50 #endif
51 ,DROPBEAR_VERSION, cli_opts.progname);
45 } 52 }
46 53
47 void cli_getopts(int argc, char ** argv) { 54 void cli_getopts(int argc, char ** argv) {
48 55
49 unsigned int i, j; 56 unsigned int i, j;
50 char ** next = 0; 57 char ** next = 0;
51 unsigned int cmdlen; 58 unsigned int cmdlen;
59 #ifdef DROPBEAR_PUBKEY_AUTH
52 int nextiskey = 0; /* A flag if the next argument is a keyfile */ 60 int nextiskey = 0; /* A flag if the next argument is a keyfile */
53 61 #endif
54 uid_t uid; 62
55 struct passwd *pw = NULL; 63
56
57 char* userhostarg = NULL;
58 64
59 /* see printhelp() for options */ 65 /* see printhelp() for options */
60 cli_opts.progname = argv[0]; 66 cli_opts.progname = argv[0];
61 cli_opts.remotehost = NULL; 67 cli_opts.remotehost = NULL;
62 cli_opts.remoteport = NULL; 68 cli_opts.remoteport = NULL;
63 cli_opts.username = NULL; 69 cli_opts.username = NULL;
64 cli_opts.cmd = NULL; 70 cli_opts.cmd = NULL;
65 cli_opts.wantpty = 1; 71 cli_opts.wantpty = 9; /* 9 means "it hasn't been touched", gets set later */
72 #ifdef DROPBEAR_PUBKEY_AUTH
73 cli_opts.pubkeys = NULL;
74 #endif
66 opts.nolocaltcp = 0; 75 opts.nolocaltcp = 0;
67 opts.noremotetcp = 0; 76 opts.noremotetcp = 0;
68 /* not yet 77 /* not yet
69 opts.ipv4 = 1; 78 opts.ipv4 = 1;
70 opts.ipv6 = 1; 79 opts.ipv6 = 1;
71 */ 80 */
72 81
73 if (argc != 2) { 82 /* Iterate all the arguments */
74 printhelp(argv[0]);
75 exit(EXIT_FAILURE);
76 }
77
78 for (i = 1; i < (unsigned int)argc; i++) { 83 for (i = 1; i < (unsigned int)argc; i++) {
84 #ifdef DROPBEAR_PUBKEY_AUTH
79 if (nextiskey) { 85 if (nextiskey) {
80 /* XXX do stuff */ 86 /* Load a hostkey since the previous argument was "-i" */
81 break; 87 loadidentityfile(argv[i]);
82 } 88 nextiskey = 0;
89 continue;
90 }
91 #endif
83 if (next) { 92 if (next) {
93 /* The previous flag set a value to assign */
84 *next = argv[i]; 94 *next = argv[i];
85 if (*next == NULL) { 95 if (*next == NULL) {
86 dropbear_exit("Invalid null argument"); 96 dropbear_exit("Invalid null argument");
87 } 97 }
88 next = NULL; 98 next = NULL;
89 continue; 99 continue;
90 } 100 }
91 101
92 if (argv[i][0] == '-') { 102 if (argv[i][0] == '-') {
93
94 /* A flag *waves* */ 103 /* A flag *waves* */
104
95 switch (argv[i][1]) { 105 switch (argv[i][1]) {
96 case 'p': 106 case 'p': /* remoteport */
97 next = &cli_opts.remoteport; 107 next = &cli_opts.remoteport;
98 break; 108 break;
99 #ifdef DROPBEAR_PUBKEY_AUTH 109 #ifdef DROPBEAR_PUBKEY_AUTH
100 case 'i': 110 case 'i': /* an identityfile */
101 nextiskey = 1; 111 nextiskey = 1;
102 break; 112 break;
103 #endif 113 #endif
114 case 't': /* we want a pty */
115 cli_opts.wantpty = 1;
116 break;
117 case 'T': /* don't want a pty */
118 cli_opts.wantpty = 0;
119 break;
104 default: 120 default:
105 fprintf(stderr, "Unknown argument %s\n", argv[i]); 121 fprintf(stderr, "Unknown argument '%s'\n", argv[i]);
106 printhelp(argv[0]); 122 printhelp();
107 exit(EXIT_FAILURE); 123 exit(EXIT_FAILURE);
108 break; 124 break;
109 } /* Switch */ 125 } /* Switch */
110 126
127 continue; /* next argument */
128
111 } else { 129 } else {
130 TRACE(("non-flag arg"));
112 131
113 /* Either the hostname or commands */ 132 /* Either the hostname or commands */
114 /* Hostname is first up, must be set before we get the cmds */
115 133
116 if (cli_opts.remotehost == NULL) { 134 if (cli_opts.remotehost == NULL) {
117 /* We'll be editing it, should probably make a copy */ 135
118 userhostarg = m_strdup(argv[1]); 136 parsehostname(argv[i]);
119 137
120 cli_opts.remotehost = strchr(userhostarg, '@');
121 if (cli_opts.remotehost == NULL) {
122 /* no username portion, the cli-auth.c code can figure the
123 * local user's name */
124 cli_opts.remotehost = userhostarg;
125 } else {
126 cli_opts.remotehost[0] = '\0'; /* Split the user/host */
127 cli_opts.remotehost++;
128 cli_opts.username = userhostarg;
129 }
130
131 if (cli_opts.username == NULL) {
132 uid = getuid();
133
134 pw = getpwuid(uid);
135 if (pw == NULL || pw->pw_name == NULL) {
136 dropbear_exit("I don't know my own [user]name");
137 }
138
139 cli_opts.username = m_strdup(pw->pw_name);
140 }
141
142 if (cli_opts.remotehost[0] == '\0') {
143 dropbear_exit("Bad hostname");
144 }
145 } else { 138 } else {
139
146 /* this is part of the commands to send - after this we 140 /* this is part of the commands to send - after this we
147 * don't parse any more options, and flags are sent as the 141 * don't parse any more options, and flags are sent as the
148 * command */ 142 * command */
149 cmdlen = 0; 143 cmdlen = 0;
150 for (j = i; j < (unsigned int)argc; j++) { 144 for (j = i; j < (unsigned int)argc; j++) {
164 /* We've eaten all the options and flags */ 158 /* We've eaten all the options and flags */
165 break; 159 break;
166 } 160 }
167 } 161 }
168 } 162 }
169 } 163
164 if (cli_opts.remotehost == NULL) {
165 dropbear_exit("Bad syntax");
166 }
167
168 if (cli_opts.remoteport == NULL) {
169 cli_opts.remoteport = "22";
170 }
171
172 /* If not explicitly specified with -t or -T, we don't want a pty if
173 * there's a command, but we do otherwise */
174 if (cli_opts.wantpty == 9) {
175 if (cli_opts.cmd == NULL) {
176 cli_opts.wantpty = 1;
177 } else {
178 cli_opts.wantpty = 0;
179 }
180 }
181 }
182
183 #ifdef DROPBEAR_PUBKEY_AUTH
184 static void loadidentityfile(const char* filename) {
185
186 struct PubkeyList * nextkey;
187 sign_key *key;
188 int keytype;
189
190 key = new_sign_key();
191 keytype = DROPBEAR_SIGNKEY_ANY;
192 if ( readhostkey(filename, key, &keytype) != DROPBEAR_SUCCESS ) {
193
194 fprintf(stderr, "Failed loading keyfile '%s'\n", filename);
195 sign_key_free(key);
196
197 } else {
198
199 nextkey = (struct PubkeyList*)m_malloc(sizeof(struct PubkeyList));
200 nextkey->key = key;
201 nextkey->next = cli_opts.pubkeys;
202 nextkey->type = keytype;
203 cli_opts.pubkeys = nextkey;
204 }
205 }
206 #endif
207
208
209 /* Parses a [user@]hostname argument. userhostarg is the argv[i] corresponding
210 * - note that it will be modified */
211 static void parsehostname(char* userhostarg) {
212
213 uid_t uid;
214 struct passwd *pw = NULL;
215
216 cli_opts.remotehost = strchr(userhostarg, '@');
217 if (cli_opts.remotehost == NULL) {
218 /* no username portion, the cli-auth.c code can figure the
219 * local user's name */
220 cli_opts.remotehost = userhostarg;
221 } else {
222 cli_opts.remotehost[0] = '\0'; /* Split the user/host */
223 cli_opts.remotehost++;
224 cli_opts.username = userhostarg;
225 }
226
227 if (cli_opts.username == NULL) {
228 uid = getuid();
229
230 pw = getpwuid(uid);
231 if (pw == NULL || pw->pw_name == NULL) {
232 dropbear_exit("Unknown own user");
233 }
234
235 cli_opts.username = m_strdup(pw->pw_name);
236 }
237
238 if (cli_opts.remotehost[0] == '\0') {
239 dropbear_exit("Bad hostname");
240 }
241 }