X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=windows%2Fwinsecur.c;h=cba7d60a196993a742851deb9a49373644c93b91;hb=095072fa46b2d7b8beafaddb2f873d2f500a1e10;hp=91ce7e92f147d1004a1920a8c64e1584ac73f7fa;hpb=70f641f84527fcb5a2ccbff7c8e238003ff2d2f3;p=PuTTY.git diff --git a/windows/winsecur.c b/windows/winsecur.c index 91ce7e92..cba7d60a 100644 --- a/windows/winsecur.c +++ b/windows/winsecur.c @@ -44,6 +44,9 @@ PSID get_user_sid(void) DWORD toklen, sidlen; PSID sid = NULL, ret = NULL; + if (usersid) + return usersid; + if (!got_advapi()) goto cleanup; @@ -73,7 +76,7 @@ PSID get_user_sid(void) /* Success. Move sid into the return value slot, and null it out * to stop the cleanup code freeing it. */ - ret = sid; + ret = usersid = sid; sid = NULL; cleanup: @@ -89,17 +92,17 @@ PSID get_user_sid(void) return ret; } -int getsids(char *error) +int getsids(char **error) { - SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY; - SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY; - int ret; + SID_IDENTIFIER_AUTHORITY world_auth = { SECURITY_WORLD_SID_AUTHORITY }; + SID_IDENTIFIER_AUTHORITY nt_auth = { SECURITY_NT_AUTHORITY }; + int ret = FALSE; - error=NULL; + *error = NULL; if (!usersid) { if ((usersid = get_user_sid()) == NULL) { - error = dupprintf("unable to construct SID for current user: %s", + *error = dupprintf("unable to construct SID for current user: %s", win_strerror(GetLastError())); goto cleanup; } @@ -108,7 +111,7 @@ int getsids(char *error) if (!worldsid) { if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &worldsid)) { - error = dupprintf("unable to construct SID for world: %s", + *error = dupprintf("unable to construct SID for world: %s", win_strerror(GetLastError())); goto cleanup; } @@ -117,20 +120,16 @@ int getsids(char *error) if (!networksid) { if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID, 0, 0, 0, 0, 0, 0, 0, &networksid)) { - error = dupprintf("unable to construct SID for " + *error = dupprintf("unable to construct SID for " "local same-user access only: %s", win_strerror(GetLastError())); goto cleanup; } } - ret=TRUE; + ret = TRUE; cleanup: - if (ret) { - sfree(error); - error = NULL; - } return ret; } @@ -149,7 +148,7 @@ int make_private_security_descriptor(DWORD permissions, *acl = NULL; *error = NULL; - if (!getsids(*error)) + if (!getsids(error)) goto cleanup; memset(ea, 0, sizeof(ea)); @@ -221,16 +220,16 @@ int make_private_security_descriptor(DWORD permissions, return ret; } -int setprocessacl(char *error) +static int really_restrict_process_acl(char **error) { EXPLICIT_ACCESS ea[2]; int acl_err; int ret=FALSE; PACL acl = NULL; - static const nastyace=WRITE_DAC | WRITE_OWNER | + static const DWORD nastyace=WRITE_DAC | WRITE_OWNER | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | - PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | + PROCESS_DUP_HANDLE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_SUSPEND_RESUME; @@ -257,8 +256,8 @@ int setprocessacl(char *error) acl_err = p_SetEntriesInAclA(2, ea, NULL, &acl); if (acl_err != ERROR_SUCCESS || acl == NULL) { - error = dupprintf("unable to construct ACL: %s", - win_strerror(acl_err)); + *error = dupprintf("unable to construct ACL: %s", + win_strerror(acl_err)); goto cleanup; } @@ -266,8 +265,8 @@ int setprocessacl(char *error) (GetCurrentProcess(), SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, usersid, NULL, acl, NULL)) { - error=dupprintf("Unable to set process ACL: %s", - win_strerror(GetLastError())); + *error = dupprintf("Unable to set process ACL: %s", + win_strerror(GetLastError())); goto cleanup; } @@ -282,5 +281,37 @@ int setprocessacl(char *error) } } return ret; -} +} #endif /* !defined NO_SECURITY */ + +/* + * Lock down our process's ACL, to present an obstacle to malware + * trying to write into its memory. This can't be a full defence, + * because well timed malware could attack us before this code runs - + * even if it was unconditionally run at the very start of main(), + * which we wouldn't want to do anyway because it turns out in practie + * that interfering with other processes in this way has significant + * non-infringing uses on Windows (e.g. screen reader software). + * + * If we've been requested to do this and are unsuccessful, bomb out + * via modalfatalbox rather than continue in a less protected mode. + * + * This function is intentionally outside the #ifndef NO_SECURITY that + * covers the rest of this file, because when PuTTY is compiled + * without the ability to restrict its ACL, we don't want it to + * silently pretend to honour the instruction to do so. + */ +void restrict_process_acl(void) +{ + char *error = NULL; + int ret; + +#if !defined NO_SECURITY + ret = really_restrict_process_acl(&error); +#else + ret = FALSE; + error = dupstr("ACL restrictions not compiled into this binary"); +#endif + if (!ret) + modalfatalbox("Could not restrict process ACL: %s", error); +}