// Connection for NAT administrator RPC *NatAdminConnect(CEDAR *cedar, char *hostname, UINT port, void *hashed_password, UINT *err) { UCHAR secure_password[SHA1_SIZE]; UCHAR random[SHA1_SIZE]; SOCK *sock; RPC *rpc; PACK *p; UINT error; // Validate arguments if (cedar == NULL || hostname == NULL || port == 0 || hashed_password == NULL || err == NULL) { if (err != NULL) { *err = ERR_INTERNAL_ERROR; } return NULL; } // Connection sock = Connect(hostname, port); if (sock == NULL) { *err = ERR_CONNECT_FAILED; return NULL; } if (StartSSL(sock, NULL, NULL) == false) { *err = ERR_PROTOCOL_ERROR; ReleaseSock(sock); return NULL; } SetTimeout(sock, 5000); p = HttpClientRecv(sock); if (p == NULL) { *err = ERR_DISCONNECTED; ReleaseSock(sock); return NULL; } if (PackGetData2(p, "auth_random", random, SHA1_SIZE) == false) { FreePack(p); *err = ERR_PROTOCOL_ERROR; ReleaseSock(sock); return NULL; } FreePack(p); SecurePassword(secure_password, hashed_password, random); p = NewPack(); PackAddData(p, "secure_password", secure_password, SHA1_SIZE); if (HttpClientSend(sock, p) == false) { FreePack(p); *err = ERR_DISCONNECTED; ReleaseSock(sock); return NULL; } FreePack(p); p = HttpClientRecv(sock); if (p == NULL) { *err = ERR_DISCONNECTED; ReleaseSock(sock); return NULL; } error = GetErrorFromPack(p); FreePack(p); if (error != ERR_NO_ERROR) { *err = error; ReleaseSock(sock); return NULL; } SetTimeout(sock, TIMEOUT_INFINITE); rpc = StartRpcClient(sock, NULL); ReleaseSock(sock); return rpc; }
bool Pop3::Login() { try { if(host.IsEmpty()) throw Exc(t_("Hostname is not specified.")); if(user.IsEmpty()) throw Exc(t_("Username is not specified.")); if(pass.IsEmpty()) throw Exc(t_("Password is nor specified.")); if(proxy_host.GetCount()) { String host_port = host; host_port << ':' << Nvl(port, ssl ? 995 : 110); String data; data << "CONNECT " << host_port << " HTTP/1.1\r\n" << "Host: " << host_port << "\r\n"; if(!IsNull(proxy_username)) data << "Proxy-Authorization: Basic " << Base64Encode(proxy_username + ':' + proxy_password) << "\r\n"; data << "\r\n"; LLOG("Trying to connect proxy " << proxy_host << ":" << proxy_port); if(!Connect(proxy_host, proxy_port)) throw Exc("Unable to connect the proxy"); LLOG("About to send proxy request:\n" << data); if(!PutAll(data)) throw Exc("Unable to send request to the proxy"); String response; for(;;) { String l = GetLine(); if(l.GetCount() == 0) break; LLOG("< " << l); if(response.GetCount() == 0) response = l; } LLOG("Proxy response: " << response); if(!response.StartsWith("HTTP") || response.Find(" 2") < 0) throw Exc("Invalid proxy reply: " + response); LLOG("Connected via proxy"); } else if(!Connect(host, Nvl(port, ssl ? 995 : 110))) throw Exc(GetErrorDesc()); LLOG(Format(t_("Opening connection to %s:%d."), host, port)); if(ssl) { if(!StartSSL()) throw Exc(t_("Couldn't start SSL session.")); LLOG(t_("SSL session successfully started.")); } // Receive server greetings. if(!PutGet(Null)) throw Exc(GetLastError()); if(!Authenticate()) throw Exc(GetLastError()); } catch (Exc e) { error = e; LLOG("-- " + e); Logout(); return false; } return online = true; }
// Management thread void NiAdminThread(THREAD *thread, void *param) { NAT_ADMIN *a = (NAT_ADMIN *)param; NAT *n; SOCK *s; UCHAR random[SHA1_SIZE]; UINT err; // Validate arguments if (thread == NULL || param == NULL) { return; } // Random number generation Rand(random, sizeof(random)); a->Thread = thread; AddRef(a->Thread->ref); s = a->Sock; AddRef(s->ref); n = a->Nat; LockList(n->AdminList); { Add(n->AdminList, a); } UnlockList(n->AdminList); NoticeThreadInit(thread); err = ERR_AUTH_FAILED; if (StartSSL(s, n->AdminX, n->AdminK)) { PACK *p; // Send the random number p = NewPack(); PackAddData(p, "auth_random", random, sizeof(random)); if (HttpServerSend(s, p)) { PACK *p; // Receive a password p = HttpServerRecv(s); if (p != NULL) { UCHAR secure_password[SHA1_SIZE]; UCHAR secure_check[SHA1_SIZE]; if (PackGetData2(p, "secure_password", secure_password, sizeof(secure_password))) { SecurePassword(secure_check, n->HashedPassword, random); if (Cmp(secure_check, secure_password, SHA1_SIZE) == 0) { UCHAR test[SHA1_SIZE]; // Password match Hash(test, "", 0, true); SecurePassword(test, test, random); #if 0 if (Cmp(test, secure_check, SHA1_SIZE) == 0 && s->RemoteIP.addr[0] != 127) { // A client can not connect from the outside with blank password err = ERR_NULL_PASSWORD_LOCAL_ONLY; } else #endif { // Successful connection err = ERR_NO_ERROR; NiAdminMain(n, s); } } } FreePack(p); } } FreePack(p); if (err != ERR_NO_ERROR) { p = PackError(err); HttpServerSend(s, p); FreePack(p); } } Disconnect(s); ReleaseSock(s); }
// 管理スレッド void NiAdminThread(THREAD *thread, void *param) { NAT_ADMIN *a = (NAT_ADMIN *)param; NAT *n; SOCK *s; UCHAR random[SHA1_SIZE]; UINT err; // 引数チェック if (thread == NULL || param == NULL) { return; } // 乱数生成 Rand(random, sizeof(random)); a->Thread = thread; AddRef(a->Thread->ref); s = a->Sock; AddRef(s->ref); n = a->Nat; LockList(n->AdminList); { Add(n->AdminList, a); } UnlockList(n->AdminList); NoticeThreadInit(thread); err = ERR_AUTH_FAILED; if (StartSSL(s, n->AdminX, n->AdminK)) { PACK *p; // 乱数を送信する p = NewPack(); PackAddData(p, "auth_random", random, sizeof(random)); if (HttpServerSend(s, p)) { PACK *p; // パスワードを受け取る p = HttpServerRecv(s); if (p != NULL) { UCHAR secure_password[SHA1_SIZE]; UCHAR secure_check[SHA1_SIZE]; if (PackGetData2(p, "secure_password", secure_password, sizeof(secure_password))) { SecurePassword(secure_check, n->HashedPassword, random); if (Cmp(secure_check, secure_password, SHA1_SIZE) == 0) { UCHAR test[SHA1_SIZE]; // パスワード一致 Hash(test, "", 0, true); SecurePassword(test, test, random); #if 0 if (Cmp(test, secure_check, SHA1_SIZE) == 0 && s->RemoteIP.addr[0] != 127) { // 空白パスワードは外部から接続できない err = ERR_NULL_PASSWORD_LOCAL_ONLY; } else #endif { // 接続成功 err = ERR_NO_ERROR; NiAdminMain(n, s); } } } FreePack(p); } } FreePack(p); if (err != ERR_NO_ERROR) { p = PackError(err); HttpServerSend(s, p); FreePack(p); } } Disconnect(s); ReleaseSock(s); }