Skip to content
This repository was archived by the owner on Apr 29, 2026. It is now read-only.

Commit 7e8a7dc

Browse files
committed
refactor: do some experimental restructure
1 parent d8a3d32 commit 7e8a7dc

4 files changed

Lines changed: 65 additions & 63 deletions

File tree

cmd/rwppa/main.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// In other words, on receiving requests, they will be sent to rvpn.zju.edu.cn and corresponding results will be passed back to the browser,
1818
// or any other HTTP-proxy-capable requesters, like clients that only utilizes HTTP protocol.
1919

20-
// In short, users are given the ability to browse ZJU intranet sites,
20+
// In short, users are given the ability to access ZJU intranet sites,
2121
// with a ZJU internet service account required, and via ZJU RVPN web portal (view rvpn.zju.edu.cn on phones to see).
2222
// Hopefully it can replace the role of Sangfor EasyConnect, to a certain extent.
2323

@@ -32,8 +32,8 @@ package main
3232
import (
3333
"fmt"
3434

35-
"github.com/coolspring8/rwppa/internal/login"
3635
"github.com/coolspring8/rwppa/internal/proxy"
36+
"github.com/coolspring8/rwppa/internal/rvpn"
3737
)
3838

3939
func main() {
@@ -52,6 +52,12 @@ func main() {
5252
if err != nil {
5353
panic(err)
5454
}
55-
twfid := login.LoginRVPNWebPortal(username, password)
56-
proxy.StartProxyServer(listenAddr, twfid)
55+
56+
w := rvpn.WebPortal{Username: username, Password: password}
57+
twfid, err := w.LogIn()
58+
if err != nil {
59+
panic(err)
60+
}
61+
62+
proxy.StartProxyServer(listenAddr, *twfid)
5763
}

internal/cert/cert.go

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,31 @@
1-
// This file was partly from https://github.com/elazarl/goproxy/blob/master/examples/goproxy-customca/cert.go
1+
// Copyright (C) 2020 CoolSpring8
22

3-
// Copyright (c) 2012 Elazar Leibovich. All rights reserved.
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
47

5-
// Redistribution and use in source and binary forms, with or without
6-
// modification, are permitted provided that the following conditions are
7-
// met:
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
812

9-
// * Redistributions of source code must retain the above copyright
10-
// notice, this list of conditions and the following disclaimer.
11-
// * Redistributions in binary form must reproduce the above
12-
// copyright notice, this list of conditions and the following disclaimer
13-
// in the documentation and/or other materials provided with the
14-
// distribution.
15-
// * Neither the name of Elazar Leibovich. nor the names of its
16-
// contributors may be used to endorse or promote products derived from
17-
// this software without specific prior written permission.
18-
19-
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20-
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21-
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22-
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23-
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24-
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25-
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26-
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27-
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28-
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29-
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13+
// You should have received a copy of the GNU General Public License
14+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
3015

16+
// Package cert provides operation functions on CA cert and key.
3117
package cert
3218

3319
import (
3420
"crypto/rand"
3521
"crypto/rsa"
36-
"crypto/tls"
3722
"crypto/x509"
3823
"crypto/x509/pkix"
3924
"encoding/pem"
4025
"io/ioutil"
4126
"math/big"
4227
"os"
4328
"time"
44-
45-
"github.com/elazarl/goproxy"
4629
)
4730

4831
// GetCA returns a CA cert, a CA key or an error in file reading or writing process.
@@ -114,24 +97,6 @@ func GetCA() ([]byte, []byte, error) {
11497
return caCert, caKey, err
11598
}
11699

117-
// SetCA takes CA cert and CA key, and sets up goproxy CA.
118-
// Returns error in parsing and setting CA.
119-
func SetCA(caCert, caKey []byte) error {
120-
goproxyCa, err := tls.X509KeyPair(caCert, caKey)
121-
if err != nil {
122-
return err
123-
}
124-
if goproxyCa.Leaf, err = x509.ParseCertificate(goproxyCa.Certificate[0]); err != nil {
125-
return err
126-
}
127-
goproxy.GoproxyCa = goproxyCa
128-
goproxy.OkConnect = &goproxy.ConnectAction{Action: goproxy.ConnectAccept, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
129-
goproxy.MitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectMitm, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
130-
goproxy.HTTPMitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectHTTPMitm, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
131-
goproxy.RejectConnect = &goproxy.ConnectAction{Action: goproxy.ConnectReject, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
132-
return nil
133-
}
134-
135100
// fileExists checks if a file exists and is not a directory.
136101
func fileExists(filename string) bool {
137102
info, err := os.Stat(filename)

internal/proxy/proxy.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
// You should have received a copy of the GNU General Public License
1414
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1515

16+
// Package proxy provides things to set up a proxy.
1617
package proxy
1718

1819
import (
20+
"crypto/tls"
21+
"crypto/x509"
1922
"fmt"
2023
"log"
2124
"net"
@@ -70,7 +73,7 @@ func StartProxyServer(listenAddr, twfid string) {
7073
if err != nil {
7174
panic(err)
7275
}
73-
err = cert.SetCA(caCert, caKey)
76+
err = SetCA(caCert, caKey)
7477
if err != nil {
7578
panic(err)
7679
}
@@ -144,3 +147,21 @@ func StartProxyServer(listenAddr, twfid string) {
144147
fmt.Println("Listen Address:" + listenAddr)
145148
log.Fatal(http.ListenAndServe(listenAddr, proxy))
146149
}
150+
151+
// SetCA takes CA cert and CA key, and sets up goproxy CA.
152+
// Returns error in parsing and setting CA.
153+
func SetCA(caCert, caKey []byte) error {
154+
goproxyCa, err := tls.X509KeyPair(caCert, caKey)
155+
if err != nil {
156+
return err
157+
}
158+
if goproxyCa.Leaf, err = x509.ParseCertificate(goproxyCa.Certificate[0]); err != nil {
159+
return err
160+
}
161+
goproxy.GoproxyCa = goproxyCa
162+
goproxy.OkConnect = &goproxy.ConnectAction{Action: goproxy.ConnectAccept, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
163+
goproxy.MitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectMitm, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
164+
goproxy.HTTPMitmConnect = &goproxy.ConnectAction{Action: goproxy.ConnectHTTPMitm, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
165+
goproxy.RejectConnect = &goproxy.ConnectAction{Action: goproxy.ConnectReject, TLSConfig: goproxy.TLSConfigFromCA(&goproxyCa)}
166+
return nil
167+
}
Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
// You should have received a copy of the GNU General Public License
1414
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1515

16-
package login
16+
// Package rvpn deals with things related to ZJU RVPN web portal.
17+
package rvpn
1718

1819
import (
1920
"net/http"
@@ -23,28 +24,37 @@ import (
2324

2425
const (
2526
// endpointURL is where ZJU RVPN web portal's login interface locates.
26-
// TODO: try to find out if some of the parameters are not necessary.
27+
// TODO: find out if some of the parameters are not necessary.
2728
endpointURL string = "https://rvpn.zju.edu.cn/por/login_psw.csp?type=cs&dev=android-phone&dev=android-phone&language=zh_CN"
2829
)
2930

30-
// LoginRVPNWebPortal takes username and password, returns TWFID.
31+
// WebPortal refers to ZJU RVPN web portal.
32+
type WebPortal struct {
33+
Username string // Username is ZJU network service account username.
34+
Password string // Password is ZJU network service account password.
35+
}
36+
37+
// LogIn uses username and password to get a TWFID.
3138
// TWFID is used by the web portal for authentication.
3239
// Incorrect or empty username and password will simply lead to a useless TWFID.
33-
// TODO: verify before returning. throw an error if not working.
34-
func LoginRVPNWebPortal(username, password string) string {
40+
// TODO: verify, throw an error if not working.
41+
func (webPortal WebPortal) LogIn() (*string, error) {
3542
data := url.Values{}
36-
data.Set("svpn_name", username)
37-
data.Set("svpn_password", password)
43+
data.Set("svpn_name", webPortal.Username)
44+
data.Set("svpn_password", webPortal.Password)
3845

3946
client := &http.Client{}
40-
r, _ := http.NewRequest("POST", endpointURL, strings.NewReader(data.Encode()))
47+
req, err := http.NewRequest("POST", endpointURL, strings.NewReader(data.Encode()))
48+
if err != nil {
49+
return nil, err
50+
}
4151

42-
resp, err := client.Do(r)
52+
resp, err := client.Do(req)
4353
if err != nil {
44-
panic(err)
54+
return nil, err
4555
}
4656

4757
twfid := resp.Cookies()[0].Value
4858

49-
return twfid
59+
return &twfid, nil
5060
}

0 commit comments

Comments
 (0)