All pastes #491636 Raw Edit

Stuff

public c v1 · immutable
·published 2007-05-16 19:44 UTC
rendered paste body
****************** 227,578 ****  - void enum_settings_finish(void *handle)- {-     struct enumsettings *e = (struct enumsettings *) handle;-     RegCloseKey(e->key);-     sfree(e);  }  - static void hostkey_regname(char *buffer, const char *hostname,- 			    int port, const char *keytype)  {-     int len;-     strcpy(buffer, keytype);-     strcat(buffer, "@");-     len = strlen(buffer);-     len += sprintf(buffer + len, "%d:", port);-     mungestr(hostname, buffer + strlen(buffer));  }    int verify_host_key(const char *hostname, int port,  		    const char *keytype, const char *key)  {-     char *otherstr, *regname;-     int len;-     HKEY rkey;-     DWORD readlen;-     DWORD type;-     int ret, compare;- -     len = 1 + strlen(key);- -     /*-      * Now read a saved key in from the registry and see what it-      * says.-      */-     otherstr = snewn(len, char);-     regname = snewn(3 * (strlen(hostname) + strlen(keytype)) + 15, char);  -     hostkey_regname(regname, hostname, port, keytype);  -     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",- 		   &rkey) != ERROR_SUCCESS)- 	return 1;		       /* key does not exist in registry */  -     readlen = len;-     ret = RegQueryValueEx(rkey, regname, NULL, &type, otherstr, &readlen);  -     if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA &&- 	!strcmp(keytype, "rsa")) {- 	/*- 	 * Key didn't exist. If the key type is RSA, we'll try- 	 * another trick, which is to look up the _old_ key format- 	 * under just the hostname and translate that.- 	 */- 	char *justhost = regname + 1 + strcspn(regname, ":");- 	char *oldstyle = snewn(len + 10, char);	/* safety margin */- 	readlen = len;- 	ret = RegQueryValueEx(rkey, justhost, NULL, &type,- 			      oldstyle, &readlen);  - 	if (ret == ERROR_SUCCESS && type == REG_SZ) {  	    /*- 	     * The old format is two old-style bignums separated by- 	     * a slash. An old-style bignum is made of groups of- 	     * four hex digits: digits are ordered in sensible- 	     * (most to least significant) order within each group,- 	     * but groups are ordered in silly (least to most)- 	     * order within the bignum. The new format is two- 	     * ordinary C-format hex numbers (0xABCDEFG...XYZ, with- 	     * A nonzero except in the special case 0x0, which- 	     * doesn't appear anyway in RSA keys) separated by a- 	     * comma. All hex digits are lowercase in both formats.  	     */- 	    char *p = otherstr;- 	    char *q = oldstyle;- 	    int i, j;- - 	    for (i = 0; i < 2; i++) {- 		int ndigits, nwords;- 		*p++ = '0';- 		*p++ = 'x';- 		ndigits = strcspn(q, "/");	/* find / or end of string */- 		nwords = ndigits / 4;- 		/* now trim ndigits to remove leading zeros */- 		while (q[(ndigits - 1) ^ 3] == '0' && ndigits > 1)- 		    ndigits--;- 		/* now move digits over to new string */- 		for (j = 0; j < ndigits; j++)- 		    p[ndigits - 1 - j] = q[j ^ 3];- 		p += ndigits;- 		q += nwords * 4;- 		if (*q) {- 		    q++;	       /* eat the slash */- 		    *p++ = ',';	       /* add a comma */- 		}- 		*p = '\0';	       /* terminate the string */- 	    }  - 	    /*- 	     * Now _if_ this key matches, we'll enter it in the new- 	     * format. If not, we'll assume something odd went- 	     * wrong, and hyper-cautiously do nothing.- 	     */- 	    if (!strcmp(otherstr, key))- 		RegSetValueEx(rkey, regname, 0, REG_SZ, otherstr,- 			      strlen(otherstr) + 1);- 	}      }  -     RegCloseKey(rkey);- -     compare = strcmp(otherstr, key);- -     sfree(otherstr);-     sfree(regname);- -     if (ret == ERROR_MORE_DATA ||- 	(ret == ERROR_SUCCESS && type == REG_SZ && compare))- 	return 2;		       /* key is different in registry */-     else if (ret != ERROR_SUCCESS || type != REG_SZ)- 	return 1;		       /* key does not exist in registry */-     else- 	return 0;		       /* key matched OK in registry */  }    void store_host_key(const char *hostname, int port,  		    const char *keytype, const char *key)  {-     char *regname;-     HKEY rkey;  -     regname = snewn(3 * (strlen(hostname) + strlen(keytype)) + 15, char);  -     hostkey_regname(regname, hostname, port, keytype);- -     if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",- 		     &rkey) != ERROR_SUCCESS)- 	return;			       /* key does not exist in registry */-     RegSetValueEx(rkey, regname, 0, REG_SZ, key, strlen(key) + 1);-     RegCloseKey(rkey);- }  - /*-  * Find the random seed file path and store it in `seedpath'.   */- static void get_seedpath(void)- {-     HKEY rkey;-     DWORD type, size;  -     size = sizeof(seedpath);  -     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey) ==- 	ERROR_SUCCESS) {- 	int ret = RegQueryValueEx(rkey, "RandSeedFile",- 				  0, &type, seedpath, &size);- 	if (ret != ERROR_SUCCESS || type != REG_SZ)- 	    seedpath[0] = '\0';- 	RegCloseKey(rkey);-     } else- 	seedpath[0] = '\0';  -     if (!seedpath[0]) {- 	int len, ret;  - 	len =- 	    GetEnvironmentVariable("HOMEDRIVE", seedpath,- 				   sizeof(seedpath));- 	ret =- 	    GetEnvironmentVariable("HOMEPATH", seedpath + len,- 				   sizeof(seedpath) - len);- 	if (ret == 0) {		       /* probably win95; store in \WINDOWS */- 	    GetWindowsDirectory(seedpath, sizeof(seedpath));- 	    len = strlen(seedpath);- 	} else- 	    len += ret;- 	strcpy(seedpath + len, "\\PUTTY.RND");-     }  }    void read_random_seed(noise_consumer_t consumer)  {-     HANDLE seedf;- -     if (!seedpath[0])- 	get_seedpath();- -     seedf = CreateFile(seedpath, GENERIC_READ,- 		       FILE_SHARE_READ | FILE_SHARE_WRITE,- 		       NULL, OPEN_EXISTING, 0, NULL);- -     if (seedf != INVALID_HANDLE_VALUE) {- 	while (1) {- 	    char buf[1024];- 	    DWORD len;  - 	    if (ReadFile(seedf, buf, sizeof(buf), &len, NULL) && len)- 		consumer(buf, len);- 	    else- 		break;- 	}- 	CloseHandle(seedf);      }  }    void write_random_seed(void *data, int len)  {-     HANDLE seedf;- -     if (!seedpath[0])- 	get_seedpath();- -     seedf = CreateFile(seedpath, GENERIC_WRITE, 0,- 		       NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);- -     if (seedf != INVALID_HANDLE_VALUE) {- 	DWORD lenwritten;- - 	WriteFile(seedf, data, len, &lenwritten, NULL);- 	CloseHandle(seedf);-     }- }  - /*-  * Recursively delete a registry key and everything under it.   */- static void registry_recursive_remove(HKEY key)- {-     DWORD i;-     char name[MAX_PATH + 1];-     HKEY subkey;  -     i = 0;-     while (RegEnumKey(key, i, name, sizeof(name)) == ERROR_SUCCESS) {- 	if (RegOpenKey(key, name, &subkey) == ERROR_SUCCESS) {- 	    registry_recursive_remove(subkey);- 	    RegCloseKey(subkey);  	}- 	RegDeleteKey(key, name);      }  }    void cleanup_all(void)  {-     HKEY key;-     int ret;-     char name[MAX_PATH + 1];  -     /* -------------------------------------------------------------      * Wipe out the random seed file.-      */-     if (!seedpath[0])- 	get_seedpath();-     remove(seedpath);  -     /* -------------------------------------------------------------      * Destroy all registry information associated with PuTTY.-      */- -     /*-      * Open the main PuTTY registry key and remove everything in it.-      */-     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &key) ==- 	ERROR_SUCCESS) {- 	registry_recursive_remove(key);- 	RegCloseKey(key);-     }-     /*-      * Now open the parent key and remove the PuTTY main key. Once-      * we've done that, see if the parent key has any other-      * children.-      */-     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_PARENT,- 		   &key) == ERROR_SUCCESS) {- 	RegDeleteKey(key, PUTTY_REG_PARENT_CHILD);- 	ret = RegEnumKey(key, 0, name, sizeof(name));- 	RegCloseKey(key);- 	/*- 	 * If the parent key had no other children, we must delete- 	 * it in its turn. That means opening the _grandparent_- 	 * key.- 	 */- 	if (ret != ERROR_SUCCESS) {- 	    if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_GPARENT,- 			   &key) == ERROR_SUCCESS) {- 		RegDeleteKey(key, PUTTY_REG_GPARENT_CHILD);- 		RegCloseKey(key);- 	    }- 	}-     }-     /*-      * Now we're done.-      */- }--- 373,628 ----+ void enum_settings_finish(void *handle)  {+     DIR *dp = (DIR *)handle;+     closedir(dp);  }  + /*+  * Lines in the host keys file are of the form+  *+  *   type@port:hostname keydata+  *+  * e.g.+  *+  *   rsa@22:foovax.example.org 0x23,0x293487364395345345....2343+  */  int verify_host_key(const char *hostname, int port,  		    const char *keytype, const char *key)  {+     FILE *fp;+     char filename[FILENAME_MAX];+     char *line;+     int ret;  +     make_filename(filename, INDEX_HOSTKEYS, NULL);+     fp = fopen(filename, "r");+     if (!fp)+ 	return 1;		       /* key does not exist */  +     ret = 1;+     while ( (line = fgetline(fp)) ) {+ 	int i;+ 	char *p = line;+ 	char porttext[20];  + 	line[strcspn(line, "\n")] = '\0';   /* strip trailing newline */  + 	i = strlen(keytype);+ 	if (strncmp(p, keytype, i))+ 	    goto done;+ 	p += i;+ + 	if (*p != '@')+ 	    goto done;+ 	p++;+ + 	sprintf(porttext, "%d", port);+ 	i = strlen(porttext);+ 	if (strncmp(p, porttext, i))+ 	    goto done;+ 	p += i;+ + 	if (*p != ':')+ 	    goto done;+ 	p++;+ + 	i = strlen(hostname);+ 	if (strncmp(p, hostname, i))+ 	    goto done;+ 	p += i;+ + 	if (*p != ' ')+ 	    goto done;+ 	p++;    	    /*+ 	 * Found the key. Now just work out whether it's the right+ 	 * one or not.  	     */+ 	if (!strcmp(p, key))+ 	    ret = 0;		       /* key matched OK */+ 	else+ 	    ret = 2;		       /* key mismatch */  + 	done:+ 	sfree(line);+ 	if (ret != 1)+ 	    break;      }  +     fclose(fp);+     return ret;  }    void store_host_key(const char *hostname, int port,  		    const char *keytype, const char *key)  {+     FILE *rfp, *wfp;+     char *newtext, *line;+     int headerlen;+     char filename[FILENAME_MAX], tmpfilename[FILENAME_MAX];  +     newtext = dupprintf("%s@%d:%s %s\n", keytype, port, hostname, key);+     headerlen = 1 + strcspn(newtext, " ");   /* count the space too */  +     /*+      * Open both the old file and a new file.+      */+     make_filename(tmpfilename, INDEX_HOSTKEYS_TMP, NULL);+     wfp = fopen(tmpfilename, "w");+     if (!wfp) {+         char dir[FILENAME_MAX];+ +         make_filename(dir, INDEX_DIR, NULL);+         _mkdir(dir);+         wfp = fopen(tmpfilename, "w");+     }+     if (!wfp)+ 	return;+     make_filename(filename, INDEX_HOSTKEYS, NULL);+     rfp = fopen(filename, "r");  +     /*+      * Copy all lines from the old file to the new one that _don't_+      * involve the same host key identifier as the one we're adding.   */+     if (rfp) {+         while ( (line = fgetline(rfp)) ) {+             if (strncmp(line, newtext, headerlen))+                 fputs(line, wfp);+         }+         fclose(rfp);+     }  +     /*+      * Now add the new line at the end.+      */+     fputs(newtext, wfp);  +     fclose(wfp);  +     _unlink(filename);+     rename(tmpfilename, filename);  +     sfree(newtext);  }    void read_random_seed(noise_consumer_t consumer)  {+     int fd;+     char fname[FILENAME_MAX];  +     make_filename(fname, INDEX_RANDSEED, NULL);+     fd = _open(fname, _O_RDONLY);+     if (fd) {+ 	char buf[512];+ 	int ret;+ 	while ( (ret = _read(fd, buf, sizeof(buf))) > 0)+ 	    consumer(buf, ret);+ 	_close(fd);      }  }    void write_random_seed(void *data, int len)  {+     int fd;+     char fname[FILENAME_MAX];  +     make_filename(fname, INDEX_RANDSEED, NULL);+     /*+      * Don't truncate the random seed file if it already exists; if+      * something goes wrong half way through writing it, it would+      * be better to leave the old data there than to leave it empty.   */+     fd = _open(fname, _O_CREAT | _O_WRONLY, 0600);+     if (fd < 0) {+ 	char dir[FILENAME_MAX];  + 	make_filename(dir, INDEX_DIR, NULL);+ 	_mkdir(dir);+ 	fd = _open(fname, _O_CREAT | _O_WRONLY, 0600);  	}+ +     while (len > 0) {+ 	int ret = _write(fd, data, len);+ 	if (ret <= 0) break;+ 	len -= ret;+ 	data = (char *)data + len;      }+ +     _close(fd);  }    void cleanup_all(void)  {+ }