void sshsocket::writeKnowHost() { QString known_host_dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "known_hosts" ; type = type == LIBSSH2_HOSTKEY_TYPE_RSA ? LIBSSH2_KNOWNHOST_KEY_SSHRSA : LIBSSH2_KNOWNHOST_KEY_SSHDSS; libssh2_knownhost_add(nh, host->hostname().toAscii(), NULL, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW|type, NULL) ; libssh2_knownhost_writefile(nh, known_host_dir.toAscii(), LIBSSH2_KNOWNHOST_FILE_OPENSSH) ; libssh2_knownhost_free(nh); libssh2_session_free(session); socket->close(); delete socket ; }
/* * hostline() * * Parse a single known_host line pre-split into host and key. * */ static int hostline(LIBSSH2_KNOWNHOSTS *hosts, const char *host, size_t hostlen, const char *key, size_t keylen) { const char *p; const char *orig = host; const char *salt = NULL; int rc; int type = LIBSSH2_KNOWNHOST_TYPE_PLAIN; const char *sep = NULL; size_t seplen = 0; char saltbuf[32]; char hostbuf[256]; /* Figure out host format */ if((hostlen >2) && memcmp(host, "|1|", 3)) { /* old style plain text: [name][,][ip-address] for the sake of simplicity, we add them as two hosts with the same key */ size_t scan = hostlen; while(scan && (*host != ',')) { host++; scan--; } if(scan) { sep = host+1; seplen = scan-1; hostlen -= scan; /* deduct what's left to scan from the first host name */ } else host = orig; } else { /* |1|[salt]|[hash] */ type = LIBSSH2_KNOWNHOST_TYPE_SHA1; salt = &host[3]; /* skip the magic marker */ hostlen -= 3; /* deduct the marker */ /* this is where the salt starts, find the end of it */ for(p = salt; *p && (*p != '|'); p++) ; if(*p=='|') { const char *hash = NULL; size_t saltlen = p - salt; if(saltlen >= (sizeof(saltbuf)-1)) return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED; /* weird length */ memcpy(saltbuf, salt, saltlen); saltbuf[saltlen] = 0; /* zero terminate */ salt = saltbuf; /* point to the stack based buffer */ hash = p+1; /* the host hash is after the separator */ /* now make the host point to the hash */ host = hash; hostlen -= saltlen+1; /* deduct the salt and separator */ } else return 0; } /* make some checks that the lenghts seem sensible */ if((keylen < 20) || (seplen >= sizeof(hostbuf)-1) || (hostlen >= sizeof(hostbuf)-1)) return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED; switch(key[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': type |= LIBSSH2_KNOWNHOST_KEY_RSA1; /* Note that the old-style keys (RSA1) aren't truly base64, but we * claim it is for now since we can get away with strcmp()ing the * entire anything anyway! We need to check and fix these to make them * work properly. */ break; case 's': /* ssh-dss or ssh-rsa */ if(!strncmp(key, "ssh-dss", 7)) type |= LIBSSH2_KNOWNHOST_KEY_SSHDSS; else if(!strncmp(key, "ssh-rsa", 7)) type |= LIBSSH2_KNOWNHOST_KEY_SSHRSA; else return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED; /* unknown key type */ key += 7; keylen -= 7; /* skip whitespaces */ while((*key ==' ') || (*key == '\t')) { key++; keylen--; } break; default: /* unknown key format */ return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED; } if(sep) { /* The second host after the comma, add this first. Copy it to the temp buffer and zero terminate */ memcpy(hostbuf, sep, seplen); hostbuf[seplen]=0; rc = libssh2_knownhost_add(hosts, hostbuf, salt, key, keylen, type | LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); if(rc) return rc; } if (!salt) host = orig; memcpy(hostbuf, host, hostlen); hostbuf[hostlen]=0; rc = libssh2_knownhost_add(hosts, hostbuf, salt, key, keylen, type | LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); return rc; }