int ssh_msg_recv(int fd, Buffer *m) { u_char buf[4]; ssize_t res; u_int msg_len; debug3("ssh_msg_recv entering"); res = atomicio(read, fd, buf, sizeof(buf)); if (res != sizeof(buf)) { if (res == 0) return -1; fatal("ssh_msg_recv: read: header %ld", (long)res); } msg_len = GET_32BIT(buf); if (msg_len > 256 * 1024) fatal("ssh_msg_recv: read: bad msg_len %u", msg_len); buffer_clear(m); buffer_append_space(m, msg_len); res = atomicio(read, fd, buffer_ptr(m), msg_len); if (res != msg_len) fatal("ssh_msg_recv: read: %ld != msg_len", (long)res); return 0; }
static void answer_msg(void *msgv) { unsigned char *msg = (unsigned char *)msgv; unsigned msglen; void *reply; int replylen; msglen = GET_32BIT(msg); if (msglen > AGENT_MAX_MSGLEN) { reply = pageant_failure_msg(&replylen); } else { reply = pageant_handle_msg(msg + 4, msglen, &replylen, NULL, NULL); if (replylen > AGENT_MAX_MSGLEN) { smemclr(reply, replylen); sfree(reply); reply = pageant_failure_msg(&replylen); } } /* * Windows Pageant answers messages in place, by overwriting the * input message buffer. */ memcpy(msg, reply, replylen); smemclr(reply, replylen); sfree(reply); }
static int agent_select_result(int fd, int event) { int ret; struct agent_connection *conn; assert(event == 1); /* not selecting for anything but R */ conn = find234(agent_connections, &fd, agent_connfind); if (!conn) { uxsel_del(fd); return 1; } ret = read(fd, conn->retbuf+conn->retlen, conn->retsize-conn->retlen); if (ret <= 0) { if (conn->retbuf != conn->sizebuf) sfree(conn->retbuf); conn->retbuf = NULL; conn->retlen = 0; goto done; } conn->retlen += ret; if (conn->retsize == 4 && conn->retlen == 4) { conn->retsize = GET_32BIT(conn->retbuf); if (conn->retsize <= 0) { conn->retbuf = NULL; conn->retlen = 0; goto done; } conn->retsize += 4; assert(conn->retbuf == conn->sizebuf); conn->retbuf = snewn(conn->retsize, char); memcpy(conn->retbuf, conn->sizebuf, 4); }
int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info) { struct user_desc info; struct n_desc_struct *desc; int idx; if (get_user(idx, &u_info->entry_number)) return -EFAULT; if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) return -EINVAL; desc = ((struct n_desc_struct *)t->tls_array) + idx - GDT_ENTRY_TLS_MIN; memset(&info, 0, sizeof(struct user_desc)); info.entry_number = idx; info.base_addr = GET_BASE(desc); info.limit = GET_LIMIT(desc); info.seg_32bit = GET_32BIT(desc); info.contents = GET_CONTENTS(desc); info.read_exec_only = !GET_WRITABLE(desc); info.limit_in_pages = GET_LIMIT_PAGES(desc); info.seg_not_present = !GET_PRESENT(desc); info.useable = GET_USEABLE(desc); info.lm = GET_LONGMODE(desc); if (copy_to_user(u_info, &info, sizeof(info))) return -EFAULT; return 0; }
static void get_msg(int fd, Buffer *m) { u_int len, msg_len; unsigned char buf[4096]; len = atomicio(read, fd, buf, 4); if (len == 0) fatal("Connection closed"); else if (len == -1) fatal("Couldn't read packet: %s", strerror(errno)); msg_len = GET_32BIT(buf); if (msg_len > 256 * 1024) fatal("Received message too long %u", msg_len); while (msg_len) { len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf))); if (len == 0) fatal("Connection closed"); else if (len == -1) fatal("Couldn't read packet: %s", strerror(errno)); msg_len -= len; buffer_append(m, buf, len); } }
static int ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply) { int l, len; char buf[1024]; /* Get the length of the message, and format it in the buffer. */ len = buffer_len(request); PUT_32BIT(buf, len); /* Send the length and then the packet to the agent. */ if (atomicio(write, auth->fd, buf, 4) != 4 || atomicio(write, auth->fd, buffer_ptr(request), buffer_len(request)) != buffer_len(request)) { error("Error writing to authentication socket."); return 0; } /* * Wait for response from the agent. First read the length of the * response packet. */ len = 4; while (len > 0) { l = read(auth->fd, buf + 4 - len, len); if (l == -1 && (errno == EAGAIN || errno == EINTR)) continue; if (l <= 0) { error("Error reading response length from authentication socket."); return 0; } len -= l; } /* Extract the length, and check it for sanity. */ len = GET_32BIT(buf); if (len > 256 * 1024) fatal("Authentication response too long: %d", len); /* Read the rest of the response in to the buffer. */ buffer_clear(reply); while (len > 0) { l = len; if (l > sizeof(buf)) l = sizeof(buf); l = read(auth->fd, buf, l); if (l == -1 && (errno == EAGAIN || errno == EINTR)) continue; if (l <= 0) { error("Error reading response from authentication socket."); return 0; } buffer_append(reply, buf, l); len -= l; } return 1; }
int buffer_get_int_ret(u_int *ret, Buffer *buffer) { u_char buf[4]; if (buffer_get_ret(buffer, (char *) buf, 4) == -1) return (-1); *ret = GET_32BIT(buf); return (0); }
static int _read_int(struct iovec *iov, int *ival) { iov->iov_len -= 4; if (iov->iov_len < 0) return (-1); *ival = GET_32BIT((u_char *)iov->iov_base); iov->iov_base += 4; return (0); }
/* * This parses an exported name, extracting the mechanism specific portion * to use for ACL checking. It verifies that the name belongs the mechanism * originally selected. */ static OM_uint32 ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) { u_char *tok; OM_uint32 offset; OM_uint32 oidl; tok = ename->value; /* * Check that ename is long enough for all of the fixed length * header, and that the initial ID bytes are correct */ if (ename->length < 6 || memcmp(tok, "\x04\x01", 2) != 0) return GSS_S_FAILURE; /* * Extract the OID, and check it. Here GSSAPI breaks with tradition * and does use the OID type and length bytes. To confuse things * there are two lengths - the first including these, and the * second without. */ oidl = GET_16BIT(tok+2); /* length including next two bytes */ oidl = oidl-2; /* turn it into the _real_ length of the variable OID */ /* * Check the BER encoding for correct type and length, that the * string is long enough and that the OID matches that in our context */ if (tok[4] != 0x06 || tok[5] != oidl || ename->length < oidl+6 || !ssh_gssapi_check_oid(ctx, tok+6, oidl)) return GSS_S_FAILURE; offset = oidl+6; if (ename->length < offset+4) return GSS_S_FAILURE; name->length = GET_32BIT(tok+offset); offset += 4; if (ename->length < offset+name->length) return GSS_S_FAILURE; name->value = xmalloc(name->length+1); memcpy(name->value, tok+offset,name->length); ((char *)name->value)[name->length] = 0; return GSS_S_COMPLETE; }
static int handle_from_string(char *handle, u_int hlen) { int val; if (hlen != sizeof(int32_t)) return -1; val = GET_32BIT(handle); if (handle_is_ok(val, HANDLE_FILE) || handle_is_ok(val, HANDLE_DIR)) return val; return -1; }
static void getstring(char **data, int *datalen, char **p, int *length) { *p = NULL; if (*datalen < 4) return; *length = GET_32BIT(*data); *datalen -= 4; *data += 4; if (*datalen < *length) return; *p = *data; *data += *length; *datalen -= *length; }
void mp_unlinearize_msb_first(MP_INT * value, const unsigned char *buf, unsigned int len) { unsigned int i; mpz_set_ui(value, 0); for (i = 0; i + 4 <= len; i += 4) { unsigned long limb = GET_32BIT(buf + i); mpz_mul_2exp(value, value, 32); mpz_add_ui(value, value, limb); } for (; i < len; i++) { mpz_mul_2exp(value, value, 8); mpz_add_ui(value, value, buf[i]); } }
void mm_request_receive(int socket, Buffer *m) { u_char buf[4]; u_int msg_len; ssize_t res; debug3("%s entering", __func__); res = atomicio(read, socket, buf, sizeof(buf)); if (res != sizeof(buf)) { if (res == 0) fatal_cleanup(); fatal("%s: read: %ld", __func__, (long)res); } msg_len = GET_32BIT(buf); if (msg_len > 256 * 1024) fatal("%s: read: bad msg_len %d", __func__, msg_len); buffer_clear(m); buffer_append_space(m, msg_len); res = atomicio(read, socket, buffer_ptr(m), msg_len); if (res != msg_len) fatal("%s: read: %ld != msg_len", __func__, (long)res); }
static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, char **commentptr, char *passphrase, const char **error) { unsigned char buf[16384]; unsigned char keybuf[16]; int len; int i, j, ciphertype; int ret = 0; struct MD5Context md5c; char *comment; *error = NULL; /* Slurp the whole file (minus the header) into a buffer. */ len = fread(buf, 1, sizeof(buf), fp); fclose(fp); if (len < 0 || len == sizeof(buf)) { *error = "error reading file"; goto end; /* file too big or not read */ } i = 0; *error = "file format error"; /* * A zero byte. (The signature includes a terminating NUL.) */ if (len - i < 1 || buf[i] != 0) goto end; i++; /* One byte giving encryption type, and one reserved uint32. */ if (len - i < 1) goto end; ciphertype = buf[i]; if (ciphertype != 0 && ciphertype != SSH_CIPHER_3DES) goto end; i++; if (len - i < 4) goto end; /* reserved field not present */ if (buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0 || buf[i + 3] != 0) goto end; /* reserved field nonzero, panic! */ i += 4; /* Now the serious stuff. An ordinary SSH-1 public key. */ j = makekey(buf + i, len - i, key, NULL, 1); if (j < 0) goto end; /* overran */ i += j; /* Next, the comment field. */ j = toint(GET_32BIT(buf + i)); i += 4; if (j < 0 || len - i < j) goto end; comment = snewn(j + 1, char); if (comment) { memcpy(comment, buf + i, j); comment[j] = '\0'; } i += j; if (commentptr) *commentptr = dupstr(comment); if (key) key->comment = comment; else sfree(comment); if (pub_only) { ret = 1; goto end; } if (!key) { ret = ciphertype != 0; *error = NULL; goto end; } /* * Decrypt remainder of buffer. */ if (ciphertype) { MD5Init(&md5c); MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase)); MD5Final(keybuf, &md5c); des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7); smemclr(keybuf, sizeof(keybuf)); /* burn the evidence */ } /* * We are now in the secret part of the key. The first four * bytes should be of the form a, b, a, b. */ if (len - i < 4) goto end; if (buf[i] != buf[i + 2] || buf[i + 1] != buf[i + 3]) { *error = "wrong passphrase"; ret = -1; goto end; } i += 4; /* * After that, we have one further bignum which is our * decryption exponent, and then the three auxiliary values * (iqmp, q, p). */ j = makeprivate(buf + i, len - i, key); if (j < 0) goto end; i += j; j = ssh1_read_bignum(buf + i, len - i, &key->iqmp); if (j < 0) goto end; i += j; j = ssh1_read_bignum(buf + i, len - i, &key->q); if (j < 0) goto end; i += j; j = ssh1_read_bignum(buf + i, len - i, &key->p); if (j < 0) goto end; i += j; if (!rsa_verify(key)) { *error = "rsa_verify failed"; freersakey(key); ret = 0; } else ret = 1; end: smemclr(buf, sizeof(buf)); /* burn the evidence */ return ret; }
static void process(void) { u_int msg_len; u_int buf_len; u_int consumed; u_int type; u_char *cp; buf_len = buffer_len(&iqueue); if (buf_len < 5) return; /* Incomplete message. */ cp = buffer_ptr(&iqueue); msg_len = GET_32BIT(cp); if (msg_len > 256 * 1024) { error("bad message "); exit(11); } if (buf_len < msg_len + 4) return; buffer_consume(&iqueue, 4); buf_len -= 4; type = buffer_get_char(&iqueue); switch (type) { case SSH2_FXP_INIT: process_init(); break; case SSH2_FXP_OPEN: process_open(); break; case SSH2_FXP_CLOSE: process_close(); break; case SSH2_FXP_READ: process_read(); break; case SSH2_FXP_WRITE: process_write(); break; case SSH2_FXP_LSTAT: process_lstat(); break; case SSH2_FXP_FSTAT: process_fstat(); break; case SSH2_FXP_SETSTAT: process_setstat(); break; case SSH2_FXP_FSETSTAT: process_fsetstat(); break; case SSH2_FXP_OPENDIR: process_opendir(); break; case SSH2_FXP_READDIR: process_readdir(); break; case SSH2_FXP_REMOVE: process_remove(); break; case SSH2_FXP_MKDIR: process_mkdir(); break; case SSH2_FXP_RMDIR: process_rmdir(); break; case SSH2_FXP_REALPATH: process_realpath(); break; case SSH2_FXP_STAT: process_stat(); break; case SSH2_FXP_RENAME: process_rename(); break; case SSH2_FXP_READLINK: process_readlink(); break; case SSH2_FXP_SYMLINK: process_symlink(); break; case SSH2_FXP_EXTENDED: process_extended(); break; default: error("Unknown message %d", type); break; } /* discard the remaining bytes from the current packet */ if (buf_len < buffer_len(&iqueue)) fatal("iqueue grows"); consumed = buf_len - buffer_len(&iqueue); if (msg_len < consumed) fatal("msg_len %d < consumed %d", msg_len, consumed); if (msg_len > consumed) buffer_consume(&iqueue, msg_len - consumed); }
int main (int argc, const char* argv[]) { HWND hwnd; char *mapname; HANDLE filemap; unsigned char *p, *ret; int id, retlen, inlen, n, rmode, r = RET_NORESPONSE; COPYDATASTRUCT cds; void *in; if (argc < 2) return RET_ERR_BADARGS; hwnd = FindWindow("Pageant", "Pageant"); if (!hwnd) return RET_ERR_UNAVAILABLE; rmode = _setmode(_fileno(stdin), _O_BINARY); if (rmode == -1) return RET_ERR_BINSTDIN; rmode = _setmode(_fileno(stdout), _O_BINARY); if (rmode == -1) return RET_ERR_BINSTDOUT; inlen = atoi(argv[1]); in = malloc(inlen); n = fread(in, 1, inlen, stdin); if (n != inlen) { free(in); return RET_ERR_BADLEN; } mapname = malloc(32); n = sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId()); filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, AGENT_MAX_MSGLEN, mapname); if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) { free(in); free(mapname); return RET_ERR_NOMAP; } p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); memcpy(p, in, inlen); cds.dwData = AGENT_COPYDATA_ID; cds.cbData = 1 + n; cds.lpData = mapname; id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); if (id > 0) { r = RET_RESPONSE; retlen = 4 + GET_32BIT(p); fwrite(p, 1, retlen, stdout); } free(in); free(mapname); UnmapViewOfFile(p); CloseHandle(filemap); return r; }
// "in" means "to pageant", "out" means "from pageant". Sorry. int send_request_to_pageant(byte *inbuf, int inbytes, byte *outbuf, int outbuflen) { EPRINTF(3, "Sending %d bytes to pageant.\n", inbytes); if (inbytes < 4) { EPRINTF(0, "Pageant-bound message too short (%d bytes).\n", inbytes); return 0; } int claimed_inbytes = GET_32BIT(inbuf); if (inbytes != claimed_inbytes + 4) { EPRINTF(0, "Pageant-bound message is %d bytes long, but it " "*says* it has %d=%d+4 bytes in it.\n", inbytes, claimed_inbytes+4, claimed_inbytes); return 0; } EPRINTF(5, "Message to pageant (%d bytes):\n", inbytes); print_buf(5, inbuf, inbytes); HWND hwnd; hwnd = FindWindow("Pageant", "Pageant"); if (!hwnd) { EPRINTF(0, "Can't FindWindow(\"Pageant\"...) - " "is pageant running?. (GetLastError is %x)\n", (unsigned) GetLastError()); return 0; } char mapname[512]; sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId()); PSECURITY_ATTRIBUTES psa = NULL; #ifndef NO_SECURITY SECURITY_ATTRIBUTES sa = {0}; if (advapi_initialised || init_advapi()) { /* * Set the security info for the file mapping to the same as Pageant's * process, to make sure Pageant's SID check will pass. */ DWORD dwProcId = 0; GetWindowThreadProcessId(hwnd, &dwProcId); HANDLE proc = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcId); if (proc != NULL) { sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; GetSecurityInfo(proc, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, (PSECURITY_DESCRIPTOR*)&sa.lpSecurityDescriptor); if (sa.lpSecurityDescriptor) { psa = &sa; } } CloseHandle(proc); } else { EPRINTF(0, "Couldn't initialize advapi.\n"); } #endif /* NO_SECURITY */ HANDLE filemap = CreateFileMapping(INVALID_HANDLE_VALUE, psa, PAGE_READWRITE, 0, AGENT_MAX_MSGLEN, mapname); if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) { EPRINTF(0, "Can't CreateFileMapping.\n"); return 0; } byte *shmem = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); memcpy(shmem, inbuf, inbytes); COPYDATASTRUCT cds; cds.dwData = AGENT_COPYDATA_ID; cds.cbData = 1 + strlen(mapname); cds.lpData = mapname; int id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); int retlen = 0; if (id > 0) { retlen = 4 + GET_32BIT(shmem); if (retlen > outbuflen) { EPRINTF(0, "Buffer too small to contain reply from pageant.\n"); return 0; } memcpy(outbuf, shmem, retlen); EPRINTF(5, "Reply from pageant (%d bytes):\n", retlen); print_buf(5, outbuf, retlen); } else { EPRINTF(0, "Couldn't SendMessage().\n"); return 0; } // enum_windows(); UnmapViewOfFile(shmem); CloseHandle(filemap); #ifndef NO_SECURITY if (sa.lpSecurityDescriptor) LocalFree(sa.lpSecurityDescriptor); #endif EPRINTF(3, "Got %d bytes back from pageant.\n", retlen); return retlen; }
void random_xor_noise(RandomState * state, unsigned int i, word32 value) { value ^= GET_32BIT(state->state + 4 * i); PUT_32BIT(state->state + 4 * i, value); }
void random_stir(RandomState * state) { word32 iv[4]; unsigned int i; /* Start IV from last block of random pool. */ iv[0] = GET_32BIT(state->state); iv[1] = GET_32BIT(state->state + 4); iv[2] = GET_32BIT(state->state + 8); iv[3] = GET_32BIT(state->state + 12); /* First CFB pass. */ for (i = 0; i < RANDOM_STATE_BYTES; i += 16) { MD5Transform((md5_uint32 *)(char*)iv, state->stir_key); iv[0] ^= GET_32BIT(state->state + i); PUT_32BIT(state->state + i, iv[0]); iv[1] ^= GET_32BIT(state->state + i + 4); PUT_32BIT(state->state + i + 4, iv[1]); iv[2] ^= GET_32BIT(state->state + i + 8); PUT_32BIT(state->state + i + 8, iv[2]); iv[3] ^= GET_32BIT(state->state + i + 12); PUT_32BIT(state->state + i + 12, iv[3]); } /* Get new key. */ memcpy(state->stir_key, state->state, sizeof(state->stir_key)); /* Second CFB pass. */ for (i = 0; i < RANDOM_STATE_BYTES; i += 16) { MD5Transform((md5_uint32 *)(char*)iv, state->stir_key); iv[0] ^= GET_32BIT(state->state + i); PUT_32BIT(state->state + i, iv[0]); iv[1] ^= GET_32BIT(state->state + i + 4); PUT_32BIT(state->state + i + 4, iv[1]); iv[2] ^= GET_32BIT(state->state + i + 8); PUT_32BIT(state->state + i + 8, iv[2]); iv[3] ^= GET_32BIT(state->state + i + 12); PUT_32BIT(state->state + i + 12, iv[3]); } memset(iv, 0, sizeof(iv)); state->add_position = 0; /* Some data in the beginning is not returned to aboid giving an observer complete knowledge of the contents of our random pool. */ state->next_available_byte = sizeof(state->stir_key); }