comparison svr-authpubkey.c @ 1733:d529a52b2f7c coverity coverity

merge coverity from main
author Matt Johnston <matt@ucc.asn.au>
date Fri, 26 Jun 2020 21:07:34 +0800
parents ae41624c2198
children 064f5be2fc45
comparison
equal deleted inserted replaced
1643:b59623a64678 1733:d529a52b2f7c
68 #if DROPBEAR_SVR_PUBKEY_AUTH 68 #if DROPBEAR_SVR_PUBKEY_AUTH
69 69
70 #define MIN_AUTHKEYS_LINE 10 /* "ssh-rsa AB" - short but doesn't matter */ 70 #define MIN_AUTHKEYS_LINE 10 /* "ssh-rsa AB" - short but doesn't matter */
71 #define MAX_AUTHKEYS_LINE 4200 /* max length of a line in authkeys */ 71 #define MAX_AUTHKEYS_LINE 4200 /* max length of a line in authkeys */
72 72
73 static int checkpubkey(const char* algo, unsigned int algolen, 73 static int checkpubkey(const char* keyalgo, unsigned int keyalgolen,
74 const unsigned char* keyblob, unsigned int keybloblen); 74 const unsigned char* keyblob, unsigned int keybloblen);
75 static int checkpubkeyperms(void); 75 static int checkpubkeyperms(void);
76 static void send_msg_userauth_pk_ok(const char* algo, unsigned int algolen, 76 static void send_msg_userauth_pk_ok(const char* sigalgo, unsigned int sigalgolen,
77 const unsigned char* keyblob, unsigned int keybloblen); 77 const unsigned char* keyblob, unsigned int keybloblen);
78 static int checkfileperm(char * filename); 78 static int checkfileperm(char * filename);
79 79
80 /* process a pubkey auth request, sending success or failure message as 80 /* process a pubkey auth request, sending success or failure message as
81 * appropriate */ 81 * appropriate */
82 void svr_auth_pubkey(int valid_user) { 82 void svr_auth_pubkey(int valid_user) {
83 83
84 unsigned char testkey; /* whether we're just checking if a key is usable */ 84 unsigned char testkey; /* whether we're just checking if a key is usable */
85 char* algo = NULL; /* pubkey algo */ 85 char* sigalgo = NULL;
86 unsigned int algolen; 86 unsigned int sigalgolen;
87 const char* keyalgo;
88 unsigned int keyalgolen;
87 unsigned char* keyblob = NULL; 89 unsigned char* keyblob = NULL;
88 unsigned int keybloblen; 90 unsigned int keybloblen;
89 unsigned int sign_payload_length; 91 unsigned int sign_payload_length;
90 buffer * signbuf = NULL; 92 buffer * signbuf = NULL;
91 sign_key * key = NULL; 93 sign_key * key = NULL;
92 char* fp = NULL; 94 char* fp = NULL;
93 enum signkey_type type = -1; 95 enum signature_type sigtype;
96 enum signkey_type keytype;
97 int auth_failure = 1;
94 98
95 TRACE(("enter pubkeyauth")) 99 TRACE(("enter pubkeyauth"))
96 100
97 /* 0 indicates user just wants to check if key can be used, 1 is an 101 /* 0 indicates user just wants to check if key can be used, 1 is an
98 * actual attempt*/ 102 * actual attempt*/
99 testkey = (buf_getbool(ses.payload) == 0); 103 testkey = (buf_getbool(ses.payload) == 0);
100 104
101 algo = buf_getstring(ses.payload, &algolen); 105 sigalgo = buf_getstring(ses.payload, &sigalgolen);
102 keybloblen = buf_getint(ses.payload); 106 keybloblen = buf_getint(ses.payload);
103 keyblob = buf_getptr(ses.payload, keybloblen); 107 keyblob = buf_getptr(ses.payload, keybloblen);
104 108
105 if (!valid_user) { 109 if (!valid_user) {
106 /* Return failure once we have read the contents of the packet 110 /* Return failure once we have read the contents of the packet
109 testing for user existence if the public key is known */ 113 testing for user existence if the public key is known */
110 send_msg_userauth_failure(0, 0); 114 send_msg_userauth_failure(0, 0);
111 goto out; 115 goto out;
112 } 116 }
113 117
118 sigtype = signature_type_from_name(sigalgo, sigalgolen);
119 if (sigtype == DROPBEAR_SIGNATURE_NONE) {
120 send_msg_userauth_failure(0, 0);
121 goto out;
122 }
123
124 keytype = signkey_type_from_signature(sigtype);
125 keyalgo = signkey_name_from_type(keytype, &keyalgolen);
126
127 #if DROPBEAR_PLUGIN
128 if (svr_ses.plugin_instance != NULL) {
129 char *options_buf;
130 if (svr_ses.plugin_instance->checkpubkey(
131 svr_ses.plugin_instance,
132 &ses.plugin_session,
133 keyalgo,
134 keyalgolen,
135 keyblob,
136 keybloblen,
137 ses.authstate.username) == DROPBEAR_SUCCESS) {
138 /* Success */
139 auth_failure = 0;
140
141 /* Options provided? */
142 options_buf = ses.plugin_session->get_options(ses.plugin_session);
143 if (options_buf) {
144 struct buf temp_buf = {
145 .data = (unsigned char *)options_buf,
146 .len = strlen(options_buf),
147 .pos = 0,
148 .size = 0
149 };
150 int ret = svr_add_pubkey_options(&temp_buf, 0, "N/A");
151 if (ret == DROPBEAR_FAILURE) {
152 /* Fail immediately as the plugin provided wrong options */
153 send_msg_userauth_failure(0, 0);
154 goto out;
155 }
156 }
157 }
158 }
159 #endif
114 /* check if the key is valid */ 160 /* check if the key is valid */
115 if (checkpubkey(algo, algolen, keyblob, keybloblen) == DROPBEAR_FAILURE) { 161 if (auth_failure) {
162 auth_failure = checkpubkey(keyalgo, keyalgolen, keyblob, keybloblen) == DROPBEAR_FAILURE;
163 }
164
165 if (auth_failure) {
116 send_msg_userauth_failure(0, 0); 166 send_msg_userauth_failure(0, 0);
117 goto out; 167 goto out;
118 } 168 }
119 169
120 /* let them know that the key is ok to use */ 170 /* let them know that the key is ok to use */
121 if (testkey) { 171 if (testkey) {
122 send_msg_userauth_pk_ok(algo, algolen, keyblob, keybloblen); 172 send_msg_userauth_pk_ok(sigalgo, sigalgolen, keyblob, keybloblen);
123 goto out; 173 goto out;
124 } 174 }
125 175
126 /* now we can actually verify the signature */ 176 /* now we can actually verify the signature */
127 177
128 /* get the key */ 178 /* get the key */
129 key = new_sign_key(); 179 key = new_sign_key();
130 type = DROPBEAR_SIGNKEY_ANY; 180 if (buf_get_pub_key(ses.payload, key, &keytype) == DROPBEAR_FAILURE) {
131 if (buf_get_pub_key(ses.payload, key, &type) == DROPBEAR_FAILURE) {
132 send_msg_userauth_failure(0, 1); 181 send_msg_userauth_failure(0, 1);
133 goto out; 182 goto out;
134 } 183 }
135 184
136 /* create the data which has been signed - this a string containing 185 /* create the data which has been signed - this a string containing
149 198
150 buf_setpos(signbuf, 0); 199 buf_setpos(signbuf, 0);
151 200
152 /* ... and finally verify the signature */ 201 /* ... and finally verify the signature */
153 fp = sign_key_fingerprint(keyblob, keybloblen); 202 fp = sign_key_fingerprint(keyblob, keybloblen);
154 if (buf_verify(ses.payload, key, signbuf) == DROPBEAR_SUCCESS) { 203 if (buf_verify(ses.payload, key, sigtype, signbuf) == DROPBEAR_SUCCESS) {
155 dropbear_log(LOG_NOTICE, 204 dropbear_log(LOG_NOTICE,
156 "Pubkey auth succeeded for '%s' with key %s from %s", 205 "Pubkey auth succeeded for '%s' with key %s from %s",
157 ses.authstate.pw_name, fp, svr_ses.addrstring); 206 ses.authstate.pw_name, fp, svr_ses.addrstring);
158 send_msg_userauth_success(); 207 send_msg_userauth_success();
208 #if DROPBEAR_PLUGIN
209 if ((ses.plugin_session != NULL) && (svr_ses.plugin_instance->auth_success != NULL)) {
210 /* Was authenticated through the external plugin. tell plugin that signature verification was ok */
211 svr_ses.plugin_instance->auth_success(ses.plugin_session);
212 }
213 #endif
214
159 } else { 215 } else {
160 dropbear_log(LOG_WARNING, 216 dropbear_log(LOG_WARNING,
161 "Pubkey auth bad signature for '%s' with key %s from %s", 217 "Pubkey auth bad signature for '%s' with key %s from %s",
162 ses.authstate.pw_name, fp, svr_ses.addrstring); 218 ses.authstate.pw_name, fp, svr_ses.addrstring);
163 send_msg_userauth_failure(0, 1); 219 send_msg_userauth_failure(0, 1);
167 out: 223 out:
168 /* cleanup stuff */ 224 /* cleanup stuff */
169 if (signbuf) { 225 if (signbuf) {
170 buf_free(signbuf); 226 buf_free(signbuf);
171 } 227 }
172 if (algo) { 228 if (sigalgo) {
173 m_free(algo); 229 m_free(sigalgo);
174 } 230 }
175 if (key) { 231 if (key) {
176 sign_key_free(key); 232 sign_key_free(key);
177 key = NULL; 233 key = NULL;
178 } 234 }
184 } 240 }
185 241
186 /* Reply that the key is valid for auth, this is sent when the user sends 242 /* Reply that the key is valid for auth, this is sent when the user sends
187 * a straight copy of their pubkey to test, to avoid having to perform 243 * a straight copy of their pubkey to test, to avoid having to perform
188 * expensive signing operations with a worthless key */ 244 * expensive signing operations with a worthless key */
189 static void send_msg_userauth_pk_ok(const char* algo, unsigned int algolen, 245 static void send_msg_userauth_pk_ok(const char* sigalgo, unsigned int sigalgolen,
190 const unsigned char* keyblob, unsigned int keybloblen) { 246 const unsigned char* keyblob, unsigned int keybloblen) {
191 247
192 TRACE(("enter send_msg_userauth_pk_ok")) 248 TRACE(("enter send_msg_userauth_pk_ok"))
193 CHECKCLEARTOWRITE(); 249 CHECKCLEARTOWRITE();
194 250
195 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_PK_OK); 251 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_PK_OK);
196 buf_putstring(ses.writepayload, algo, algolen); 252 buf_putstring(ses.writepayload, sigalgo, sigalgolen);
197 buf_putstring(ses.writepayload, (const char*)keyblob, keybloblen); 253 buf_putstring(ses.writepayload, (const char*)keyblob, keybloblen);
198 254
199 encrypt_packet(); 255 encrypt_packet();
200 TRACE(("leave send_msg_userauth_pk_ok")) 256 TRACE(("leave send_msg_userauth_pk_ok"))
201 257
308 364
309 365
310 /* Checks whether a specified publickey (and associated algorithm) is an 366 /* Checks whether a specified publickey (and associated algorithm) is an
311 * acceptable key for authentication */ 367 * acceptable key for authentication */
312 /* Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */ 368 /* Returns DROPBEAR_SUCCESS if key is ok for auth, DROPBEAR_FAILURE otherwise */
313 static int checkpubkey(const char* algo, unsigned int algolen, 369 static int checkpubkey(const char* keyalgo, unsigned int keyalgolen,
314 const unsigned char* keyblob, unsigned int keybloblen) { 370 const unsigned char* keyblob, unsigned int keybloblen) {
315 371
316 FILE * authfile = NULL; 372 FILE * authfile = NULL;
317 char * filename = NULL; 373 char * filename = NULL;
318 int ret = DROPBEAR_FAILURE; 374 int ret = DROPBEAR_FAILURE;
322 uid_t origuid; 378 uid_t origuid;
323 gid_t origgid; 379 gid_t origgid;
324 380
325 TRACE(("enter checkpubkey")) 381 TRACE(("enter checkpubkey"))
326 382
327 /* check that we can use the algo */
328 if (have_algo(algo, algolen, sshhostkey) == DROPBEAR_FAILURE) {
329 dropbear_log(LOG_WARNING,
330 "Pubkey auth attempt with unknown algo for '%s' from %s",
331 ses.authstate.pw_name, svr_ses.addrstring);
332 goto out;
333 }
334
335 /* check file permissions, also whether file exists */ 383 /* check file permissions, also whether file exists */
336 if (checkpubkeyperms() == DROPBEAR_FAILURE) { 384 if (checkpubkeyperms() == DROPBEAR_FAILURE) {
337 TRACE(("bad authorized_keys permissions, or file doesn't exist")) 385 TRACE(("bad authorized_keys permissions, or file doesn't exist"))
338 goto out; 386 goto out;
339 } 387 }
381 TRACE(("checkpubkey: authorized_keys EOF reached")) 429 TRACE(("checkpubkey: authorized_keys EOF reached"))
382 break; 430 break;
383 } 431 }
384 line_num++; 432 line_num++;
385 433
386 ret = checkpubkey_line(line, line_num, filename, algo, algolen, keyblob, keybloblen); 434 ret = checkpubkey_line(line, line_num, filename, keyalgo, keyalgolen, keyblob, keybloblen);
387 if (ret == DROPBEAR_SUCCESS) { 435 if (ret == DROPBEAR_SUCCESS) {
388 break; 436 break;
389 } 437 }
390 438
391 /* We continue to the next line otherwise */ 439 /* We continue to the next line otherwise */