comparison cli-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 d18fa38c1fd4
children 8dc43b30c6bf
comparison
equal deleted inserted replaced
1643:b59623a64678 1733:d529a52b2f7c
31 #include "runopts.h" 31 #include "runopts.h"
32 #include "auth.h" 32 #include "auth.h"
33 #include "agentfwd.h" 33 #include "agentfwd.h"
34 34
35 #if DROPBEAR_CLI_PUBKEY_AUTH 35 #if DROPBEAR_CLI_PUBKEY_AUTH
36 static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign); 36 static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign);
37 37
38 /* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request. 38 /* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request.
39 * We use it to remove the key we tried from the list */ 39 * We use it to remove the key we tried from the list */
40 void cli_pubkeyfail() { 40 void cli_pubkeyfail() {
41 m_list_elem *iter; 41 m_list_elem *iter;
57 m_list_elem *iter; 57 m_list_elem *iter;
58 buffer* keybuf = NULL; 58 buffer* keybuf = NULL;
59 char* algotype = NULL; 59 char* algotype = NULL;
60 unsigned int algolen; 60 unsigned int algolen;
61 enum signkey_type keytype; 61 enum signkey_type keytype;
62 enum signature_type sigtype;
62 unsigned int remotelen; 63 unsigned int remotelen;
63 64
64 TRACE(("enter recv_msg_userauth_pk_ok")) 65 TRACE(("enter recv_msg_userauth_pk_ok"))
65 66
66 algotype = buf_getstring(ses.payload, &algolen); 67 algotype = buf_getstring(ses.payload, &algolen);
67 keytype = signkey_type_from_name(algotype, algolen); 68 sigtype = signature_type_from_name(algotype, algolen);
68 TRACE(("recv_msg_userauth_pk_ok: type %d", keytype)) 69 keytype = signkey_type_from_signature(sigtype);
70 TRACE(("recv_msg_userauth_pk_ok: type %d", sigtype))
69 m_free(algotype); 71 m_free(algotype);
70 72
71 keybuf = buf_new(MAX_PUBKEY_SIZE); 73 keybuf = buf_new(MAX_PUBKEY_SIZE);
72 74
73 remotelen = buf_getint(ses.payload); 75 remotelen = buf_getint(ses.payload);
110 112
111 if (iter != NULL) { 113 if (iter != NULL) {
112 TRACE(("matching key")) 114 TRACE(("matching key"))
113 /* XXX TODO: if it's an encrypted key, here we ask for their 115 /* XXX TODO: if it's an encrypted key, here we ask for their
114 * password */ 116 * password */
115 send_msg_userauth_pubkey((sign_key*)iter->item, keytype, 1); 117 send_msg_userauth_pubkey((sign_key*)iter->item, sigtype, 1);
116 } else { 118 } else {
117 TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part")) 119 TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part"))
118 } 120 }
119 121
120 TRACE(("leave recv_msg_userauth_pk_ok")) 122 TRACE(("leave recv_msg_userauth_pk_ok"))
121 } 123 }
122 124
123 void cli_buf_put_sign(buffer* buf, sign_key *key, int type, 125 static void cli_buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
124 const buffer *data_buf) { 126 const buffer *data_buf) {
125 #if DROPBEAR_CLI_AGENTFWD 127 #if DROPBEAR_CLI_AGENTFWD
128 // TODO: rsa-sha256 agent
126 if (key->source == SIGNKEY_SOURCE_AGENT) { 129 if (key->source == SIGNKEY_SOURCE_AGENT) {
127 /* Format the agent signature ourselves, as buf_put_sign would. */ 130 /* Format the agent signature ourselves, as buf_put_sign would. */
128 buffer *sigblob; 131 buffer *sigblob;
129 sigblob = buf_new(MAX_PUBKEY_SIZE); 132 sigblob = buf_new(MAX_PUBKEY_SIZE);
130 agent_buf_sign(sigblob, key, data_buf); 133 agent_buf_sign(sigblob, key, data_buf, sigtype);
131 buf_putbufstring(buf, sigblob); 134 buf_putbufstring(buf, sigblob);
132 buf_free(sigblob); 135 buf_free(sigblob);
133 } else 136 } else
134 #endif /* DROPBEAR_CLI_AGENTFWD */ 137 #endif /* DROPBEAR_CLI_AGENTFWD */
135 { 138 {
136 buf_put_sign(buf, key, type, data_buf); 139 buf_put_sign(buf, key, sigtype, data_buf);
137 } 140 }
138 } 141 }
139 142
140 /* TODO: make it take an agent reference to use as well */ 143 static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign) {
141 static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
142 144
143 const char *algoname = NULL; 145 const char *algoname = NULL;
144 unsigned int algolen; 146 unsigned int algolen;
145 buffer* sigbuf = NULL; 147 buffer* sigbuf = NULL;
146 148 enum signkey_type keytype = signkey_type_from_signature(sigtype);
147 TRACE(("enter send_msg_userauth_pubkey")) 149
150 TRACE(("enter send_msg_userauth_pubkey sigtype %d", sigtype))
148 CHECKCLEARTOWRITE(); 151 CHECKCLEARTOWRITE();
149 152
150 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST); 153 buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
151 154
152 buf_putstring(ses.writepayload, cli_opts.username, 155 buf_putstring(ses.writepayload, cli_opts.username,
158 buf_putstring(ses.writepayload, AUTH_METHOD_PUBKEY, 161 buf_putstring(ses.writepayload, AUTH_METHOD_PUBKEY,
159 AUTH_METHOD_PUBKEY_LEN); 162 AUTH_METHOD_PUBKEY_LEN);
160 163
161 buf_putbyte(ses.writepayload, realsign); 164 buf_putbyte(ses.writepayload, realsign);
162 165
163 algoname = signkey_name_from_type(type, &algolen); 166 algoname = signature_name_from_type(sigtype, &algolen);
164
165 buf_putstring(ses.writepayload, algoname, algolen); 167 buf_putstring(ses.writepayload, algoname, algolen);
166 buf_put_pub_key(ses.writepayload, key, type); 168 buf_put_pub_key(ses.writepayload, key, keytype);
167 169
168 if (realsign) { 170 if (realsign) {
169 TRACE(("realsign")) 171 TRACE(("realsign"))
170 /* We put the signature as well - this contains string(session id), then 172 /* We put the signature as well - this contains string(session id), then
171 * the contents of the write payload to this point */ 173 * the contents of the write payload to this point */
172 sigbuf = buf_new(4 + ses.session_id->len + ses.writepayload->len); 174 sigbuf = buf_new(4 + ses.session_id->len + ses.writepayload->len);
173 buf_putbufstring(sigbuf, ses.session_id); 175 buf_putbufstring(sigbuf, ses.session_id);
174 buf_putbytes(sigbuf, ses.writepayload->data, ses.writepayload->len); 176 buf_putbytes(sigbuf, ses.writepayload->data, ses.writepayload->len);
175 cli_buf_put_sign(ses.writepayload, key, type, sigbuf); 177 cli_buf_put_sign(ses.writepayload, key, sigtype, sigbuf);
176 buf_free(sigbuf); /* Nothing confidential in the buffer */ 178 buf_free(sigbuf); /* Nothing confidential in the buffer */
177 } 179 }
178 180
179 encrypt_packet(); 181 encrypt_packet();
180 TRACE(("leave send_msg_userauth_pubkey")) 182 TRACE(("leave send_msg_userauth_pubkey"))
181 } 183 }
182 184
183 /* Returns 1 if a key was tried */ 185 /* Returns 1 if a key was tried */
184 int cli_auth_pubkey() { 186 int cli_auth_pubkey() {
185 187 enum signature_type sigtype = DROPBEAR_SIGNATURE_NONE;
186 TRACE(("enter cli_auth_pubkey")) 188 TRACE(("enter cli_auth_pubkey"))
187 189
188 #if DROPBEAR_CLI_AGENTFWD 190 #if DROPBEAR_CLI_AGENTFWD
189 if (!cli_opts.agent_keys_loaded) { 191 if (!cli_opts.agent_keys_loaded) {
190 /* get the list of available keys from the agent */ 192 /* get the list of available keys from the agent */
191 cli_load_agent_keys(cli_opts.privkeys); 193 cli_load_agent_keys(cli_opts.privkeys);
192 cli_opts.agent_keys_loaded = 1; 194 cli_opts.agent_keys_loaded = 1;
195 TRACE(("cli_auth_pubkey: agent keys loaded"))
193 } 196 }
194 #endif 197 #endif
198
199 /* iterate through privkeys to remove ones not allowed in server-sig-algs */
200 while (cli_opts.privkeys->first) {
201 sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
202 if (cli_ses.server_sig_algs) {
203 #if DROPBEAR_RSA
204 if (key->type == DROPBEAR_SIGNKEY_RSA) {
205 #if DROPBEAR_RSA_SHA256
206 if (buf_has_algo(cli_ses.server_sig_algs, SSH_SIGNATURE_RSA_SHA256)
207 == DROPBEAR_SUCCESS) {
208 sigtype = DROPBEAR_SIGNATURE_RSA_SHA256;
209 TRACE(("server-sig-algs allows rsa sha256"))
210 break;
211 }
212 #endif /* DROPBEAR_RSA_SHA256 */
213 #if DROPBEAR_RSA_SHA1
214 if (buf_has_algo(cli_ses.server_sig_algs, SSH_SIGNKEY_RSA)
215 == DROPBEAR_SUCCESS) {
216 sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
217 TRACE(("server-sig-algs allows rsa sha1"))
218 break;
219 }
220 #endif /* DROPBEAR_RSA_SHA256 */
221 } else
222 #endif /* DROPBEAR_RSA */
223 {
224 /* Not RSA */
225 const char *name = NULL;
226 sigtype = signature_type_from_signkey(key->type);
227 name = signature_name_from_type(sigtype, NULL);
228 if (buf_has_algo(cli_ses.server_sig_algs, name)
229 == DROPBEAR_SUCCESS) {
230 TRACE(("server-sig-algs allows %s", name))
231 break;
232 }
233 }
234
235 /* No match, skip this key */
236 TRACE(("server-sig-algs no match keytype %d, skipping", key->type))
237 key = list_remove(cli_opts.privkeys->first);
238 sign_key_free(key);
239 continue;
240 } else {
241 /* Server didn't provide a server-sig-algs list, we'll
242 assume all except rsa-sha256 are OK. */
243 #if DROPBEAR_RSA
244 if (key->type == DROPBEAR_SIGNKEY_RSA) {
245 #if DROPBEAR_RSA_SHA1
246 sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
247 TRACE(("no server-sig-algs, using rsa sha1"))
248 break;
249 #else
250 /* only support rsa-sha256, skip this key */
251 TRACE(("no server-sig-algs, skipping rsa sha256"))
252 key = list_remove(cli_opts.privkeys->first);
253 sign_key_free(key);
254 continue;
255 #endif
256 } /* key->type == DROPBEAR_SIGNKEY_RSA */
257 #endif /* DROPBEAR_RSA */
258 sigtype = signature_type_from_signkey(key->type);
259 TRACE(("no server-sig-algs, using key"))
260 break;
261 }
262 }
195 263
196 if (cli_opts.privkeys->first) { 264 if (cli_opts.privkeys->first) {
197 sign_key * key = (sign_key*)cli_opts.privkeys->first->item; 265 sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
198 /* Send a trial request */ 266 /* Send a trial request */
199 send_msg_userauth_pubkey(key, key->type, 0); 267 send_msg_userauth_pubkey(key, sigtype, 0);
200 cli_ses.lastprivkey = key; 268 cli_ses.lastprivkey = key;
201 TRACE(("leave cli_auth_pubkey-success")) 269 TRACE(("leave cli_auth_pubkey-success"))
202 return 1; 270 return 1;
203 } else { 271 } else {
204 /* no more keys left */ 272 /* no more keys left */